SF: Moving EventThread::Connection out of impl class
This is part of Scheduler refactoring. EventThread::Connection should be
a wrapper that translates IDisplayEventConnection into EventThread calls.
Test: SF tests pass.
Bug: 113612090
Change-Id: I2bcf0c45a33638c59f7828085c563dbc52b2d66e
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index 1f08f4e..1683982 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -43,6 +43,40 @@
// ---------------------------------------------------------------------------
+EventThreadConnection::EventThreadConnection(EventThread* eventThread)
+ : count(-1), mEventThread(eventThread), mChannel(gui::BitTube::DefaultSize) {}
+
+EventThreadConnection::~EventThreadConnection() {
+ // do nothing here -- clean-up will happen automatically
+ // when the main thread wakes up
+}
+
+void EventThreadConnection::onFirstRef() {
+ // NOTE: mEventThread doesn't hold a strong reference on us
+ mEventThread->registerDisplayEventConnection(this);
+}
+
+status_t EventThreadConnection::stealReceiveChannel(gui::BitTube* outChannel) {
+ outChannel->setReceiveFd(mChannel.moveReceiveFd());
+ return NO_ERROR;
+}
+
+status_t EventThreadConnection::setVsyncRate(uint32_t count) {
+ mEventThread->setVsyncRate(count, this);
+ return NO_ERROR;
+}
+
+void EventThreadConnection::requestNextVsync() {
+ mEventThread->requestNextVsync(this);
+}
+
+status_t EventThreadConnection::postEvent(const DisplayEventReceiver::Event& event) {
+ ssize_t size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);
+ return size < 0 ? status_t(size) : status_t(NO_ERROR);
+}
+
+// ---------------------------------------------------------------------------
+
EventThread::~EventThread() = default;
namespace impl {
@@ -110,12 +144,11 @@
mVSyncSource->setPhaseOffset(phaseOffset);
}
-sp<BnDisplayEventConnection> EventThread::createEventConnection() const {
- return new Connection(const_cast<EventThread*>(this));
+sp<EventThreadConnection> EventThread::createEventConnection() const {
+ return new EventThreadConnection(const_cast<EventThread*>(this));
}
-status_t EventThread::registerDisplayEventConnection(
- const sp<EventThread::Connection>& connection) {
+status_t EventThread::registerDisplayEventConnection(const sp<EventThreadConnection>& connection) {
std::lock_guard<std::mutex> lock(mMutex);
// this should never happen
@@ -132,8 +165,7 @@
return NO_ERROR;
}
-void EventThread::removeDisplayEventConnectionLocked(
- const wp<EventThread::Connection>& connection) {
+void EventThread::removeDisplayEventConnectionLocked(const wp<EventThreadConnection>& connection) {
auto it = std::find(mDisplayEventConnections.cbegin(),
mDisplayEventConnections.cend(), connection);
if (it != mDisplayEventConnections.cend()) {
@@ -141,7 +173,7 @@
}
}
-void EventThread::setVsyncRate(uint32_t count, const sp<EventThread::Connection>& connection) {
+void EventThread::setVsyncRate(uint32_t count, const sp<EventThreadConnection>& connection) {
if (int32_t(count) >= 0) { // server must protect against bad params
std::lock_guard<std::mutex> lock(mMutex);
const int32_t new_count = (count == 0) ? -1 : count;
@@ -152,7 +184,7 @@
}
}
-void EventThread::requestNextVsync(const sp<EventThread::Connection>& connection) {
+void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection) {
std::lock_guard<std::mutex> lock(mMutex);
if (mResetIdleTimer) {
mResetIdleTimer();
@@ -212,11 +244,11 @@
std::unique_lock<std::mutex> lock(mMutex);
while (mKeepRunning) {
DisplayEventReceiver::Event event;
- std::vector<sp<EventThread::Connection>> signalConnections;
+ std::vector<sp<EventThreadConnection>> signalConnections;
signalConnections = waitForEventLocked(&lock, &event);
// dispatch events to listeners...
- for (const sp<Connection>& conn : signalConnections) {
+ for (const sp<EventThreadConnection>& conn : signalConnections) {
// now see if we still need to report this event
status_t err = conn->postEvent(event);
if (err == -EAGAIN || err == -EWOULDBLOCK) {
@@ -239,9 +271,9 @@
// This will return when (1) a vsync event has been received, and (2) there was
// at least one connection interested in receiving it when we started waiting.
-std::vector<sp<EventThread::Connection>> EventThread::waitForEventLocked(
+std::vector<sp<EventThreadConnection>> EventThread::waitForEventLocked(
std::unique_lock<std::mutex>* lock, DisplayEventReceiver::Event* outEvent) {
- std::vector<sp<EventThread::Connection>> signalConnections;
+ std::vector<sp<EventThreadConnection>> signalConnections;
while (signalConnections.empty() && mKeepRunning) {
bool eventPending = false;
@@ -276,7 +308,7 @@
// find out connections waiting for events
auto it = mDisplayEventConnections.begin();
while (it != mDisplayEventConnections.end()) {
- sp<Connection> connection(it->promote());
+ sp<EventThreadConnection> connection(it->promote());
if (connection != nullptr) {
bool added = false;
if (connection->count >= 0) {
@@ -399,49 +431,13 @@
StringAppendF(&result, " soft-vsync: %s\n", mUseSoftwareVSync ? "enabled" : "disabled");
StringAppendF(&result, " numListeners=%zu,\n events-delivered: %u\n",
mDisplayEventConnections.size(), mVSyncEvent[0].vsync.count);
- for (const wp<Connection>& weak : mDisplayEventConnections) {
- sp<Connection> connection = weak.promote();
+ for (const wp<EventThreadConnection>& weak : mDisplayEventConnections) {
+ sp<EventThreadConnection> connection = weak.promote();
StringAppendF(&result, " %p: count=%d\n", connection.get(),
connection != nullptr ? connection->count : 0);
}
StringAppendF(&result, " other-events-pending: %zu\n", mPendingEvents.size());
}
-// ---------------------------------------------------------------------------
-
-EventThread::Connection::Connection(EventThread* eventThread)
- : count(-1), mEventThread(eventThread), mChannel(gui::BitTube::DefaultSize) {}
-
-EventThread::Connection::~Connection() {
- // do nothing here -- clean-up will happen automatically
- // when the main thread wakes up
-}
-
-void EventThread::Connection::onFirstRef() {
- // NOTE: mEventThread doesn't hold a strong reference on us
- mEventThread->registerDisplayEventConnection(this);
-}
-
-status_t EventThread::Connection::stealReceiveChannel(gui::BitTube* outChannel) {
- outChannel->setReceiveFd(mChannel.moveReceiveFd());
- return NO_ERROR;
-}
-
-status_t EventThread::Connection::setVsyncRate(uint32_t count) {
- mEventThread->setVsyncRate(count, this);
- return NO_ERROR;
-}
-
-void EventThread::Connection::requestNextVsync() {
- mEventThread->requestNextVsync(this);
-}
-
-status_t EventThread::Connection::postEvent(const DisplayEventReceiver::Event& event) {
- ssize_t size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);
- return size < 0 ? status_t(size) : status_t(NO_ERROR);
-}
-
-// ---------------------------------------------------------------------------
-
} // namespace impl
} // namespace android
diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h
index 0773c05..66f54bd 100644
--- a/services/surfaceflinger/Scheduler/EventThread.h
+++ b/services/surfaceflinger/Scheduler/EventThread.h
@@ -38,6 +38,7 @@
namespace android {
// ---------------------------------------------------------------------------
+class EventThread;
class EventThreadTest;
class SurfaceFlinger;
@@ -57,6 +58,28 @@
virtual void setPhaseOffset(nsecs_t phaseOffset) = 0;
};
+class EventThreadConnection : public BnDisplayEventConnection {
+public:
+ explicit EventThreadConnection(EventThread* eventThread);
+ virtual ~EventThreadConnection();
+
+ virtual status_t postEvent(const DisplayEventReceiver::Event& event);
+
+ status_t stealReceiveChannel(gui::BitTube* outChannel) override;
+ status_t setVsyncRate(uint32_t count) override;
+ void requestNextVsync() override; // asynchronous
+
+ // 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
+ int32_t count;
+
+private:
+ virtual void onFirstRef();
+ EventThread* const mEventThread;
+ gui::BitTube mChannel;
+};
+
class EventThread {
public:
// TODO: Remove once stable display IDs are plumbed through SF/WM interface.
@@ -64,7 +87,7 @@
virtual ~EventThread();
- virtual sp<BnDisplayEventConnection> createEventConnection() const = 0;
+ virtual sp<EventThreadConnection> createEventConnection() const = 0;
// called before the screen is turned off from main thread
virtual void onScreenReleased() = 0;
@@ -78,32 +101,16 @@
virtual void dump(std::string& result) const = 0;
virtual void setPhaseOffset(nsecs_t phaseOffset) = 0;
+
+ virtual status_t registerDisplayEventConnection(
+ const sp<EventThreadConnection>& connection) = 0;
+ virtual void setVsyncRate(uint32_t count, const sp<EventThreadConnection>& connection) = 0;
+ virtual void requestNextVsync(const sp<EventThreadConnection>& connection) = 0;
};
namespace impl {
class EventThread : public android::EventThread, private VSyncSource::Callback {
- class Connection : public BnDisplayEventConnection {
- public:
- explicit Connection(EventThread* eventThread);
- virtual ~Connection();
-
- virtual status_t postEvent(const DisplayEventReceiver::Event& event);
-
- // 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
- int32_t count;
-
- private:
- virtual void onFirstRef();
- status_t stealReceiveChannel(gui::BitTube* outChannel) override;
- status_t setVsyncRate(uint32_t count) override;
- void requestNextVsync() override; // asynchronous
- EventThread* const mEventThread;
- gui::BitTube mChannel;
- };
-
public:
using ResyncWithRateLimitCallback = std::function<void()>;
using InterceptVSyncsCallback = std::function<void(nsecs_t)>;
@@ -118,10 +125,11 @@
const ResetIdleTimerCallback& resetIdleTimerCallback, const char* threadName);
~EventThread();
- sp<BnDisplayEventConnection> createEventConnection() const override;
+ sp<EventThreadConnection> createEventConnection() const override;
- void setVsyncRate(uint32_t count, const sp<Connection>& connection);
- void requestNextVsync(const sp<Connection>& connection);
+ status_t registerDisplayEventConnection(const sp<EventThreadConnection>& connection) override;
+ void setVsyncRate(uint32_t count, const sp<EventThreadConnection>& connection) override;
+ void requestNextVsync(const sp<EventThreadConnection>& connection) override;
// called before the screen is turned off from main thread
void onScreenReleased() override;
@@ -144,14 +152,14 @@
ResyncWithRateLimitCallback resyncWithRateLimitCallback,
InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName);
- status_t registerDisplayEventConnection(const sp<Connection>& connection);
void threadMain();
- std::vector<sp<EventThread::Connection>> waitForEventLocked(std::unique_lock<std::mutex>* lock,
- DisplayEventReceiver::Event* event)
+ std::vector<sp<EventThreadConnection>> waitForEventLocked(std::unique_lock<std::mutex>* lock,
+ DisplayEventReceiver::Event* event)
REQUIRES(mMutex);
- void removeDisplayEventConnectionLocked(const wp<Connection>& connection) REQUIRES(mMutex);
+ void removeDisplayEventConnectionLocked(const wp<EventThreadConnection>& connection)
+ REQUIRES(mMutex);
void enableVSyncLocked() REQUIRES(mMutex);
void disableVSyncLocked() REQUIRES(mMutex);
@@ -170,7 +178,7 @@
mutable std::condition_variable mCondition;
// protected by mLock
- std::vector<wp<Connection>> mDisplayEventConnections GUARDED_BY(mMutex);
+ std::vector<wp<EventThreadConnection>> mDisplayEventConnections GUARDED_BY(mMutex);
std::queue<DisplayEventReceiver::Event> mPendingEvents GUARDED_BY(mMutex);
std::array<DisplayEventReceiver::Event, 2> mVSyncEvent GUARDED_BY(mMutex);
bool mUseSoftwareVSync GUARDED_BY(mMutex) = false;
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.cpp b/services/surfaceflinger/Scheduler/MessageQueue.cpp
index 58355ae..36403cc 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.cpp
+++ b/services/surfaceflinger/Scheduler/MessageQueue.cpp
@@ -101,7 +101,7 @@
this);
}
-void MessageQueue::setEventConnection(const sp<BnDisplayEventConnection>& connection) {
+void MessageQueue::setEventConnection(const sp<EventThreadConnection>& connection) {
if (mEventTube.getFd() >= 0) {
mLooper->removeFd(mEventTube.getFd());
}
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.h b/services/surfaceflinger/Scheduler/MessageQueue.h
index 2ec697e..24a3834 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.h
+++ b/services/surfaceflinger/Scheduler/MessageQueue.h
@@ -87,7 +87,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 setEventConnection(const sp<BnDisplayEventConnection>& connection) = 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;
virtual void invalidate() = 0;
@@ -116,7 +116,7 @@
sp<SurfaceFlinger> mFlinger;
sp<Looper> mLooper;
android::EventThread* mEventThread;
- sp<IDisplayEventConnection> mEvents;
+ sp<EventThreadConnection> mEvents;
gui::BitTube mEventTube;
sp<Handler> mHandler;
@@ -127,7 +127,7 @@
~MessageQueue() override = default;
void init(const sp<SurfaceFlinger>& flinger) override;
void setEventThread(android::EventThread* events) override;
- void setEventConnection(const sp<BnDisplayEventConnection>& connection) override;
+ void setEventConnection(const sp<EventThreadConnection>& connection) override;
void waitMessage() override;
status_t postMessage(const sp<MessageBase>& message, nsecs_t reltime = 0) override;
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index fad56e6..c363ba5 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -126,7 +126,7 @@
return mConnections[handle->id]->thread.get();
}
-sp<BnDisplayEventConnection> Scheduler::getEventConnection(const sp<ConnectionHandle>& handle) {
+sp<EventThreadConnection> Scheduler::getEventConnection(const sp<ConnectionHandle>& handle) {
RETURN_VALUE_IF_INVALID(nullptr);
return mConnections[handle->id]->eventConnection;
}
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 8d4514b..9d7dd4d 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -53,14 +53,14 @@
class Connection {
public:
- Connection(sp<ConnectionHandle> handle, sp<BnDisplayEventConnection> eventConnection,
+ Connection(sp<ConnectionHandle> handle, sp<EventThreadConnection> eventConnection,
std::unique_ptr<EventThread> eventThread)
: handle(handle), eventConnection(eventConnection), thread(std::move(eventThread)) {}
~Connection() = default;
sp<ConnectionHandle> handle;
- sp<BnDisplayEventConnection> eventConnection;
+ sp<EventThreadConnection> eventConnection;
const std::unique_ptr<EventThread> thread;
};
@@ -79,7 +79,7 @@
// Getter methods.
EventThread* getEventThread(const sp<ConnectionHandle>& handle);
- sp<BnDisplayEventConnection> getEventConnection(const sp<ConnectionHandle>& handle);
+ sp<EventThreadConnection> getEventConnection(const sp<ConnectionHandle>& handle);
// Should be called when receiving a hotplug event.
void hotplugReceived(const sp<ConnectionHandle>& handle, EventThread::DisplayType displayType,
diff --git a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
index fb3b7a2..acbed51 100644
--- a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
+++ b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
@@ -47,10 +47,10 @@
class EventThreadTest : public testing::Test {
protected:
- class MockEventThreadConnection : public android::impl::EventThread::Connection {
+ class MockEventThreadConnection : public android::EventThreadConnection {
public:
explicit MockEventThreadConnection(android::impl::EventThread* eventThread)
- : android::impl::EventThread::Connection(eventThread) {}
+ : android::EventThreadConnection(eventThread) {}
MOCK_METHOD1(postEvent, status_t(const DisplayEventReceiver::Event& event));
};
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index 35f30d7..4253ad8 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -23,9 +23,10 @@
class SchedulerTest : public testing::Test {
protected:
- class MockEventThreadConnection : public BnDisplayEventConnection {
+ class MockEventThreadConnection : public android::EventThreadConnection {
public:
- MockEventThreadConnection() = default;
+ explicit MockEventThreadConnection(EventThread* eventThread)
+ : EventThreadConnection(eventThread) {}
~MockEventThreadConnection() = default;
MOCK_METHOD1(stealReceiveChannel, status_t(gui::BitTube* outChannel));
@@ -77,7 +78,9 @@
std::unique_ptr<mock::EventThread> eventThread = std::make_unique<mock::EventThread>();
mEventThread = eventThread.get();
mScheduler = std::make_unique<MockScheduler>(std::move(eventThread));
- mEventThreadConnection = new MockEventThreadConnection();
+ EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_)).WillOnce(Return(0));
+
+ mEventThreadConnection = new MockEventThreadConnection(mEventThread);
// createConnection call to scheduler makes a createEventConnection call to EventThread. Make
// sure that call gets executed and returns an EventThread::Connection object.
diff --git a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
index 0a1c827..bb6e183 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
@@ -28,12 +28,16 @@
EventThread();
~EventThread() override;
- MOCK_CONST_METHOD0(createEventConnection, sp<BnDisplayEventConnection>());
+ MOCK_CONST_METHOD0(createEventConnection, sp<EventThreadConnection>());
MOCK_METHOD0(onScreenReleased, void());
MOCK_METHOD0(onScreenAcquired, void());
MOCK_METHOD2(onHotplugReceived, void(DisplayType, bool));
MOCK_CONST_METHOD1(dump, void(std::string&));
MOCK_METHOD1(setPhaseOffset, void(nsecs_t phaseOffset));
+ MOCK_METHOD1(registerDisplayEventConnection,
+ status_t(const sp<android::EventThreadConnection> &));
+ MOCK_METHOD2(setVsyncRate, void(uint32_t, const sp<android::EventThreadConnection> &));
+ MOCK_METHOD1(requestNextVsync, void(const sp<android::EventThreadConnection> &));
};
} // namespace mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockMessageQueue.h b/services/surfaceflinger/tests/unittests/mock/MockMessageQueue.h
index f2f3675..dc8d606 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockMessageQueue.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockMessageQueue.h
@@ -18,6 +18,7 @@
#include <gmock/gmock.h>
+#include "Scheduler/EventThread.h"
#include "Scheduler/MessageQueue.h"
namespace android {
@@ -30,7 +31,7 @@
MOCK_METHOD1(init, void(const sp<SurfaceFlinger>&));
MOCK_METHOD1(setEventThread, void(android::EventThread*));
- MOCK_METHOD1(setEventConnection, void(const sp<BnDisplayEventConnection>& connection));
+ MOCK_METHOD1(setEventConnection, void(const sp<android::EventThreadConnection>& connection));
MOCK_METHOD0(waitMessage, void());
MOCK_METHOD2(postMessage, status_t(const sp<MessageBase>&, nsecs_t));
MOCK_METHOD0(invalidate, void());