SF: Register resync callback per event connection
This CL ties the resync callback to an EventThreadConnection instead
of an EventThread. This is a step towards having IDisplayEventConnection
subscribe to a given display rather than the primary display implicitly.
Each display will then have SurfaceFlinger::VsyncState that resyncs
independently at potentially different rates. Callbacks have weak
references to the per-display VsyncState owned by SurfaceFlinger.
Bug: 74619554
Test: Boot and turn display on/off repeatedly
Change-Id: Ic7cc64e2004fa07a5d54431fc330995048a4ed20
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index bf925b2..7b25adb 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -43,8 +43,12 @@
// ---------------------------------------------------------------------------
-EventThreadConnection::EventThreadConnection(EventThread* eventThread)
- : count(-1), mEventThread(eventThread), mChannel(gui::BitTube::DefaultSize) {}
+EventThreadConnection::EventThreadConnection(EventThread* eventThread,
+ ResyncCallback resyncCallback)
+ : resyncCallback(std::move(resyncCallback)),
+ count(-1),
+ mEventThread(eventThread),
+ mChannel(gui::BitTube::DefaultSize) {}
EventThreadConnection::~EventThreadConnection() {
// do nothing here -- clean-up will happen automatically
@@ -88,26 +92,21 @@
namespace impl {
EventThread::EventThread(std::unique_ptr<VSyncSource> src,
- const ResyncWithRateLimitCallback& resyncWithRateLimitCallback,
const InterceptVSyncsCallback& interceptVSyncsCallback,
const ResetIdleTimerCallback& resetIdleTimerCallback,
const char* threadName)
- : EventThread(nullptr, std::move(src), resyncWithRateLimitCallback, interceptVSyncsCallback,
- threadName) {
+ : EventThread(nullptr, std::move(src), interceptVSyncsCallback, threadName) {
mResetIdleTimer = resetIdleTimerCallback;
}
-EventThread::EventThread(VSyncSource* src, ResyncWithRateLimitCallback resyncWithRateLimitCallback,
- InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName)
- : EventThread(src, nullptr, resyncWithRateLimitCallback, interceptVSyncsCallback,
- threadName) {}
+EventThread::EventThread(VSyncSource* src, InterceptVSyncsCallback interceptVSyncsCallback,
+ const char* threadName)
+ : EventThread(src, nullptr, interceptVSyncsCallback, threadName) {}
EventThread::EventThread(VSyncSource* src, std::unique_ptr<VSyncSource> uniqueSrc,
- ResyncWithRateLimitCallback resyncWithRateLimitCallback,
InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName)
: mVSyncSource(src),
mVSyncSourceUnique(std::move(uniqueSrc)),
- mResyncWithRateLimitCallback(resyncWithRateLimitCallback),
mInterceptVSyncsCallback(interceptVSyncsCallback) {
if (src == nullptr) {
mVSyncSource = mVSyncSourceUnique.get();
@@ -150,8 +149,8 @@
mVSyncSource->setPhaseOffset(phaseOffset);
}
-sp<EventThreadConnection> EventThread::createEventConnection() const {
- return new EventThreadConnection(const_cast<EventThread*>(this));
+sp<EventThreadConnection> EventThread::createEventConnection(ResyncCallback resyncCallback) const {
+ return new EventThreadConnection(const_cast<EventThread*>(this), std::move(resyncCallback));
}
status_t EventThread::registerDisplayEventConnection(const sp<EventThreadConnection>& connection) {
@@ -195,8 +194,9 @@
ATRACE_NAME("resetIdleTimer");
mResetIdleTimer();
}
- if (mResyncWithRateLimitCallback) {
- mResyncWithRateLimitCallback();
+
+ if (connection->resyncCallback) {
+ connection->resyncCallback();
}
std::lock_guard<std::mutex> lock(mMutex);
diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h
index e110488..a411885 100644
--- a/services/surfaceflinger/Scheduler/EventThread.h
+++ b/services/surfaceflinger/Scheduler/EventThread.h
@@ -44,6 +44,8 @@
// ---------------------------------------------------------------------------
+using ResyncCallback = std::function<void()>;
+
class VSyncSource {
public:
class Callback {
@@ -60,7 +62,7 @@
class EventThreadConnection : public BnDisplayEventConnection {
public:
- explicit EventThreadConnection(EventThread* eventThread);
+ EventThreadConnection(EventThread* eventThread, ResyncCallback resyncCallback);
virtual ~EventThreadConnection();
virtual status_t postEvent(const DisplayEventReceiver::Event& event);
@@ -72,6 +74,9 @@
// in order to update the configs.
void requestNextVsyncForHWC();
+ // Called in response to requestNextVsync.
+ const ResyncCallback resyncCallback;
+
// count >= 1 : continuous event. count is the vsync rate
// count == 0 : one-shot event that has not fired
// count ==-1 : one-shot event that fired this round / disabled
@@ -90,7 +95,8 @@
virtual ~EventThread();
- virtual sp<EventThreadConnection> createEventConnection() const = 0;
+ virtual sp<EventThreadConnection> createEventConnection(
+ ResyncCallback resyncCallback) const = 0;
// called before the screen is turned off from main thread
virtual void onScreenReleased() = 0;
@@ -117,20 +123,18 @@
class EventThread : public android::EventThread, private VSyncSource::Callback {
public:
- using ResyncWithRateLimitCallback = std::function<void()>;
using InterceptVSyncsCallback = std::function<void(nsecs_t)>;
using ResetIdleTimerCallback = std::function<void()>;
// TODO(b/113612090): Once the Scheduler is complete this constructor will become obsolete.
- EventThread(VSyncSource* src, ResyncWithRateLimitCallback resyncWithRateLimitCallback,
- InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName);
+ EventThread(VSyncSource* src, InterceptVSyncsCallback interceptVSyncsCallback,
+ const char* threadName);
EventThread(std::unique_ptr<VSyncSource> src,
- const ResyncWithRateLimitCallback& resyncWithRateLimitCallback,
const InterceptVSyncsCallback& interceptVSyncsCallback,
const ResetIdleTimerCallback& resetIdleTimerCallback, const char* threadName);
~EventThread();
- sp<EventThreadConnection> createEventConnection() const override;
+ sp<EventThreadConnection> createEventConnection(ResyncCallback resyncCallback) const override;
status_t registerDisplayEventConnection(const sp<EventThreadConnection>& connection) override;
void setVsyncRate(uint32_t count, const sp<EventThreadConnection>& connection) override;
@@ -155,7 +159,6 @@
// TODO(b/113612090): Once the Scheduler is complete this constructor will become obsolete.
EventThread(VSyncSource* src, std::unique_ptr<VSyncSource> uniqueSrc,
- ResyncWithRateLimitCallback resyncWithRateLimitCallback,
InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName);
@@ -179,7 +182,6 @@
VSyncSource* mVSyncSource GUARDED_BY(mMutex) = nullptr;
std::unique_ptr<VSyncSource> mVSyncSourceUnique GUARDED_BY(mMutex) = nullptr;
// constants
- const ResyncWithRateLimitCallback mResyncWithRateLimitCallback;
const InterceptVSyncsCallback mInterceptVSyncsCallback;
std::thread mThread;
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.cpp b/services/surfaceflinger/Scheduler/MessageQueue.cpp
index 66f42bb..75a410b 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.cpp
+++ b/services/surfaceflinger/Scheduler/MessageQueue.cpp
@@ -85,7 +85,8 @@
mHandler = new Handler(*this);
}
-void MessageQueue::setEventThread(android::EventThread* eventThread) {
+void MessageQueue::setEventThread(android::EventThread* eventThread,
+ ResyncCallback resyncCallback) {
if (mEventThread == eventThread) {
return;
}
@@ -95,7 +96,7 @@
}
mEventThread = eventThread;
- mEvents = eventThread->createEventConnection();
+ mEvents = eventThread->createEventConnection(std::move(resyncCallback));
mEvents->stealReceiveChannel(&mEventTube);
mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver,
this);
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.h b/services/surfaceflinger/Scheduler/MessageQueue.h
index 0bf00b0..56a00c0 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.h
+++ b/services/surfaceflinger/Scheduler/MessageQueue.h
@@ -29,12 +29,12 @@
#include <private/gui/BitTube.h>
#include "Barrier.h"
+#include "EventThread.h"
#include <functional>
namespace android {
-class EventThread;
class SurfaceFlinger;
// ---------------------------------------------------------------------------
@@ -86,7 +86,7 @@
virtual void init(const sp<SurfaceFlinger>& flinger) = 0;
// TODO(akrulec): Remove this function once everything is migrated to Scheduler.
- virtual void setEventThread(EventThread* events) = 0;
+ virtual void setEventThread(EventThread* events, ResyncCallback resyncCallback) = 0;
virtual void setEventConnection(const sp<EventThreadConnection>& connection) = 0;
virtual void waitMessage() = 0;
virtual status_t postMessage(const sp<MessageBase>& message, nsecs_t reltime = 0) = 0;
@@ -127,7 +127,7 @@
public:
~MessageQueue() override = default;
void init(const sp<SurfaceFlinger>& flinger) override;
- void setEventThread(android::EventThread* events) override;
+ void setEventThread(android::EventThread* events, ResyncCallback resyncCallback) override;
void setEventConnection(const sp<EventThreadConnection>& connection) override;
void waitMessage() override;
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index fec53af..0d587dd 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -86,39 +86,38 @@
Scheduler::~Scheduler() = default;
sp<Scheduler::ConnectionHandle> Scheduler::createConnection(
- const std::string& connectionName, int64_t phaseOffsetNs,
- impl::EventThread::ResyncWithRateLimitCallback resyncCallback,
+ const std::string& connectionName, int64_t phaseOffsetNs, ResyncCallback resyncCallback,
impl::EventThread::InterceptVSyncsCallback interceptCallback) {
const int64_t id = sNextId++;
ALOGV("Creating a connection handle with ID: %" PRId64 "\n", id);
std::unique_ptr<EventThread> eventThread =
- makeEventThread(connectionName, mPrimaryDispSync.get(), phaseOffsetNs, resyncCallback,
+ makeEventThread(connectionName, mPrimaryDispSync.get(), phaseOffsetNs,
interceptCallback);
auto connection = std::make_unique<Connection>(new ConnectionHandle(id),
- eventThread->createEventConnection(),
+ eventThread->createEventConnection(
+ std::move(resyncCallback)),
std::move(eventThread));
+
mConnections.insert(std::make_pair(id, std::move(connection)));
return mConnections[id]->handle;
}
std::unique_ptr<EventThread> Scheduler::makeEventThread(
const std::string& connectionName, DispSync* dispSync, int64_t phaseOffsetNs,
- impl::EventThread::ResyncWithRateLimitCallback resyncCallback,
impl::EventThread::InterceptVSyncsCallback interceptCallback) {
const std::string sourceName = connectionName + "Source";
std::unique_ptr<VSyncSource> eventThreadSource =
std::make_unique<DispSyncSource>(dispSync, phaseOffsetNs, true, sourceName.c_str());
const std::string threadName = connectionName + "Thread";
- return std::make_unique<impl::EventThread>(std::move(eventThreadSource), resyncCallback,
- interceptCallback, [this] { resetIdleTimer(); },
- threadName.c_str());
+ return std::make_unique<impl::EventThread>(std::move(eventThreadSource), interceptCallback,
+ [this] { resetIdleTimer(); }, threadName.c_str());
}
sp<IDisplayEventConnection> Scheduler::createDisplayEventConnection(
- const sp<Scheduler::ConnectionHandle>& handle) {
+ const sp<Scheduler::ConnectionHandle>& handle, ResyncCallback resyncCallback) {
RETURN_VALUE_IF_INVALID(nullptr);
- return mConnections[handle->id]->thread->createEventConnection();
+ return mConnections[handle->id]->thread->createEventConnection(std::move(resyncCallback));
}
EventThread* Scheduler::getEventThread(const sp<Scheduler::ConnectionHandle>& handle) {
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 3538f31..ba18d21 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -73,11 +73,11 @@
/** Creates an EventThread connection. */
sp<ConnectionHandle> createConnection(
- const std::string& connectionName, int64_t phaseOffsetNs,
- impl::EventThread::ResyncWithRateLimitCallback resyncCallback,
+ const std::string& connectionName, int64_t phaseOffsetNs, ResyncCallback resyncCallback,
impl::EventThread::InterceptVSyncsCallback interceptCallback);
- sp<IDisplayEventConnection> createDisplayEventConnection(const sp<ConnectionHandle>& handle);
+ sp<IDisplayEventConnection> createDisplayEventConnection(const sp<ConnectionHandle>& handle,
+ ResyncCallback resyncCallback);
// Getter methods.
EventThread* getEventThread(const sp<ConnectionHandle>& handle);
@@ -122,7 +122,6 @@
protected:
virtual std::unique_ptr<EventThread> makeEventThread(
const std::string& connectionName, DispSync* dispSync, int64_t phaseOffsetNs,
- impl::EventThread::ResyncWithRateLimitCallback resyncCallback,
impl::EventThread::InterceptVSyncsCallback interceptCallback);
private:
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index bd16d64..2a90d08 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -617,6 +617,8 @@
Mutex::Autolock _l(mStateLock);
+ auto resyncCallback = makeResyncCallback();
+
// start the EventThread
if (mUseScheduler) {
mScheduler = getFactory().createScheduler([this](bool enabled) {
@@ -625,12 +627,11 @@
mAppConnectionHandle =
mScheduler->createConnection("appConnection", SurfaceFlinger::vsyncPhaseOffsetNs,
- [this] { resyncWithRateLimit(); },
+ resyncCallback,
impl::EventThread::InterceptVSyncsCallback());
mSfConnectionHandle =
mScheduler->createConnection("sfConnection", SurfaceFlinger::sfVsyncPhaseOffsetNs,
- [this] { resyncWithRateLimit(); },
- [this](nsecs_t timestamp) {
+ resyncCallback, [this](nsecs_t timestamp) {
mInterceptor->saveVSyncEvent(timestamp);
});
@@ -643,7 +644,6 @@
SurfaceFlinger::vsyncPhaseOffsetNs, true, "app");
mEventThread =
std::make_unique<impl::EventThread>(mEventThreadSource.get(),
- [this] { resyncWithRateLimit(); },
impl::EventThread::InterceptVSyncsCallback(),
"appEventThread");
mSfEventThreadSource =
@@ -652,12 +652,11 @@
mSFEventThread =
std::make_unique<impl::EventThread>(mSfEventThreadSource.get(),
- [this] { resyncWithRateLimit(); },
[this](nsecs_t timestamp) {
mInterceptor->saveVSyncEvent(timestamp);
},
"sfEventThread");
- mEventQueue->setEventThread(mSFEventThread.get());
+ mEventQueue->setEventThread(mSFEventThread.get(), std::move(resyncCallback));
mVsyncModulator.setEventThreads(mSFEventThread.get(), mEventThread.get());
}
@@ -1160,6 +1159,8 @@
return;
}
+ auto resyncCallback = makeResyncCallback();
+
// TODO(akrulec): Part of the Injector should be refactored, so that it
// can be passed to Scheduler.
if (enable) {
@@ -1167,14 +1168,14 @@
if (mVSyncInjector.get() == nullptr) {
mVSyncInjector = std::make_unique<InjectVSyncSource>();
mInjectorEventThread = std::make_unique<
- impl::EventThread>(mVSyncInjector.get(), [this] { resyncWithRateLimit(); },
+ impl::EventThread>(mVSyncInjector.get(),
impl::EventThread::InterceptVSyncsCallback(),
"injEventThread");
}
- mEventQueue->setEventThread(mInjectorEventThread.get());
+ mEventQueue->setEventThread(mInjectorEventThread.get(), std::move(resyncCallback));
} else {
ALOGV("VSync Injections disabled");
- mEventQueue->setEventThread(mSFEventThread.get());
+ mEventQueue->setEventThread(mSFEventThread.get(), std::move(resyncCallback));
}
mInjectVSyncs = enable;
@@ -1231,17 +1232,19 @@
sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection(
ISurfaceComposer::VsyncSource vsyncSource) {
+ auto resyncCallback = makeResyncCallback();
+
if (mUseScheduler) {
if (vsyncSource == eVsyncSourceSurfaceFlinger) {
- return mScheduler->createDisplayEventConnection(mSfConnectionHandle);
+ return mScheduler->createDisplayEventConnection(mSfConnectionHandle, resyncCallback);
} else {
- return mScheduler->createDisplayEventConnection(mAppConnectionHandle);
+ return mScheduler->createDisplayEventConnection(mAppConnectionHandle, resyncCallback);
}
} else {
if (vsyncSource == eVsyncSourceSurfaceFlinger) {
- return mSFEventThread->createEventConnection();
+ return mSFEventThread->createEventConnection(resyncCallback);
} else {
- return mEventThread->createEventConnection();
+ return mEventThread->createEventConnection(resyncCallback);
}
}
}
@@ -1343,16 +1346,15 @@
}
}
-void SurfaceFlinger::resyncWithRateLimit() {
+void SurfaceFlinger::VsyncState::resync() {
static constexpr nsecs_t kIgnoreDelay = ms2ns(500);
// No explicit locking is needed here since EventThread holds a lock while calling this method
- static nsecs_t sLastResyncAttempted = 0;
const nsecs_t now = systemTime();
- if (now - sLastResyncAttempted > kIgnoreDelay) {
- resyncToHardwareVsync(false);
+ if (now - lastResyncTime > kIgnoreDelay) {
+ flinger.resyncToHardwareVsync(false);
}
- sLastResyncAttempted = now;
+ lastResyncTime = now;
}
void SurfaceFlinger::onVsyncReceived(int32_t sequenceId, hwc2_display_t hwcDisplayId,
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index eb7127e..9f81476 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -706,6 +706,7 @@
void preComposition();
void postComposition();
+ void getCompositorTiming(CompositorTiming* compositorTiming);
void updateCompositorTiming(const DisplayStatInfo& stats, nsecs_t compositeTime,
std::shared_ptr<FenceTime>& presentFenceTime);
void setCompositorTimingSnapped(const DisplayStatInfo& stats,
@@ -764,14 +765,31 @@
void resyncToHardwareVsync(bool makeAvailable);
void disableHardwareVsync(bool makeUnavailable);
-public:
- void resyncWithRateLimit();
- void getCompositorTiming(CompositorTiming* compositorTiming);
-private:
// Sets the refresh rate to newFps by switching active configs, if they are available for
// the desired refresh rate.
void setRefreshRateTo(float newFps);
+ // Stores per-display state about VSYNC.
+ struct VsyncState {
+ explicit VsyncState(SurfaceFlinger& flinger) : flinger(flinger) {}
+
+ void resync();
+
+ SurfaceFlinger& flinger;
+ nsecs_t lastResyncTime = 0;
+ };
+
+ const std::shared_ptr<VsyncState> mPrimaryVsyncState{std::make_shared<VsyncState>(*this)};
+
+ auto makeResyncCallback() {
+ std::weak_ptr<VsyncState> ptr = mPrimaryVsyncState;
+ return [ptr]() {
+ if (const auto vsync = ptr.lock()) {
+ vsync->resync();
+ }
+ };
+ }
+
/* ------------------------------------------------------------------------
* Debugging & dumpsys
*/
diff --git a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
index 2d26bb3..c18068f 100644
--- a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
+++ b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
@@ -47,10 +47,11 @@
class EventThreadTest : public testing::Test {
protected:
- class MockEventThreadConnection : public android::EventThreadConnection {
+ class MockEventThreadConnection : public EventThreadConnection {
public:
- explicit MockEventThreadConnection(android::impl::EventThread* eventThread)
- : android::EventThreadConnection(eventThread) {}
+ MockEventThreadConnection(android::impl::EventThread* eventThread,
+ ResyncCallback&& resyncCallback)
+ : EventThreadConnection(eventThread, std::move(resyncCallback)) {}
MOCK_METHOD1(postEvent, status_t(const DisplayEventReceiver::Event& event));
};
@@ -113,14 +114,14 @@
void EventThreadTest::createThread() {
mThread =
std::make_unique<android::impl::EventThread>(&mVSyncSource,
- mResyncCallRecorder.getInvocable(),
mInterceptVSyncCallRecorder.getInvocable(),
"unit-test-event-thread");
}
sp<EventThreadTest::MockEventThreadConnection> EventThreadTest::createConnection(
ConnectionEventRecorder& recorder) {
- sp<MockEventThreadConnection> connection = new MockEventThreadConnection(mThread.get());
+ sp<MockEventThreadConnection> connection =
+ new MockEventThreadConnection(mThread.get(), mResyncCallRecorder.getInvocable());
EXPECT_CALL(*connection, postEvent(_)).WillRepeatedly(Invoke(recorder.getInvocable()));
return connection;
}
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index 4253ad8..3dd5143 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -8,12 +8,9 @@
#include <mutex>
-#include "AsyncCallRecorder.h"
-#include "Scheduler/DispSync.h"
#include "Scheduler/EventControlThread.h"
#include "Scheduler/EventThread.h"
#include "Scheduler/Scheduler.h"
-#include "mock/MockDispSync.h"
#include "mock/MockEventThread.h"
using testing::_;
@@ -26,7 +23,7 @@
class MockEventThreadConnection : public android::EventThreadConnection {
public:
explicit MockEventThreadConnection(EventThread* eventThread)
- : EventThreadConnection(eventThread) {}
+ : EventThreadConnection(eventThread, ResyncCallback()) {}
~MockEventThreadConnection() = default;
MOCK_METHOD1(stealReceiveChannel, status_t(gui::BitTube* outChannel));
@@ -46,7 +43,6 @@
std::unique_ptr<EventThread> makeEventThread(
const std::string& /* connectionName */, DispSync* /* dispSync */,
nsecs_t /* phaseOffsetNs */,
- impl::EventThread::ResyncWithRateLimitCallback /* resyncCallback */,
impl::EventThread::InterceptVSyncsCallback /* interceptCallback */) override {
return std::move(mEventThread);
}
@@ -61,13 +57,9 @@
~SchedulerTest() override;
sp<Scheduler::ConnectionHandle> mConnectionHandle;
- mock::DispSync* mPrimaryDispSync = new mock::DispSync();
mock::EventThread* mEventThread;
std::unique_ptr<MockScheduler> mScheduler;
sp<MockEventThreadConnection> mEventThreadConnection;
-
- AsyncCallRecorder<void (*)()> mResyncCallRecorder;
- AsyncCallRecorder<void (*)(nsecs_t)> mInterceptVSyncCallRecorder;
};
SchedulerTest::SchedulerTest() {
@@ -84,12 +76,12 @@
// createConnection call to scheduler makes a createEventConnection call to EventThread. Make
// sure that call gets executed and returns an EventThread::Connection object.
- EXPECT_CALL(*mEventThread, createEventConnection())
+ EXPECT_CALL(*mEventThread, createEventConnection(_))
.WillRepeatedly(Return(mEventThreadConnection));
- mConnectionHandle =
- mScheduler->createConnection("appConnection", 16, mResyncCallRecorder.getInvocable(),
- mInterceptVSyncCallRecorder.getInvocable());
+ mConnectionHandle = mScheduler->createConnection("appConnection", 16, ResyncCallback(),
+ impl::EventThread::InterceptVSyncsCallback());
+ EXPECT_TRUE(mConnectionHandle != nullptr);
}
SchedulerTest::~SchedulerTest() {
@@ -102,17 +94,13 @@
/* ------------------------------------------------------------------------
* Test cases
*/
-TEST_F(SchedulerTest, canCreateAndDestroyTest) {
- EXPECT_FALSE(mResyncCallRecorder.waitForCall().has_value());
- EXPECT_FALSE(mInterceptVSyncCallRecorder.waitForCall().has_value());
- EXPECT_EQ(0, mConnectionHandle->id);
-}
TEST_F(SchedulerTest, testNullPtr) {
// Passing a null pointer for ConnectionHandle is a valid argument. The code doesn't throw any
// exceptions, just gracefully continues.
sp<IDisplayEventConnection> returnedValue;
- ASSERT_NO_FATAL_FAILURE(returnedValue = mScheduler->createDisplayEventConnection(nullptr));
+ ASSERT_NO_FATAL_FAILURE(
+ returnedValue = mScheduler->createDisplayEventConnection(nullptr, ResyncCallback()));
EXPECT_TRUE(returnedValue == nullptr);
EXPECT_TRUE(mScheduler->getEventThread(nullptr) == nullptr);
EXPECT_TRUE(mScheduler->getEventConnection(nullptr) == nullptr);
@@ -132,8 +120,9 @@
sp<Scheduler::ConnectionHandle> connectionHandle = new Scheduler::ConnectionHandle(20);
sp<IDisplayEventConnection> returnedValue;
- ASSERT_NO_FATAL_FAILURE(returnedValue =
- mScheduler->createDisplayEventConnection(connectionHandle));
+ ASSERT_NO_FATAL_FAILURE(
+ returnedValue =
+ mScheduler->createDisplayEventConnection(connectionHandle, ResyncCallback()));
EXPECT_TRUE(returnedValue == nullptr);
EXPECT_TRUE(mScheduler->getEventThread(connectionHandle) == nullptr);
EXPECT_TRUE(mScheduler->getEventConnection(connectionHandle) == nullptr);
@@ -160,8 +149,9 @@
TEST_F(SchedulerTest, validConnectionHandle) {
sp<IDisplayEventConnection> returnedValue;
- ASSERT_NO_FATAL_FAILURE(returnedValue =
- mScheduler->createDisplayEventConnection(mConnectionHandle));
+ ASSERT_NO_FATAL_FAILURE(
+ returnedValue =
+ mScheduler->createDisplayEventConnection(mConnectionHandle, ResyncCallback()));
EXPECT_TRUE(returnedValue != nullptr);
ASSERT_EQ(returnedValue, mEventThreadConnection);
diff --git a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
index 48d45fa..3242ef1 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
@@ -28,7 +28,7 @@
EventThread();
~EventThread() override;
- MOCK_CONST_METHOD0(createEventConnection, sp<EventThreadConnection>());
+ MOCK_CONST_METHOD1(createEventConnection, sp<EventThreadConnection>(ResyncCallback));
MOCK_METHOD0(onScreenReleased, void());
MOCK_METHOD0(onScreenAcquired, void());
MOCK_METHOD2(onHotplugReceived, void(DisplayType, bool));
diff --git a/services/surfaceflinger/tests/unittests/mock/MockMessageQueue.h b/services/surfaceflinger/tests/unittests/mock/MockMessageQueue.h
index 8c113e2..e22d3e8 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockMessageQueue.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockMessageQueue.h
@@ -30,8 +30,8 @@
~MessageQueue() override;
MOCK_METHOD1(init, void(const sp<SurfaceFlinger>&));
- MOCK_METHOD1(setEventThread, void(android::EventThread*));
- MOCK_METHOD1(setEventConnection, void(const sp<android::EventThreadConnection>& connection));
+ MOCK_METHOD2(setEventThread, void(android::EventThread*, ResyncCallback));
+ MOCK_METHOD1(setEventConnection, void(const sp<EventThreadConnection>& connection));
MOCK_METHOD0(waitMessage, void());
MOCK_METHOD2(postMessage, status_t(const sp<MessageBase>&, nsecs_t));
MOCK_METHOD0(invalidate, void());