blob: 4daa3be36f1d238b6b984532400286314e85ee7e [file] [log] [blame]
/*
* Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <aidl/android/hardware/power/Boost.h>
#include <fuzzbinder/libbinder_driver.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
#include <libgui_fuzzer_utils.h>
#include "android-base/stringprintf.h"
using namespace android;
constexpr int32_t kRandomStringMaxBytes = 256;
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};
constexpr aidl::android::hardware::power::Boost kBoost[] = {
aidl::android::hardware::power::Boost::INTERACTION,
aidl::android::hardware::power::Boost::DISPLAY_UPDATE_IMMINENT,
aidl::android::hardware::power::Boost::ML_ACC,
aidl::android::hardware::power::Boost::AUDIO_LAUNCH,
aidl::android::hardware::power::Boost::CAMERA_LAUNCH,
aidl::android::hardware::power::Boost::CAMERA_SHOT,
};
constexpr gui::TouchOcclusionMode kMode[] = {
gui::TouchOcclusionMode::BLOCK_UNTRUSTED,
gui::TouchOcclusionMode::USE_OPACITY,
gui::TouchOcclusionMode::ALLOW,
};
constexpr gui::WindowInfo::Flag kFlags[] = {
gui::WindowInfo::Flag::ALLOW_LOCK_WHILE_SCREEN_ON,
gui::WindowInfo::Flag::DIM_BEHIND,
gui::WindowInfo::Flag::BLUR_BEHIND,
gui::WindowInfo::Flag::NOT_FOCUSABLE,
gui::WindowInfo::Flag::NOT_TOUCHABLE,
gui::WindowInfo::Flag::NOT_TOUCH_MODAL,
gui::WindowInfo::Flag::TOUCHABLE_WHEN_WAKING,
gui::WindowInfo::Flag::KEEP_SCREEN_ON,
gui::WindowInfo::Flag::LAYOUT_IN_SCREEN,
gui::WindowInfo::Flag::LAYOUT_NO_LIMITS,
gui::WindowInfo::Flag::FULLSCREEN,
gui::WindowInfo::Flag::FORCE_NOT_FULLSCREEN,
gui::WindowInfo::Flag::DITHER,
gui::WindowInfo::Flag::SECURE,
gui::WindowInfo::Flag::SCALED,
gui::WindowInfo::Flag::IGNORE_CHEEK_PRESSES,
gui::WindowInfo::Flag::LAYOUT_INSET_DECOR,
gui::WindowInfo::Flag::ALT_FOCUSABLE_IM,
gui::WindowInfo::Flag::WATCH_OUTSIDE_TOUCH,
gui::WindowInfo::Flag::SHOW_WHEN_LOCKED,
gui::WindowInfo::Flag::SHOW_WALLPAPER,
gui::WindowInfo::Flag::TURN_SCREEN_ON,
gui::WindowInfo::Flag::DISMISS_KEYGUARD,
gui::WindowInfo::Flag::SPLIT_TOUCH,
gui::WindowInfo::Flag::HARDWARE_ACCELERATED,
gui::WindowInfo::Flag::LAYOUT_IN_OVERSCAN,
gui::WindowInfo::Flag::TRANSLUCENT_STATUS,
gui::WindowInfo::Flag::TRANSLUCENT_NAVIGATION,
gui::WindowInfo::Flag::LOCAL_FOCUS_MODE,
gui::WindowInfo::Flag::SLIPPERY,
gui::WindowInfo::Flag::LAYOUT_ATTACHED_IN_DECOR,
gui::WindowInfo::Flag::DRAWS_SYSTEM_BAR_BACKGROUNDS,
};
constexpr gui::WindowInfo::Type kType[] = {
gui::WindowInfo::Type::UNKNOWN,
gui::WindowInfo::Type::FIRST_APPLICATION_WINDOW,
gui::WindowInfo::Type::BASE_APPLICATION,
gui::WindowInfo::Type::APPLICATION,
gui::WindowInfo::Type::APPLICATION_STARTING,
gui::WindowInfo::Type::LAST_APPLICATION_WINDOW,
gui::WindowInfo::Type::FIRST_SUB_WINDOW,
gui::WindowInfo::Type::APPLICATION_PANEL,
gui::WindowInfo::Type::APPLICATION_MEDIA,
gui::WindowInfo::Type::APPLICATION_SUB_PANEL,
gui::WindowInfo::Type::APPLICATION_ATTACHED_DIALOG,
gui::WindowInfo::Type::APPLICATION_MEDIA_OVERLAY,
};
constexpr gui::WindowInfo::InputConfig kFeatures[] = {
gui::WindowInfo::InputConfig::NO_INPUT_CHANNEL,
gui::WindowInfo::InputConfig::DISABLE_USER_ACTIVITY,
gui::WindowInfo::InputConfig::DROP_INPUT,
gui::WindowInfo::InputConfig::DROP_INPUT_IF_OBSCURED,
gui::WindowInfo::InputConfig::SPY,
gui::WindowInfo::InputConfig::INTERCEPTS_STYLUS,
};
class SurfaceComposerClientFuzzer {
public:
SurfaceComposerClientFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
void process();
private:
void invokeSurfaceComposerClient();
void invokeSurfaceComposerClientBinder();
void invokeSurfaceComposerTransaction();
void getWindowInfo(gui::WindowInfo*);
sp<SurfaceControl> makeSurfaceControl();
BlurRegion getBlurRegion();
void fuzzOnPullAtom();
gui::DisplayModeSpecs getDisplayModeSpecs();
FuzzedDataProvider mFdp;
};
gui::DisplayModeSpecs SurfaceComposerClientFuzzer::getDisplayModeSpecs() {
const auto getRefreshRateRange = [&] {
gui::DisplayModeSpecs::RefreshRateRanges::RefreshRateRange range;
range.min = mFdp.ConsumeFloatingPoint<float>();
range.max = mFdp.ConsumeFloatingPoint<float>();
return range;
};
const auto getRefreshRateRanges = [&] {
gui::DisplayModeSpecs::RefreshRateRanges ranges;
ranges.physical = getRefreshRateRange();
ranges.render = getRefreshRateRange();
return ranges;
};
String8 displayName((mFdp.ConsumeRandomLengthString(kRandomStringMaxBytes)).c_str());
sp<IBinder> displayToken =
SurfaceComposerClient::createDisplay(displayName, mFdp.ConsumeBool() /*secure*/);
gui::DisplayModeSpecs specs;
specs.defaultMode = mFdp.ConsumeIntegral<int32_t>();
specs.allowGroupSwitching = mFdp.ConsumeBool();
specs.primaryRanges = getRefreshRateRanges();
specs.appRequestRanges = getRefreshRateRanges();
return specs;
}
BlurRegion SurfaceComposerClientFuzzer::getBlurRegion() {
int32_t left = mFdp.ConsumeIntegral<int32_t>();
int32_t right = mFdp.ConsumeIntegral<int32_t>();
int32_t top = mFdp.ConsumeIntegral<int32_t>();
int32_t bottom = mFdp.ConsumeIntegral<int32_t>();
uint32_t blurRadius = mFdp.ConsumeIntegral<uint32_t>();
float alpha = mFdp.ConsumeFloatingPoint<float>();
float cornerRadiusTL = mFdp.ConsumeFloatingPoint<float>();
float cornerRadiusTR = mFdp.ConsumeFloatingPoint<float>();
float cornerRadiusBL = mFdp.ConsumeFloatingPoint<float>();
float cornerRadiusBR = mFdp.ConsumeFloatingPoint<float>();
return BlurRegion{blurRadius, cornerRadiusTL, cornerRadiusTR, cornerRadiusBL,
cornerRadiusBR, alpha, left, top,
right, bottom};
}
void SurfaceComposerClientFuzzer::getWindowInfo(gui::WindowInfo* windowInfo) {
windowInfo->id = mFdp.ConsumeIntegral<int32_t>();
windowInfo->name = mFdp.ConsumeRandomLengthString(kRandomStringMaxBytes);
windowInfo->layoutParamsFlags = mFdp.PickValueInArray(kFlags);
windowInfo->layoutParamsType = mFdp.PickValueInArray(kType);
windowInfo->frame = Rect(mFdp.ConsumeIntegral<int32_t>(), mFdp.ConsumeIntegral<int32_t>(),
mFdp.ConsumeIntegral<int32_t>(), mFdp.ConsumeIntegral<int32_t>());
windowInfo->surfaceInset = mFdp.ConsumeIntegral<int32_t>();
windowInfo->alpha = mFdp.ConsumeFloatingPointInRange<float>(0, 1);
ui::Transform transform(mFdp.PickValueInArray(kOrientation));
windowInfo->transform = transform;
windowInfo->touchableRegion = Region(getRect(&mFdp));
windowInfo->replaceTouchableRegionWithCrop = mFdp.ConsumeBool();
windowInfo->touchOcclusionMode = mFdp.PickValueInArray(kMode);
windowInfo->ownerPid = gui::Pid{mFdp.ConsumeIntegral<pid_t>()};
windowInfo->ownerUid = gui::Uid{mFdp.ConsumeIntegral<uid_t>()};
windowInfo->packageName = mFdp.ConsumeRandomLengthString(kRandomStringMaxBytes);
windowInfo->inputConfig = mFdp.PickValueInArray(kFeatures);
}
sp<SurfaceControl> SurfaceComposerClientFuzzer::makeSurfaceControl() {
sp<IBinder> handle;
const sp<FakeBnSurfaceComposerClient> testClient(new FakeBnSurfaceComposerClient());
sp<SurfaceComposerClient> client = new SurfaceComposerClient(testClient);
sp<BnGraphicBufferProducer> producer;
uint32_t width = mFdp.ConsumeIntegral<uint32_t>();
uint32_t height = mFdp.ConsumeIntegral<uint32_t>();
uint32_t transformHint = mFdp.ConsumeIntegral<uint32_t>();
uint32_t flags = mFdp.ConsumeIntegral<uint32_t>();
int32_t format = mFdp.ConsumeIntegral<int32_t>();
int32_t layerId = mFdp.ConsumeIntegral<int32_t>();
std::string layerName = base::StringPrintf("#%d", layerId);
return new SurfaceControl(client, handle, layerId, layerName, width, height, format,
transformHint, flags);
}
void SurfaceComposerClientFuzzer::invokeSurfaceComposerTransaction() {
sp<SurfaceControl> surface = makeSurfaceControl();
SurfaceComposerClient::Transaction transaction;
int32_t layer = mFdp.ConsumeIntegral<int32_t>();
transaction.setLayer(surface, layer);
sp<SurfaceControl> relativeSurface = makeSurfaceControl();
transaction.setRelativeLayer(surface, relativeSurface, layer);
Region transparentRegion(getRect(&mFdp));
transaction.setTransparentRegionHint(surface, transparentRegion);
transaction.setAlpha(surface, mFdp.ConsumeFloatingPoint<float>());
transaction.setCornerRadius(surface, mFdp.ConsumeFloatingPoint<float>());
transaction.setBackgroundBlurRadius(surface, mFdp.ConsumeFloatingPoint<float>());
std::vector<BlurRegion> regions;
uint32_t vectorSize = mFdp.ConsumeIntegralInRange<uint32_t>(0, 100);
regions.resize(vectorSize);
for (size_t idx = 0; idx < vectorSize; ++idx) {
regions.push_back(getBlurRegion());
}
transaction.setBlurRegions(surface, regions);
transaction.setLayerStack(surface, {mFdp.ConsumeIntegral<uint32_t>()});
half3 color = {mFdp.ConsumeIntegral<uint32_t>(), mFdp.ConsumeIntegral<uint32_t>(),
mFdp.ConsumeIntegral<uint32_t>()};
transaction.setColor(surface, color);
transaction.setBackgroundColor(surface, color, mFdp.ConsumeFloatingPoint<float>(),
mFdp.PickValueInArray(kDataspaces));
transaction.setApi(surface, mFdp.ConsumeIntegral<int32_t>());
transaction.setFrameRateSelectionPriority(surface, mFdp.ConsumeIntegral<int32_t>());
transaction.setColorSpaceAgnostic(surface, mFdp.ConsumeBool() /*agnostic*/);
gui::WindowInfo windowInfo;
getWindowInfo(&windowInfo);
transaction.setInputWindowInfo(surface, windowInfo);
Parcel windowParcel;
windowInfo.writeToParcel(&windowParcel);
windowParcel.setDataPosition(0);
windowInfo.readFromParcel(&windowParcel);
windowInfo.addTouchableRegion(getRect(&mFdp));
int32_t pointX = mFdp.ConsumeIntegral<int32_t>();
int32_t pointY = mFdp.ConsumeIntegral<int32_t>();
windowInfo.touchableRegionContainsPoint(pointX, pointY);
windowInfo.frameContainsPoint(pointX, pointY);
Parcel transactionParcel;
transaction.writeToParcel(&transactionParcel);
transactionParcel.setDataPosition(0);
transaction.readFromParcel(&transactionParcel);
SurfaceComposerClient::Transaction::createFromParcel(&transactionParcel);
}
void SurfaceComposerClientFuzzer::fuzzOnPullAtom() {
std::string outData;
bool success;
SurfaceComposerClient::onPullAtom(mFdp.ConsumeIntegral<int32_t>(), &outData, &success);
}
void SurfaceComposerClientFuzzer::invokeSurfaceComposerClient() {
String8 displayName((mFdp.ConsumeRandomLengthString(kRandomStringMaxBytes)).c_str());
sp<IBinder> displayToken =
SurfaceComposerClient::createDisplay(displayName, mFdp.ConsumeBool() /*secure*/);
SurfaceComposerClient::setDesiredDisplayModeSpecs(displayToken, getDisplayModeSpecs());
ui::ColorMode colorMode = mFdp.PickValueInArray(kColormodes);
SurfaceComposerClient::setActiveColorMode(displayToken, colorMode);
SurfaceComposerClient::setAutoLowLatencyMode(displayToken, mFdp.ConsumeBool() /*on*/);
SurfaceComposerClient::setGameContentType(displayToken, mFdp.ConsumeBool() /*on*/);
SurfaceComposerClient::setDisplayPowerMode(displayToken, mFdp.ConsumeIntegral<int32_t>());
SurfaceComposerClient::doUncacheBufferTransaction(mFdp.ConsumeIntegral<uint64_t>());
SurfaceComposerClient::setDisplayBrightness(displayToken, getBrightness(&mFdp));
aidl::android::hardware::power::Boost boostId = mFdp.PickValueInArray(kBoost);
SurfaceComposerClient::notifyPowerBoost((int32_t)boostId);
String8 surfaceName((mFdp.ConsumeRandomLengthString(kRandomStringMaxBytes)).c_str());
sp<BBinder> handle(new BBinder());
sp<BnGraphicBufferProducer> producer;
sp<Surface> surfaceParent(
new Surface(producer, mFdp.ConsumeBool() /*controlledByApp*/, handle));
fuzzOnPullAtom();
SurfaceComposerClient::setDisplayContentSamplingEnabled(displayToken,
mFdp.ConsumeBool() /*enable*/,
mFdp.ConsumeIntegral<uint8_t>(),
mFdp.ConsumeIntegral<uint64_t>());
sp<IBinder> stopLayerHandle;
sp<gui::IRegionSamplingListener> listener = sp<gui::IRegionSamplingListenerDefault>::make();
sp<gui::IRegionSamplingListenerDelegator> sampleListener =
new gui::IRegionSamplingListenerDelegator(listener);
SurfaceComposerClient::addRegionSamplingListener(getRect(&mFdp), stopLayerHandle,
sampleListener);
sp<gui::IFpsListenerDefault> fpsListener;
SurfaceComposerClient::addFpsListener(mFdp.ConsumeIntegral<int32_t>(), fpsListener);
}
void SurfaceComposerClientFuzzer::invokeSurfaceComposerClientBinder() {
sp<FakeBnSurfaceComposerClient> client(new FakeBnSurfaceComposerClient());
fuzzService(client.get(), std::move(mFdp));
}
void SurfaceComposerClientFuzzer::process() {
invokeSurfaceComposerClient();
invokeSurfaceComposerTransaction();
invokeSurfaceComposerClientBinder();
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
SurfaceComposerClientFuzzer surfaceComposerClientFuzzer(data, size);
surfaceComposerClientFuzzer.process();
return 0;
}