You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
203 lines
8.2 KiB
203 lines
8.2 KiB
/*
|
|
* Copyright (C) 2018 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.
|
|
*/
|
|
|
|
#undef LOG_TAG
|
|
#define LOG_TAG "LibSurfaceFlingerUnittests"
|
|
|
|
#include "DisplayTransactionTestHelpers.h"
|
|
|
|
namespace android {
|
|
|
|
using testing::AnyNumber;
|
|
using testing::DoAll;
|
|
using testing::Mock;
|
|
using testing::Return;
|
|
using testing::SetArgPointee;
|
|
|
|
using android::hardware::graphics::composer::hal::HWDisplayId;
|
|
|
|
using FakeDisplayDeviceInjector = TestableSurfaceFlinger::FakeDisplayDeviceInjector;
|
|
|
|
DisplayTransactionTest::DisplayTransactionTest() {
|
|
const ::testing::TestInfo* const test_info =
|
|
::testing::UnitTest::GetInstance()->current_test_info();
|
|
ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
|
|
|
|
// Default to no wide color display support configured
|
|
mFlinger.mutableHasWideColorDisplay() = false;
|
|
mFlinger.mutableUseColorManagement() = false;
|
|
mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::kUnmanaged;
|
|
|
|
mFlinger.setCreateBufferQueueFunction([](auto, auto, auto) {
|
|
ADD_FAILURE() << "Unexpected request to create a buffer queue.";
|
|
});
|
|
|
|
mFlinger.setCreateNativeWindowSurface([](auto) {
|
|
ADD_FAILURE() << "Unexpected request to create a native window surface.";
|
|
return nullptr;
|
|
});
|
|
|
|
injectMockScheduler();
|
|
mFlinger.mutableEventQueue().reset(mMessageQueue);
|
|
mFlinger.setupRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine));
|
|
mFlinger.mutableInterceptor() = mSurfaceInterceptor;
|
|
|
|
injectMockComposer(0);
|
|
}
|
|
|
|
DisplayTransactionTest::~DisplayTransactionTest() {
|
|
const ::testing::TestInfo* const test_info =
|
|
::testing::UnitTest::GetInstance()->current_test_info();
|
|
ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
|
|
}
|
|
|
|
void DisplayTransactionTest::injectMockScheduler() {
|
|
EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_));
|
|
EXPECT_CALL(*mEventThread, createEventConnection(_, _))
|
|
.WillOnce(Return(
|
|
new EventThreadConnection(mEventThread, /*callingUid=*/0, ResyncCallback())));
|
|
|
|
EXPECT_CALL(*mSFEventThread, registerDisplayEventConnection(_));
|
|
EXPECT_CALL(*mSFEventThread, createEventConnection(_, _))
|
|
.WillOnce(Return(
|
|
new EventThreadConnection(mSFEventThread, /*callingUid=*/0, ResyncCallback())));
|
|
|
|
mFlinger.setupScheduler(std::unique_ptr<scheduler::VsyncController>(mVsyncController),
|
|
std::unique_ptr<scheduler::VSyncTracker>(mVSyncTracker),
|
|
std::unique_ptr<EventThread>(mEventThread),
|
|
std::unique_ptr<EventThread>(mSFEventThread), &mSchedulerCallback);
|
|
}
|
|
|
|
void DisplayTransactionTest::injectMockComposer(int virtualDisplayCount) {
|
|
if (mComposer) {
|
|
// If reinjecting, disable first to prevent the enable below from being a no-op.
|
|
mFlinger.enableHalVirtualDisplays(false);
|
|
}
|
|
|
|
mComposer = new Hwc2::mock::Composer();
|
|
mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer));
|
|
|
|
EXPECT_CALL(*mComposer, getMaxVirtualDisplayCount()).WillOnce(Return(virtualDisplayCount));
|
|
mFlinger.enableHalVirtualDisplays(true);
|
|
|
|
Mock::VerifyAndClear(mComposer);
|
|
}
|
|
|
|
void DisplayTransactionTest::injectFakeBufferQueueFactory() {
|
|
// This setup is only expected once per test.
|
|
ASSERT_TRUE(mConsumer == nullptr && mProducer == nullptr);
|
|
|
|
mConsumer = new mock::GraphicBufferConsumer();
|
|
mProducer = new mock::GraphicBufferProducer();
|
|
|
|
mFlinger.setCreateBufferQueueFunction([this](auto outProducer, auto outConsumer, bool) {
|
|
*outProducer = mProducer;
|
|
*outConsumer = mConsumer;
|
|
});
|
|
}
|
|
|
|
void DisplayTransactionTest::injectFakeNativeWindowSurfaceFactory() {
|
|
// This setup is only expected once per test.
|
|
ASSERT_TRUE(mNativeWindowSurface == nullptr);
|
|
|
|
mNativeWindowSurface = new surfaceflinger::mock::NativeWindowSurface();
|
|
|
|
mFlinger.setCreateNativeWindowSurface([this](auto) {
|
|
return std::unique_ptr<surfaceflinger::NativeWindowSurface>(mNativeWindowSurface);
|
|
});
|
|
}
|
|
|
|
sp<DisplayDevice> DisplayTransactionTest::injectDefaultInternalDisplay(
|
|
std::function<void(FakeDisplayDeviceInjector&)> injectExtra) {
|
|
constexpr PhysicalDisplayId DEFAULT_DISPLAY_ID(777);
|
|
constexpr int DEFAULT_DISPLAY_WIDTH = 1080;
|
|
constexpr int DEFAULT_DISPLAY_HEIGHT = 1920;
|
|
constexpr HWDisplayId DEFAULT_DISPLAY_HWC_DISPLAY_ID = 0;
|
|
|
|
// The DisplayDevice is required to have a framebuffer (behind the
|
|
// ANativeWindow interface) which uses the actual hardware display
|
|
// size.
|
|
EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
|
|
.WillRepeatedly(DoAll(SetArgPointee<1>(DEFAULT_DISPLAY_WIDTH), Return(0)));
|
|
EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
|
|
.WillRepeatedly(DoAll(SetArgPointee<1>(DEFAULT_DISPLAY_HEIGHT), Return(0)));
|
|
EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT));
|
|
EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT));
|
|
EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64));
|
|
EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT)).Times(AnyNumber());
|
|
|
|
constexpr auto kConnectionType = ui::DisplayConnectionType::Internal;
|
|
constexpr bool kIsPrimary = true;
|
|
|
|
auto compositionDisplay =
|
|
compositionengine::impl::createDisplay(mFlinger.getCompositionEngine(),
|
|
compositionengine::DisplayCreationArgsBuilder()
|
|
.setId(DEFAULT_DISPLAY_ID)
|
|
.setConnectionType(kConnectionType)
|
|
.setPixels({DEFAULT_DISPLAY_WIDTH,
|
|
DEFAULT_DISPLAY_HEIGHT})
|
|
.setPowerAdvisor(&mPowerAdvisor)
|
|
.build());
|
|
|
|
auto injector = FakeDisplayDeviceInjector(mFlinger, compositionDisplay, kConnectionType,
|
|
DEFAULT_DISPLAY_HWC_DISPLAY_ID, kIsPrimary);
|
|
|
|
injector.setNativeWindow(mNativeWindow);
|
|
if (injectExtra) {
|
|
injectExtra(injector);
|
|
}
|
|
|
|
auto displayDevice = injector.inject();
|
|
|
|
Mock::VerifyAndClear(mNativeWindow.get());
|
|
|
|
return displayDevice;
|
|
}
|
|
|
|
bool DisplayTransactionTest::hasPhysicalHwcDisplay(HWDisplayId hwcDisplayId) {
|
|
return mFlinger.mutableHwcPhysicalDisplayIdMap().count(hwcDisplayId) == 1;
|
|
}
|
|
|
|
bool DisplayTransactionTest::hasTransactionFlagSet(int flag) {
|
|
return mFlinger.mutableTransactionFlags() & flag;
|
|
}
|
|
|
|
bool DisplayTransactionTest::hasDisplayDevice(sp<IBinder> displayToken) {
|
|
return mFlinger.mutableDisplays().count(displayToken) == 1;
|
|
}
|
|
|
|
sp<DisplayDevice> DisplayTransactionTest::getDisplayDevice(sp<IBinder> displayToken) {
|
|
return mFlinger.mutableDisplays()[displayToken];
|
|
}
|
|
|
|
bool DisplayTransactionTest::hasCurrentDisplayState(sp<IBinder> displayToken) {
|
|
return mFlinger.mutableCurrentState().displays.indexOfKey(displayToken) >= 0;
|
|
}
|
|
|
|
const DisplayDeviceState& DisplayTransactionTest::getCurrentDisplayState(sp<IBinder> displayToken) {
|
|
return mFlinger.mutableCurrentState().displays.valueFor(displayToken);
|
|
}
|
|
|
|
bool DisplayTransactionTest::hasDrawingDisplayState(sp<IBinder> displayToken) {
|
|
return mFlinger.mutableDrawingState().displays.indexOfKey(displayToken) >= 0;
|
|
}
|
|
|
|
const DisplayDeviceState& DisplayTransactionTest::getDrawingDisplayState(sp<IBinder> displayToken) {
|
|
return mFlinger.mutableDrawingState().displays.valueFor(displayToken);
|
|
}
|
|
|
|
} // namespace android
|