SF: Remove EventControlThread
EventControlThread was a HWC workaround dating back to K for toggling
VSYNC off the main thread, but as of R it defers back to main only to
incur context switches.
Clean up TestableScheduler construction to skip creating DispSync and
timer threads, which fixes several gMock warnings of unexpected calls.
Remove virtual destructors for non-polymorphic interfaces.
Bug: 160012986
Test: systrace
Test: libsurfaceflinger_unittest
Change-Id: I01360016a7dba79dc905f250753e6fce34af0a90
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index 3c4a791..c46c914 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -40,7 +40,6 @@
"DispSyncSourceTest.cpp",
"DisplayIdentificationTest.cpp",
"DisplayTransactionTest.cpp",
- "EventControlThreadTest.cpp",
"EventThreadTest.cpp",
"HWComposerTest.cpp",
"OneShotTimerTest.cpp",
@@ -69,7 +68,6 @@
"mock/DisplayHardware/MockDisplay.cpp",
"mock/DisplayHardware/MockPowerAdvisor.cpp",
"mock/MockDispSync.cpp",
- "mock/MockEventControlThread.cpp",
"mock/MockEventThread.cpp",
"mock/MockMessageQueue.cpp",
"mock/MockNativeWindowSurface.cpp",
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 9add6a5..0c4c742 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -42,7 +42,6 @@
#include "mock/DisplayHardware/MockComposer.h"
#include "mock/DisplayHardware/MockPowerAdvisor.h"
#include "mock/MockDispSync.h"
-#include "mock/MockEventControlThread.h"
#include "mock/MockEventThread.h"
#include "mock/MockMessageQueue.h"
#include "mock/MockTimeStats.h"
@@ -150,11 +149,10 @@
.WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_REFRESH_RATE));
EXPECT_CALL(*primaryDispSync, expectedPresentTime(_)).WillRepeatedly(Return(0));
+ constexpr ISchedulerCallback* kCallback = nullptr;
constexpr bool kHasMultipleConfigs = true;
- mFlinger.setupScheduler(std::move(primaryDispSync),
- std::make_unique<mock::EventControlThread>(),
- std::move(eventThread), std::move(sfEventThread),
- kHasMultipleConfigs);
+ mFlinger.setupScheduler(std::move(primaryDispSync), std::move(eventThread),
+ std::move(sfEventThread), kCallback, kHasMultipleConfigs);
// Layer history should be created if there are multiple configs.
ASSERT_TRUE(mFlinger.scheduler()->hasLayerHistory());
@@ -897,7 +895,7 @@
static FlingerLayerType createLayer(CompositionTest* test) {
FlingerLayerType layer = Base::template createLayerWithFactory<EffectLayer>(test, [test]() {
return new EffectLayer(
- LayerCreationArgs(test->mFlinger.mFlinger.get(), sp<Client>(), "test-layer",
+ LayerCreationArgs(test->mFlinger.flinger(), sp<Client>(), "test-layer",
LayerProperties::WIDTH, LayerProperties::HEIGHT,
LayerProperties::LAYER_FLAGS, LayerMetadata()));
});
@@ -936,8 +934,7 @@
FlingerLayerType layer =
Base::template createLayerWithFactory<BufferQueueLayer>(test, [test]() {
- sp<Client> client;
- LayerCreationArgs args(test->mFlinger.mFlinger.get(), client, "test-layer",
+ LayerCreationArgs args(test->mFlinger.flinger(), sp<Client>(), "test-layer",
LayerProperties::WIDTH, LayerProperties::HEIGHT,
LayerProperties::LAYER_FLAGS, LayerMetadata());
args.textureName = test->mFlinger.mutableTexturePool().back();
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index 9130b04..e0e6873 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -46,10 +46,10 @@
#include "mock/DisplayHardware/MockComposer.h"
#include "mock/DisplayHardware/MockPowerAdvisor.h"
#include "mock/MockDispSync.h"
-#include "mock/MockEventControlThread.h"
#include "mock/MockEventThread.h"
#include "mock/MockMessageQueue.h"
#include "mock/MockNativeWindowSurface.h"
+#include "mock/MockSchedulerCallback.h"
#include "mock/MockSurfaceInterceptor.h"
#include "mock/system/window/MockNativeWindow.h"
@@ -156,7 +156,7 @@
mock::SurfaceInterceptor* mSurfaceInterceptor = new mock::SurfaceInterceptor();
mock::DispSync* mPrimaryDispSync = new mock::DispSync;
- mock::EventControlThread* mEventControlThread = new mock::EventControlThread;
+ mock::SchedulerCallback mSchedulerCallback;
mock::EventThread* mEventThread = new mock::EventThread;
mock::EventThread* mSFEventThread = new mock::EventThread;
@@ -214,9 +214,8 @@
ISurfaceComposer::eConfigChangedSuppress)));
mFlinger.setupScheduler(std::unique_ptr<DispSync>(mPrimaryDispSync),
- std::unique_ptr<EventControlThread>(mEventControlThread),
std::unique_ptr<EventThread>(mEventThread),
- std::unique_ptr<EventThread>(mSFEventThread));
+ std::unique_ptr<EventThread>(mSFEventThread), &mSchedulerCallback);
}
void DisplayTransactionTest::injectMockComposer(int virtualDisplayCount) {
@@ -1322,7 +1321,7 @@
// Call Expectations
// The call disable vsyncs
- EXPECT_CALL(*mEventControlThread, setVsyncEnabled(false)).Times(1);
+ EXPECT_CALL(mSchedulerCallback, setVsyncEnabled(false)).Times(1);
// The call ends any display resyncs
EXPECT_CALL(*mPrimaryDispSync, endResync()).Times(1);
@@ -3212,9 +3211,9 @@
};
struct EventThreadBaseSupportedVariant {
- static void setupEventAndEventControlThreadNoCallExpectations(DisplayTransactionTest* test) {
- // The event control thread should not be notified.
- EXPECT_CALL(*test->mEventControlThread, setVsyncEnabled(_)).Times(0);
+ static void setupVsyncAndEventThreadNoCallExpectations(DisplayTransactionTest* test) {
+ // The callback should not be notified to toggle VSYNC.
+ EXPECT_CALL(test->mSchedulerCallback, setVsyncEnabled(_)).Times(0);
// The event thread should not be notified.
EXPECT_CALL(*test->mEventThread, onScreenReleased()).Times(0);
@@ -3227,29 +3226,29 @@
// These calls are only expected for the primary display.
// Instead expect no calls.
- setupEventAndEventControlThreadNoCallExpectations(test);
+ setupVsyncAndEventThreadNoCallExpectations(test);
}
static void setupReleaseAndDisableVsyncCallExpectations(DisplayTransactionTest* test) {
// These calls are only expected for the primary display.
// Instead expect no calls.
- setupEventAndEventControlThreadNoCallExpectations(test);
+ setupVsyncAndEventThreadNoCallExpectations(test);
}
};
struct EventThreadIsSupportedVariant : public EventThreadBaseSupportedVariant {
static void setupAcquireAndEnableVsyncCallExpectations(DisplayTransactionTest* test) {
- // The event control thread should be notified to enable vsyncs
- EXPECT_CALL(*test->mEventControlThread, setVsyncEnabled(true)).Times(1);
+ // The callback should be notified to enable VSYNC.
+ EXPECT_CALL(test->mSchedulerCallback, setVsyncEnabled(true)).Times(1);
// The event thread should be notified that the screen was acquired.
EXPECT_CALL(*test->mEventThread, onScreenAcquired()).Times(1);
}
static void setupReleaseAndDisableVsyncCallExpectations(DisplayTransactionTest* test) {
- // There should be a call to setVsyncEnabled(false)
- EXPECT_CALL(*test->mEventControlThread, setVsyncEnabled(false)).Times(1);
+ // The callback should be notified to disable VSYNC.
+ EXPECT_CALL(test->mSchedulerCallback, setVsyncEnabled(false)).Times(1);
// The event thread should not be notified that the screen was released.
EXPECT_CALL(*test->mEventThread, onScreenReleased()).Times(1);
@@ -3308,7 +3307,7 @@
template <typename Case>
static void setupCallExpectations(DisplayTransactionTest* test) {
Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE_SUSPEND);
- Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
+ Case::EventThread::setupVsyncAndEventThreadNoCallExpectations(test);
Case::setupRepaintEverythingCallExpectations(test);
}
@@ -3335,7 +3334,7 @@
: public TransitionVariantCommon<PowerMode::DOZE_SUSPEND, PowerMode::OFF> {
template <typename Case>
static void setupCallExpectations(DisplayTransactionTest* test) {
- Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
+ Case::EventThread::setupVsyncAndEventThreadNoCallExpectations(test);
Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::OFF);
}
@@ -3347,7 +3346,7 @@
struct TransitionOnToDozeVariant : public TransitionVariantCommon<PowerMode::ON, PowerMode::DOZE> {
template <typename Case>
static void setupCallExpectations(DisplayTransactionTest* test) {
- Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
+ Case::EventThread::setupVsyncAndEventThreadNoCallExpectations(test);
Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE);
}
};
@@ -3365,7 +3364,7 @@
struct TransitionDozeToOnVariant : public TransitionVariantCommon<PowerMode::DOZE, PowerMode::ON> {
template <typename Case>
static void setupCallExpectations(DisplayTransactionTest* test) {
- Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
+ Case::EventThread::setupVsyncAndEventThreadNoCallExpectations(test);
Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::ON);
}
};
@@ -3394,7 +3393,7 @@
: public TransitionVariantCommon<PowerMode::ON, static_cast<PowerMode>(POWER_MODE_LEET)> {
template <typename Case>
static void setupCallExpectations(DisplayTransactionTest* test) {
- Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
+ Case::EventThread::setupVsyncAndEventThreadNoCallExpectations(test);
Case::setupNoComposerPowerModeCallExpectations(test);
}
};
diff --git a/services/surfaceflinger/tests/unittests/EventControlThreadTest.cpp b/services/surfaceflinger/tests/unittests/EventControlThreadTest.cpp
deleted file mode 100644
index 9dc4193..0000000
--- a/services/surfaceflinger/tests/unittests/EventControlThreadTest.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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 <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include <log/log.h>
-
-#include "AsyncCallRecorder.h"
-#include "Scheduler/EventControlThread.h"
-
-namespace android {
-namespace {
-
-using namespace std::chrono_literals;
-using testing::_;
-
-class EventControlThreadTest : public testing::Test {
-protected:
- EventControlThreadTest();
- ~EventControlThreadTest() override;
-
- void createThread();
-
- void expectVSyncEnableCallbackCalled(bool enable);
-
- AsyncCallRecorder<void (*)(bool)> mVSyncSetEnabledCallRecorder;
-
- std::unique_ptr<EventControlThread> mThread;
-};
-
-EventControlThreadTest::EventControlThreadTest() {
- 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());
-}
-
-EventControlThreadTest::~EventControlThreadTest() {
- 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 EventControlThreadTest::createThread() {
- mThread = std::make_unique<android::impl::EventControlThread>(
- mVSyncSetEnabledCallRecorder.getInvocable());
-}
-
-void EventControlThreadTest::expectVSyncEnableCallbackCalled(bool expectedEnabled) {
- auto args = mVSyncSetEnabledCallRecorder.waitForCall();
- ASSERT_TRUE(args.has_value());
- EXPECT_EQ(std::get<0>(args.value()), expectedEnabled);
-}
-
-/* ------------------------------------------------------------------------
- * Test cases
- */
-
-TEST_F(EventControlThreadTest, signalsVSyncDisabledOnStartup) {
- createThread();
-
- // On thread start, there should be an automatic explicit call to disable
- // vsyncs
- expectVSyncEnableCallbackCalled(false);
-}
-
-TEST_F(EventControlThreadTest, signalsVSyncDisabledOnce) {
- createThread();
- expectVSyncEnableCallbackCalled(false);
-
- mThread->setVsyncEnabled(false);
-
- EXPECT_FALSE(mVSyncSetEnabledCallRecorder.waitForUnexpectedCall().has_value());
-}
-
-TEST_F(EventControlThreadTest, signalsVSyncEnabledThenDisabled) {
- createThread();
- expectVSyncEnableCallbackCalled(false);
-
- mThread->setVsyncEnabled(true);
-
- expectVSyncEnableCallbackCalled(true);
-
- mThread->setVsyncEnabled(false);
-
- expectVSyncEnableCallbackCalled(false);
-}
-
-TEST_F(EventControlThreadTest, signalsVSyncEnabledOnce) {
- createThread();
- expectVSyncEnableCallbackCalled(false);
-
- mThread->setVsyncEnabled(true);
-
- expectVSyncEnableCallbackCalled(true);
-
- mThread->setVsyncEnabled(true);
-
- EXPECT_FALSE(mVSyncSetEnabledCallRecorder.waitForUnexpectedCall().has_value());
-}
-
-} // namespace
-} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/HWComposerTest.cpp b/services/surfaceflinger/tests/unittests/HWComposerTest.cpp
index 91b304c..fa12315 100644
--- a/services/surfaceflinger/tests/unittests/HWComposerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/HWComposerTest.cpp
@@ -23,7 +23,13 @@
#include <vector>
+// StrictMock<T> derives from T and is not marked final, so the destructor of T is expected to be
+// virtual in case StrictMock<T> is used as a polymorphic base class. That is not the case here.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
#include <gmock/gmock.h>
+#pragma clang diagnostic pop
+
#include <gui/LayerMetadata.h>
#include <log/log.h>
@@ -45,27 +51,20 @@
using ::testing::SetArgPointee;
using ::testing::StrictMock;
-struct MockHWC2ComposerCallback : public HWC2::ComposerCallback {
- ~MockHWC2ComposerCallback() = default;
-
- MOCK_METHOD3(onHotplugReceived,
- void(int32_t sequenceId, hal::HWDisplayId display, hal::Connection connection));
- MOCK_METHOD2(onRefreshReceived, void(int32_t sequenceId, hal::HWDisplayId display));
+struct MockHWC2ComposerCallback final : StrictMock<HWC2::ComposerCallback> {
+ MOCK_METHOD3(onHotplugReceived, void(int32_t sequenceId, hal::HWDisplayId, hal::Connection));
+ MOCK_METHOD2(onRefreshReceived, void(int32_t sequenceId, hal::HWDisplayId));
MOCK_METHOD4(onVsyncReceived,
- void(int32_t sequenceId, hal::HWDisplayId display, int64_t timestamp,
- std::optional<hal::VsyncPeriodNanos> vsyncPeriod));
+ void(int32_t sequenceId, hal::HWDisplayId, int64_t timestamp,
+ std::optional<hal::VsyncPeriodNanos>));
MOCK_METHOD3(onVsyncPeriodTimingChangedReceived,
- void(int32_t sequenceId, hal::HWDisplayId display,
- const hal::VsyncPeriodChangeTimeline& updatedTimeline));
- MOCK_METHOD2(onSeamlessPossible, void(int32_t sequenceId, hal::HWDisplayId display));
+ void(int32_t sequenceId, hal::HWDisplayId, const hal::VsyncPeriodChangeTimeline&));
+ MOCK_METHOD2(onSeamlessPossible, void(int32_t sequenceId, hal::HWDisplayId));
};
-struct HWComposerTest : public testing::Test {
+struct HWComposerSetConfigurationTest : testing::Test {
Hwc2::mock::Composer* mHal = new StrictMock<Hwc2::mock::Composer>();
-};
-
-struct HWComposerSetConfigurationTest : public HWComposerTest {
- StrictMock<MockHWC2ComposerCallback> mCallback;
+ MockHWC2ComposerCallback mCallback;
};
TEST_F(HWComposerSetConfigurationTest, loadsLayerMetadataSupport) {
diff --git a/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp b/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
index 3ab22d3..0fbe8ec 100644
--- a/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
@@ -30,6 +30,7 @@
#include "TestableScheduler.h"
#include "TestableSurfaceFlinger.h"
#include "mock/MockLayer.h"
+#include "mock/MockSchedulerCallback.h"
using testing::_;
using testing::Return;
@@ -75,7 +76,13 @@
.setConfigGroup(0)
.build()},
HwcConfigIndexType(0)};
- TestableScheduler* const mScheduler{new TestableScheduler(mConfigs, false)};
+
+ mock::NoOpSchedulerCallback mSchedulerCallback;
+ static constexpr bool kUseContentDetectionV2 = false;
+
+ TestableScheduler* const mScheduler =
+ new TestableScheduler(mConfigs, mSchedulerCallback, kUseContentDetectionV2);
+
TestableSurfaceFlinger mFlinger;
const nsecs_t mTime = systemTime();
diff --git a/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp b/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp
index 1705835..cb376cd 100644
--- a/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp
@@ -27,6 +27,7 @@
#include "TestableScheduler.h"
#include "TestableSurfaceFlinger.h"
#include "mock/MockLayer.h"
+#include "mock/MockSchedulerCallback.h"
using testing::_;
using testing::Return;
@@ -115,9 +116,14 @@
.setConfigGroup(0)
.build()},
HwcConfigIndexType(0)};
- TestableScheduler* const mScheduler{new TestableScheduler(mConfigs, true)};
- TestableSurfaceFlinger mFlinger;
+ mock::NoOpSchedulerCallback mSchedulerCallback;
+ static constexpr bool kUseContentDetectionV2 = true;
+
+ TestableScheduler* const mScheduler =
+ new TestableScheduler(mConfigs, mSchedulerCallback, kUseContentDetectionV2);
+
+ TestableSurfaceFlinger mFlinger;
};
namespace {
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp
index 43b8e01..f6bf05a 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp
@@ -32,7 +32,6 @@
#include "TestableSurfaceFlinger.h"
#include "mock/DisplayHardware/MockComposer.h"
#include "mock/MockDispSync.h"
-#include "mock/MockEventControlThread.h"
#include "mock/MockEventThread.h"
namespace android {
@@ -146,8 +145,7 @@
EXPECT_CALL(*primaryDispSync, getPeriod())
.WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_REFRESH_RATE));
EXPECT_CALL(*primaryDispSync, expectedPresentTime(_)).WillRepeatedly(Return(0));
- mFlinger.setupScheduler(std::move(primaryDispSync),
- std::make_unique<mock::EventControlThread>(), std::move(eventThread),
+ mFlinger.setupScheduler(std::move(primaryDispSync), std::move(eventThread),
std::move(sfEventThread));
}
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index 382199d..d6468b4 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -14,20 +14,12 @@
* limitations under the License.
*/
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wconversion"
-
-#undef LOG_TAG
-#define LOG_TAG "SchedulerUnittests"
-
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <log/log.h>
#include <mutex>
-#include "Scheduler/EventControlThread.h"
#include "Scheduler/EventThread.h"
#include "Scheduler/RefreshRateConfigs.h"
#include "TestableScheduler.h"
@@ -35,11 +27,13 @@
#include "mock/DisplayHardware/MockDisplay.h"
#include "mock/MockEventThread.h"
#include "mock/MockLayer.h"
+#include "mock/MockSchedulerCallback.h"
using testing::_;
using testing::Return;
namespace android {
+namespace {
constexpr PhysicalDisplayId PHYSICAL_DISPLAY_ID = 999;
@@ -58,7 +52,6 @@
};
SchedulerTest();
- ~SchedulerTest() override;
Hwc2::mock::Display mDisplay;
const scheduler::RefreshRateConfigs mConfigs{{HWC2::Display::Config::Builder(mDisplay, 0)
@@ -67,7 +60,17 @@
.build()},
HwcConfigIndexType(0)};
- TestableScheduler mScheduler{mConfigs, false};
+ mock::SchedulerCallback mSchedulerCallback;
+
+ // The scheduler should initially disable VSYNC.
+ struct ExpectDisableVsync {
+ ExpectDisableVsync(mock::SchedulerCallback& callback) {
+ EXPECT_CALL(callback, setVsyncEnabled(false)).Times(1);
+ }
+ } mExpectDisableVsync{mSchedulerCallback};
+
+ static constexpr bool kUseContentDetectionV2 = false;
+ TestableScheduler mScheduler{mConfigs, mSchedulerCallback, kUseContentDetectionV2};
Scheduler::ConnectionHandle mConnectionHandle;
mock::EventThread* mEventThread;
@@ -75,10 +78,6 @@
};
SchedulerTest::SchedulerTest() {
- 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());
-
auto eventThread = std::make_unique<mock::EventThread>();
mEventThread = eventThread.get();
EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_)).WillOnce(Return(0));
@@ -94,15 +93,7 @@
EXPECT_TRUE(mConnectionHandle);
}
-SchedulerTest::~SchedulerTest() {
- 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());
-}
-
-/* ------------------------------------------------------------------------
- * Test cases
- */
+} // namespace
TEST_F(SchedulerTest, invalidConnectionHandle) {
Scheduler::ConnectionHandle handle;
@@ -159,8 +150,7 @@
mScheduler.setPhaseOffset(mConnectionHandle, 10);
static constexpr size_t kEventConnections = 5;
- ON_CALL(*mEventThread, getEventThreadConnectionCount())
- .WillByDefault(Return(kEventConnections));
+ EXPECT_CALL(*mEventThread, getEventThreadConnectionCount()).WillOnce(Return(kEventConnections));
EXPECT_EQ(kEventConnections, mScheduler.getEventThreadConnectionCount(mConnectionHandle));
}
@@ -181,11 +171,8 @@
constexpr uint32_t kDisplayArea = 999'999;
mScheduler.onPrimaryDisplayAreaChanged(kDisplayArea);
+ EXPECT_CALL(mSchedulerCallback, changeRefreshRate(_, _)).Times(0);
mScheduler.chooseRefreshRateForContent();
- EXPECT_EQ(0, mScheduler.refreshRateChangeCount());
}
} // namespace android
-
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic pop // ignored "-Wconversion"
diff --git a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
index 0d6c799..6c01f85 100644
--- a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
@@ -33,7 +33,6 @@
#include "TestableSurfaceFlinger.h"
#include "mock/DisplayHardware/MockComposer.h"
#include "mock/MockDispSync.h"
-#include "mock/MockEventControlThread.h"
#include "mock/MockEventThread.h"
#include "mock/MockMessageQueue.h"
@@ -182,8 +181,7 @@
EXPECT_CALL(*primaryDispSync, getPeriod())
.WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_REFRESH_RATE));
EXPECT_CALL(*primaryDispSync, expectedPresentTime(_)).WillRepeatedly(Return(0));
- mFlinger.setupScheduler(std::move(primaryDispSync),
- std::make_unique<mock::EventControlThread>(), std::move(eventThread),
+ mFlinger.setupScheduler(std::move(primaryDispSync), std::move(eventThread),
std::move(sfEventThread));
}
diff --git a/services/surfaceflinger/tests/unittests/TestableScheduler.h b/services/surfaceflinger/tests/unittests/TestableScheduler.h
index c463294..d78546d 100644
--- a/services/surfaceflinger/tests/unittests/TestableScheduler.h
+++ b/services/surfaceflinger/tests/unittests/TestableScheduler.h
@@ -23,20 +23,27 @@
#include "Scheduler/EventThread.h"
#include "Scheduler/LayerHistory.h"
#include "Scheduler/Scheduler.h"
+#include "Scheduler/VSyncTracker.h"
+#include "mock/MockDispSync.h"
namespace android {
-class TestableScheduler : public Scheduler, private ISchedulerCallback {
+class TestableScheduler : public Scheduler {
public:
- TestableScheduler(const scheduler::RefreshRateConfigs& configs, bool useContentDetectionV2)
- : Scheduler([](bool) {}, configs, *this, useContentDetectionV2, true) {}
+ TestableScheduler(const scheduler::RefreshRateConfigs& configs, ISchedulerCallback& callback,
+ bool useContentDetectionV2)
+ : TestableScheduler(std::make_unique<mock::DispSync>(), configs, callback,
+ useContentDetectionV2) {}
TestableScheduler(std::unique_ptr<DispSync> primaryDispSync,
- std::unique_ptr<EventControlThread> eventControlThread,
- const scheduler::RefreshRateConfigs& configs, bool useContentDetectionV2)
- : Scheduler(std::move(primaryDispSync), std::move(eventControlThread), configs, *this,
- createLayerHistory(configs, useContentDetectionV2), useContentDetectionV2,
- true) {}
+ const scheduler::RefreshRateConfigs& configs, ISchedulerCallback& callback,
+ bool useContentDetectionV2)
+ : Scheduler({std::move(primaryDispSync), nullptr, nullptr}, configs, callback,
+ createLayerHistory(configs, useContentDetectionV2),
+ {.supportKernelTimer = false,
+ .useContentDetection = true,
+ .useContentDetectionV2 = useContentDetectionV2,
+ .useVsyncPredictor = false}) {}
// Used to inject mock event thread.
ConnectionHandle createConnection(std::unique_ptr<EventThread> eventThread) {
@@ -48,28 +55,24 @@
* post-conditions.
*/
auto& mutablePrimaryHWVsyncEnabled() { return mPrimaryHWVsyncEnabled; }
- auto& mutableEventControlThread() { return mEventControlThread; }
- auto& mutablePrimaryDispSync() { return mPrimaryDispSync; }
auto& mutableHWVsyncAvailable() { return mHWVsyncAvailable; }
- size_t refreshRateChangeCount() const { return mRefreshRateChangeCount; }
-
bool hasLayerHistory() const { return static_cast<bool>(mLayerHistory); }
auto* mutableLayerHistory() {
- LOG_ALWAYS_FATAL_IF(mUseContentDetectionV2);
+ LOG_ALWAYS_FATAL_IF(mOptions.useContentDetectionV2);
return static_cast<scheduler::impl::LayerHistory*>(mLayerHistory.get());
}
auto* mutableLayerHistoryV2() {
- LOG_ALWAYS_FATAL_IF(!mUseContentDetectionV2);
+ LOG_ALWAYS_FATAL_IF(!mOptions.useContentDetectionV2);
return static_cast<scheduler::impl::LayerHistoryV2*>(mLayerHistory.get());
}
size_t layerHistorySize() NO_THREAD_SAFETY_ANALYSIS {
if (!mLayerHistory) return 0;
- return mUseContentDetectionV2 ? mutableLayerHistoryV2()->mLayerInfos.size()
- : mutableLayerHistory()->mLayerInfos.size();
+ return mOptions.useContentDetectionV2 ? mutableLayerHistoryV2()->mLayerInfos.size()
+ : mutableLayerHistory()->mLayerInfos.size();
}
void replaceTouchTimer(int64_t millis) {
@@ -93,18 +96,9 @@
// not report a leaked object, since the Scheduler instance may
// still be referenced by something despite our best efforts to destroy
// it after each test is done.
- mutableEventControlThread().reset();
- mutablePrimaryDispSync().reset();
+ mVsyncSchedule.sync.reset();
mConnections.clear();
}
-
-private:
- void changeRefreshRate(const RefreshRate&, ConfigEvent) override { mRefreshRateChangeCount++; }
-
- void repaintEverythingForHWC() override {}
- void kernelTimerChanged(bool /*expired*/) override {}
-
- size_t mRefreshRateChangeCount = 0;
};
} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 256e048..cb748ba 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -69,11 +69,6 @@
return nullptr;
}
- std::unique_ptr<EventControlThread> createEventControlThread(
- std::function<void(bool)>) override {
- return nullptr;
- }
-
std::unique_ptr<HWComposer> createHWComposer(const std::string&) override {
return nullptr;
}
@@ -87,8 +82,7 @@
return std::make_unique<scheduler::FakePhaseOffsets>();
}
- std::unique_ptr<Scheduler> createScheduler(std::function<void(bool)>,
- const scheduler::RefreshRateConfigs&,
+ std::unique_ptr<Scheduler> createScheduler(const scheduler::RefreshRateConfigs&,
ISchedulerCallback&) override {
return nullptr;
}
@@ -175,7 +169,7 @@
} // namespace surfaceflinger::test
-class TestableSurfaceFlinger {
+class TestableSurfaceFlinger final : private ISchedulerCallback {
public:
using HotplugEvent = SurfaceFlinger::HotplugEvent;
@@ -198,11 +192,11 @@
mFlinger->mCompositionEngine->setTimeStats(timeStats);
}
+ // The ISchedulerCallback argument can be nullptr for a no-op implementation.
void setupScheduler(std::unique_ptr<DispSync> primaryDispSync,
- std::unique_ptr<EventControlThread> eventControlThread,
std::unique_ptr<EventThread> appEventThread,
std::unique_ptr<EventThread> sfEventThread,
- bool hasMultipleConfigs = false) {
+ ISchedulerCallback* callback = nullptr, bool hasMultipleConfigs = false) {
std::vector<std::shared_ptr<const HWC2::Display::Config>> configs{
HWC2::Display::Config::Builder(mDisplay, 0)
.setVsyncPeriod(16'666'667)
@@ -227,8 +221,8 @@
constexpr bool kUseContentDetectionV2 = false;
mScheduler =
- new TestableScheduler(std::move(primaryDispSync), std::move(eventControlThread),
- *mFlinger->mRefreshRateConfigs, kUseContentDetectionV2);
+ new TestableScheduler(std::move(primaryDispSync), *mFlinger->mRefreshRateConfigs,
+ *(callback ?: this), kUseContentDetectionV2);
mFlinger->mAppConnectionHandle = mScheduler->createConnection(std::move(appEventThread));
mFlinger->mSfConnectionHandle = mScheduler->createConnection(std::move(sfEventThread));
@@ -667,6 +661,12 @@
const std::optional<hal::HWDisplayId> mHwcDisplayId;
};
+private:
+ void setVsyncEnabled(bool) override {}
+ void changeRefreshRate(const Scheduler::RefreshRate&, Scheduler::ConfigEvent) override {}
+ void repaintEverythingForHWC() override {}
+ void kernelTimerChanged(bool) override {}
+
surfaceflinger::test::Factory mFactory;
sp<SurfaceFlinger> mFlinger = new SurfaceFlinger(mFactory, SurfaceFlinger::SkipInitialization);
TestableScheduler* mScheduler = nullptr;
diff --git a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
index 2a48a22..44b3dc0 100644
--- a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
@@ -32,7 +32,6 @@
#include "TestableScheduler.h"
#include "TestableSurfaceFlinger.h"
#include "mock/MockDispSync.h"
-#include "mock/MockEventControlThread.h"
#include "mock/MockEventThread.h"
#include "mock/MockMessageQueue.h"
@@ -81,7 +80,6 @@
.WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_REFRESH_RATE));
mFlinger.setupScheduler(std::unique_ptr<mock::DispSync>(mPrimaryDispSync),
- std::make_unique<mock::EventControlThread>(),
std::move(eventThread), std::move(sfEventThread));
}
@@ -89,7 +87,6 @@
TestableSurfaceFlinger mFlinger;
std::unique_ptr<mock::EventThread> mEventThread = std::make_unique<mock::EventThread>();
- mock::EventControlThread* mEventControlThread = new mock::EventControlThread();
mock::MessageQueue* mMessageQueue = new mock::MessageQueue();
mock::DispSync* mPrimaryDispSync = new mock::DispSync();
diff --git a/services/surfaceflinger/tests/unittests/VSyncModulatorTest.cpp b/services/surfaceflinger/tests/unittests/VSyncModulatorTest.cpp
index 9c1ec07..af1e84b 100644
--- a/services/surfaceflinger/tests/unittests/VSyncModulatorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncModulatorTest.cpp
@@ -27,15 +27,15 @@
namespace android::scheduler {
-class MockScheduler : public IPhaseOffsetControl {
+class MockScheduler final : public IPhaseOffsetControl {
public:
- void setPhaseOffset(ConnectionHandle handle, nsecs_t phaseOffset) {
- mPhaseOffset[handle] = phaseOffset;
- }
-
nsecs_t getOffset(ConnectionHandle handle) { return mPhaseOffset[handle]; }
private:
+ void setPhaseOffset(ConnectionHandle handle, nsecs_t phaseOffset) override {
+ mPhaseOffset[handle] = phaseOffset;
+ }
+
std::unordered_map<ConnectionHandle, nsecs_t> mPhaseOffset;
};
diff --git a/services/surfaceflinger/tests/unittests/mock/MockEventControlThread.cpp b/services/surfaceflinger/tests/unittests/mock/MockEventControlThread.cpp
deleted file mode 100644
index f9bacc8..0000000
--- a/services/surfaceflinger/tests/unittests/mock/MockEventControlThread.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.
- */
-
-#include "mock/MockEventControlThread.h"
-
-namespace android {
-namespace mock {
-
-// Explicit default instantiation is recommended.
-EventControlThread::EventControlThread() = default;
-EventControlThread::~EventControlThread() = default;
-
-} // namespace mock
-} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/MockEventControlThread.h b/services/surfaceflinger/tests/unittests/mock/MockEventControlThread.h
deleted file mode 100644
index 6ef352a..0000000
--- a/services/surfaceflinger/tests/unittests/mock/MockEventControlThread.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <gmock/gmock.h>
-
-#include "Scheduler/EventControlThread.h"
-
-namespace android {
-namespace mock {
-
-class EventControlThread : public android::EventControlThread {
-public:
- EventControlThread();
- ~EventControlThread() override;
-
- MOCK_METHOD1(setVsyncEnabled, void(bool));
-};
-
-} // namespace mock
-} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/MockSchedulerCallback.h b/services/surfaceflinger/tests/unittests/mock/MockSchedulerCallback.h
new file mode 100644
index 0000000..72bc89c
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/mock/MockSchedulerCallback.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2020 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 <gmock/gmock.h>
+
+#include "Scheduler/Scheduler.h"
+
+namespace android::mock {
+
+struct SchedulerCallback final : ISchedulerCallback {
+ MOCK_METHOD1(setVsyncEnabled, void(bool));
+ MOCK_METHOD2(changeRefreshRate,
+ void(const scheduler::RefreshRateConfigs::RefreshRate&,
+ scheduler::RefreshRateConfigEvent));
+ MOCK_METHOD0(repaintEverythingForHWC, void());
+ MOCK_METHOD1(kernelTimerChanged, void(bool));
+};
+
+struct NoOpSchedulerCallback final : ISchedulerCallback {
+ void setVsyncEnabled(bool) override {}
+ void changeRefreshRate(const scheduler::RefreshRateConfigs::RefreshRate&,
+ scheduler::RefreshRateConfigEvent) override {}
+ void repaintEverythingForHWC() override {}
+ void kernelTimerChanged(bool) override {}
+};
+
+} // namespace android::mock