blob: 68237c8dd6690a2cfb526a49a77db34ca0489039 [file] [log] [blame]
/*
* Copyright 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <compositionengine/impl/OutputCompositionState.h>
#include <fuzzer/FuzzedDataProvider.h>
#include <gui/BLASTBufferQueue.h>
#include <gui/IGraphicBufferProducer.h>
#include <gui/IProducerListener.h>
#include <gui/LayerDebugInfo.h>
#include <gui/SurfaceComposerClient.h>
#include <hidl/ServiceManagement.h>
#include <hwbinder/ProcessState.h>
#include <ui/DisplayIdentification.h>
#include "DisplayHardware/AidlComposerHal.h"
#include "DisplayHardware/DisplayMode.h"
#include "DisplayHardware/FramebufferSurface.h"
#include "DisplayHardware/HWComposer.h"
#include "DisplayHardware/PowerAdvisor.h"
#include "DisplayHardware/VirtualDisplaySurface.h"
#include "SurfaceFlinger.h"
#include "surfaceflinger_displayhardware_fuzzer_utils.h"
#include <FuzzableDataspaces.h>
namespace android::fuzz {
using namespace android::hardware::graphics::common;
using namespace android::hardware::graphics::composer;
namespace aidl = aidl::android::hardware::graphics::composer3;
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 aidl::Capability kCapability[] = {aidl::Capability::INVALID,
aidl::Capability::SIDEBAND_STREAM,
aidl::Capability::SKIP_CLIENT_COLOR_TRANSFORM,
aidl::Capability::PRESENT_FENCE_IS_NOT_RELIABLE,
aidl::Capability::SKIP_VALIDATE};
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 = TestableSurfaceFlinger::getFirstDisplayId().value_or(
PhysicalDisplayId::fromPort(mFdp.ConsumeIntegral<uint8_t>()));
};
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;
const auto frameIntervalRange =
mFdp.ConsumeIntegralInRange<int32_t>(Fps::fromValue(1).getPeriodNsecs(),
Fps::fromValue(120).getPeriodNsecs());
composer->validateDisplay(display, mFdp.ConsumeIntegral<nsecs_t>(), frameIntervalRange,
&outNumTypes, &outNumRequests);
}
void DisplayHardwareFuzzer::presentOrValidateDisplay(Hwc2::AidlComposer* composer,
Display display) {
int32_t outPresentFence;
uint32_t outNumTypes, outNumRequests, state;
const auto frameIntervalRange =
mFdp.ConsumeIntegralInRange<int32_t>(Fps::fromValue(1).getPeriodNsecs(),
Fps::fromValue(120).getPeriodNsecs());
composer->presentOrValidateDisplay(display, mFdp.ConsumeIntegral<nsecs_t>(), frameIntervalRange,
&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(),
mFdp.ConsumeIntegral<nsecs_t>(),
Fps::fromValue(
mFdp.ConsumeFloatingPointInRange<float>(1.f, 120.f)),
&outChanges);
}
void DisplayHardwareFuzzer::getDisplayedContentSamplingAttributes(HalDisplayId halDisplayID) {
uint8_t outComponentMask;
ui::Dataspace dataSpace;
ui::PixelFormat pixelFormat;
mHwc.getDisplayedContentSamplingAttributes(halDisplayID, &pixelFormat, &dataSpace,
&outComponentMask);
}
void DisplayHardwareFuzzer::getHdrCapabilities(HalDisplayId halDisplayID) {
HdrCapabilities outCapabilities;
mHwc.getHdrCapabilities(halDisplayID, &outCapabilities);
}
void DisplayHardwareFuzzer::getDisplayedContentSample(HalDisplayId halDisplayID) {
DisplayedFrameStats outStats;
mHwc.getDisplayedContentSample(halDisplayID, mFdp.ConsumeIntegral<uint64_t>() /* maxFrames*/,
mFdp.ConsumeIntegral<uint64_t>() /*timestamps*/, &outStats);
}
void DisplayHardwareFuzzer::getSupportedContentTypes() {
std::vector<hal::ContentType> contentType{};
mHwc.getSupportedContentTypes(mPhysicalDisplayId, &contentType);
}
void DisplayHardwareFuzzer::invokeAidlComposer() {
hardware::ProcessState::self()->startThreadPool();
ProcessState::self()->startThreadPool();
if (!Hwc2::AidlComposer::isDeclared("default")) {
return;
}
Hwc2::AidlComposer composer("default");
android::hardware::graphics::composer::hal::TestHWC2ComposerCallback composerCallback{};
composer.registerCallback(composerCallback);
Display display = createVirtualDisplay(&composer);
composer.acceptDisplayChanges(display);
Hwc2::V2_4::hal::Layer outLayer;
composer.createLayer(display, &outLayer);
int32_t outPresentFence;
composer.presentDisplay(display, &outPresentFence);
composer.setActiveConfig(display, Config{});
composer.setClientTarget(display, mFdp.ConsumeIntegral<uint32_t>(), sp<GraphicBuffer>(),
mFdp.ConsumeIntegral<int32_t>(), mFdp.PickValueInArray(kDataspaces),
{}, mFdp.ConsumeFloatingPoint<float>());
composer.setColorMode(display, mFdp.PickValueInArray(kColormodes),
mFdp.PickValueInArray(kRenderIntents));
setOutputBuffer(&composer, display);
composer.setPowerMode(display, mFdp.PickValueInArray(kPowerModes));
composer.setVsyncEnabled(display, mFdp.ConsumeBool() ? Vsync::ENABLE : Vsync::DISABLE);
composer.setClientTargetSlotCount(display);
validateDisplay(&composer, display);
presentOrValidateDisplay(&composer, display);
composer.setCursorPosition(display, outLayer, mFdp.ConsumeIntegral<uint8_t>() /*x*/,
mFdp.ConsumeIntegral<uint8_t>() /*y*/);
composer.setLayerBuffer(display, outLayer, mFdp.ConsumeIntegral<uint32_t>() /*slot*/,
sp<GraphicBuffer>(), mFdp.ConsumeIntegral<int32_t>() /*acquireFence*/);
composer.setLayerSurfaceDamage(display, outLayer, {} /*damage*/);
composer.setLayerBlendMode(display, outLayer, mFdp.PickValueInArray(kBlendModes));
composer.setLayerColor(display, outLayer,
{mFdp.ConsumeFloatingPoint<float>() /*red*/,
mFdp.ConsumeFloatingPoint<float>() /*green*/,
mFdp.ConsumeFloatingPoint<float>() /*blue*/,
mFdp.ConsumeFloatingPoint<float>() /*alpha*/});
composer.setLayerCompositionType(display, outLayer, mFdp.PickValueInArray(kCompositions));
composer.setLayerDataspace(display, outLayer, mFdp.PickValueInArray(kDataspaces));
composer.setLayerDisplayFrame(display, outLayer, {} /*frame*/);
composer.setLayerPlaneAlpha(display, outLayer, mFdp.ConsumeFloatingPoint<float>());
setLayerSidebandStream(&composer, display, outLayer);
composer.setLayerSourceCrop(display, outLayer, {} /*crop*/);
composer.setLayerTransform(display, outLayer, mFdp.PickValueInArray(kTransforms));
composer.setLayerVisibleRegion(display, outLayer, std::vector<IComposerClient::Rect>{});
composer.setLayerZOrder(display, outLayer, mFdp.ConsumeIntegral<uint32_t>());
invokeComposerHal2_2(&composer, display, outLayer);
invokeComposerHal2_3(&composer, display, outLayer);
invokeComposerHal2_4(&composer, display, outLayer);
composer.executeCommands(display);
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>(),
mFdp.ConsumeFloatingPoint<float>(),
Hwc2::Composer::DisplayBrightnessOptions{
.applyImmediately = mFdp.ConsumeIntegral<bool>()});
}
void DisplayHardwareFuzzer::invokeComposerHal2_4(Hwc2::AidlComposer* composer, Display display,
Hwc2::V2_4::hal::Layer outLayer) {
VsyncPeriodChangeTimeline outTimeline;
composer->setActiveConfigWithConstraints(display, Config{},
IComposerClient::VsyncPeriodChangeConstraints{},
&outTimeline);
composer->setAutoLowLatencyMode(display, mFdp.ConsumeBool());
composer->setContentType(display, mFdp.PickValueInArray(kContentTypes));
std::vector<uint8_t> value;
value.push_back(mFdp.ConsumeIntegral<uint8_t>());
composer->setLayerGenericMetadata(display, outLayer, mFdp.ConsumeRandomLengthString() /*key*/,
mFdp.ConsumeBool() /*mandatory*/, value);
}
ui::Size DisplayHardwareFuzzer::getFuzzedSize() {
ui::Size size{mFdp.ConsumeIntegral<int32_t>() /*width*/,
mFdp.ConsumeIntegral<int32_t>() /*height*/};
return size;
}
mat4 DisplayHardwareFuzzer::getFuzzedMatrix() {
mat4 matrix{mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>(),
mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>(),
mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>(),
mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>(),
mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>(),
mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>(),
mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>(),
mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>()};
return matrix;
}
void DisplayHardwareFuzzer::setCursorPosition(HWC2::Layer* layer) {
layer->setCursorPosition(mFdp.ConsumeIntegral<int32_t>() /*x*/,
mFdp.ConsumeIntegral<int32_t>() /*y*/);
}
void DisplayHardwareFuzzer::setBuffer(HWC2::Layer* layer) {
layer->setBuffer(mFdp.ConsumeIntegral<uint32_t>() /*slot*/, sp<GraphicBuffer>(),
sp<Fence>::make());
}
void DisplayHardwareFuzzer::setSurfaceDamage(HWC2::Layer* layer) {
Rect rhs{mFdp.ConsumeIntegral<uint32_t>() /*width*/,
mFdp.ConsumeIntegral<uint32_t>() /*height*/};
const Region damage{rhs};
layer->setSurfaceDamage(damage);
}
void DisplayHardwareFuzzer::setVisibleRegion(HWC2::Layer* layer) {
uint32_t width = mFdp.ConsumeIntegral<uint32_t>();
uint32_t height = mFdp.ConsumeIntegral<uint32_t>();
Rect rect{width, height};
const Region region{rect};
layer->setVisibleRegion(region);
}
void DisplayHardwareFuzzer::setDisplayFrame(HWC2::Layer* layer) {
uint32_t width = mFdp.ConsumeIntegral<uint32_t>();
uint32_t height = mFdp.ConsumeIntegral<uint32_t>();
const Rect frame{width, height};
layer->setDisplayFrame(frame);
}
void DisplayHardwareFuzzer::setLayerGenericMetadata(HWC2::Layer* layer) {
std::vector<uint8_t> value;
value.push_back(mFdp.ConsumeIntegral<uint8_t>());
layer->setLayerGenericMetadata(mFdp.ConsumeRandomLengthString().c_str() /*name*/,
mFdp.ConsumeBool() /*mandatory*/, value);
}
void DisplayHardwareFuzzer::setSidebandStream(HWC2::Layer* layer) {
const native_handle_t stream{};
layer->setSidebandStream(&stream);
}
void DisplayHardwareFuzzer::invokeLayer(HWC2::Layer* layer) {
setCursorPosition(layer);
setBuffer(layer);
setSurfaceDamage(layer);
layer->setBlendMode(mFdp.PickValueInArray(kBlendModes));
layer->setColor({mFdp.ConsumeFloatingPoint<float>() /*red*/,
mFdp.ConsumeFloatingPoint<float>() /*green*/,
mFdp.ConsumeFloatingPoint<float>() /*blue*/,
mFdp.ConsumeFloatingPoint<float>() /*alpha*/});
layer->setCompositionType(mFdp.PickValueInArray(kCompositions));
layer->setDataspace(mFdp.PickValueInArray(kDataspaces));
layer->setPerFrameMetadata(mFdp.ConsumeIntegral<int32_t>(), getFuzzedHdrMetadata(&mFdp));
setDisplayFrame(layer);
layer->setPlaneAlpha(mFdp.ConsumeFloatingPoint<float>());
setSidebandStream(layer);
layer->setSourceCrop(getFuzzedFloatRect(&mFdp));
layer->setTransform(mFdp.PickValueInArray(kTransforms));
setVisibleRegion(layer);
layer->setZOrder(mFdp.ConsumeIntegral<uint32_t>());
layer->setColorTransform(getFuzzedMatrix());
setLayerGenericMetadata(layer);
}
void DisplayHardwareFuzzer::invokeFrameBufferSurface() {
sp<IGraphicBufferProducer> bqProducer = sp<mock::GraphicBufferProducer>::make();
sp<IGraphicBufferConsumer> bqConsumer;
BufferQueue::createBufferQueue(&bqProducer, &bqConsumer);
sp<FramebufferSurface> surface =
sp<FramebufferSurface>::make(mHwc, mPhysicalDisplayId, bqConsumer,
getFuzzedSize() /*size*/, getFuzzedSize() /*maxSize*/);
surface->beginFrame(mFdp.ConsumeBool());
surface->prepareFrame(mFdp.PickValueInArray(kCompositionTypes));
surface->advanceFrame(mFdp.ConsumeFloatingPoint<float>());
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 = sp<SurfaceComposerClient>::make();
sp<SurfaceControl> mSurfaceControl =
mClient->createSurface(String8("TestSurface"), 100, 100, PIXEL_FORMAT_RGBA_8888,
ISurfaceComposerClient::eFXSurfaceBufferState,
/*parent*/ nullptr);
auto mBlastBufferQueueAdapter =
sp<BLASTBufferQueue>::make("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);
auto surface =
sp<VirtualDisplaySurface>::make(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(mFdp.ConsumeFloatingPoint<float>());
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),
mFdp.ConsumeFloatingPoint<float>());
mHwc.presentAndGetReleaseFences(halDisplayID, std::chrono::steady_clock::now());
mHwc.setPowerMode(mPhysicalDisplayId, mFdp.PickValueInArray(kPowerModes));
mHwc.setColorTransform(halDisplayID, getFuzzedMatrix());
mHwc.getPresentFence(halDisplayID);
mHwc.getLayerReleaseFence(halDisplayID, layer);
mHwc.setOutputBuffer(halVirtualDisplayId, sp<Fence>::make(), 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>(),
mFdp.ConsumeFloatingPoint<float>(),
Hwc2::Composer::DisplayBrightnessOptions{
.applyImmediately = mFdp.ConsumeIntegral<bool>()});
mHwc.onHotplug(kHwDisplayId, hal::Connection::CONNECTED);
mHwc.updatesDeviceProductInfoOnHotplugReconnect();
mHwc.onVsync(kHwDisplayId, mFdp.ConsumeIntegral<int64_t>());
mHwc.setVsyncEnabled(mPhysicalDisplayId,
mFdp.ConsumeBool() ? hal::Vsync::ENABLE : hal::Vsync::DISABLE);
mHwc.isConnected(mPhysicalDisplayId);
mHwc.getModes(mPhysicalDisplayId, mFdp.ConsumeIntegral<int32_t>());
mHwc.getActiveMode(mPhysicalDisplayId);
mHwc.getColorModes(mPhysicalDisplayId);
mHwc.hasCapability(mFdp.PickValueInArray(kCapability));
mHwc.setActiveColorMode(mPhysicalDisplayId, mFdp.PickValueInArray(kColormodes),
mFdp.PickValueInArray(kRenderIntents));
mHwc.getDisplayConnectionType(mPhysicalDisplayId);
mHwc.isVsyncPeriodSwitchSupported(mPhysicalDisplayId);
getDisplayVsyncPeriod();
setActiveModeWithConstraints();
mHwc.setAutoLowLatencyMode(mPhysicalDisplayId, mFdp.ConsumeBool());
getSupportedContentTypes();
mHwc.setContentType(mPhysicalDisplayId, mFdp.PickValueInArray(kContentTypes));
dumpHwc();
mHwc.toPhysicalDisplayId(kHwDisplayId);
mHwc.fromPhysicalDisplayId(mPhysicalDisplayId);
mHwc.disconnectDisplay(halDisplayID);
static hal::HWDisplayId displayId = mFdp.ConsumeIntegral<hal::HWDisplayId>();
mHwc.onHotplug(displayId,
mFdp.ConsumeBool() ? hal::Connection::DISCONNECTED : hal::Connection::CONNECTED);
}
template <size_t N>
DisplayIdentificationData asDisplayIdentificationData(const unsigned char (&bytes)[N]) {
return DisplayIdentificationData(bytes, bytes + N - 1);
}
void DisplayHardwareFuzzer::invokeDisplayIdentification() {
static const DisplayIdentificationData data = asDisplayIdentificationData(kInternalEdid);
isEdid(data);
parseEdid(data);
parseDisplayIdentificationData(mFdp.ConsumeIntegral<uint8_t>(), data);
getPnpId(getVirtualDisplayId(mFdp.ConsumeIntegral<uint32_t>()));
getPnpId(mFdp.ConsumeIntegral<uint8_t>());
}
void DisplayHardwareFuzzer::process() {
invokeComposer();
invokeAidlComposer();
invokeDisplayIdentification();
invokeFrameBufferSurface();
invokeVirtualDisplaySurface();
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
DisplayHardwareFuzzer displayHardwareFuzzer(data, size);
displayHardwareFuzzer.process();
return 0;
}
} // namespace android::fuzz