SF: Fix VSYNC injection
Disabling VSYNC injection causes the main thread to destroy the injected
EventThreadConnection, while it might be accessed by a Binder thread via
MessageQueue::invalidate.
Also, fix injection itself:
- The EventThread did not dispatch injected events, falling back to
fake VSYNC after timeout.
- The MessageQueue would try listening to invalid FDs when enabling
injection more than once.
- Injection was not disabled after each test.
Finally, rename MessageQueue members only used for injection since S.
Bug: 150226265
Test: Toggle VSYNC injection in a tight loop while using phone.
Test: sffakehwc_test --gtest_repeat=-1 --gtest_break_on_failure
--gtest_filter='*VsyncInjection'
Change-Id: Ia58859cd8a36749bf56bb94fa724efe7c1b27b46
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.h b/services/surfaceflinger/Scheduler/MessageQueue.h
index 99ce3a6..2934af0 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.h
+++ b/services/surfaceflinger/Scheduler/MessageQueue.h
@@ -21,12 +21,11 @@
#include <type_traits>
#include <utility>
-#include <utils/Looper.h>
-#include <utils/Timers.h>
-#include <utils/threads.h>
-
+#include <android-base/thread_annotations.h>
#include <gui/IDisplayEventConnection.h>
#include <private/gui/BitTube.h>
+#include <utils/Looper.h>
+#include <utils/Timers.h>
#include "EventThread.h"
#include "TracedOrdinal.h"
@@ -68,7 +67,7 @@
virtual void initVsync(scheduler::VSyncDispatch&, frametimeline::TokenManager&,
std::chrono::nanoseconds workDuration) = 0;
virtual void setDuration(std::chrono::nanoseconds workDuration) = 0;
- virtual void setEventConnection(const sp<EventThreadConnection>& connection) = 0;
+ virtual void setInjector(sp<EventThreadConnection>) = 0;
virtual void waitMessage() = 0;
virtual void postMessage(sp<MessageHandler>&&) = 0;
virtual void invalidate() = 0;
@@ -99,7 +98,6 @@
sp<SurfaceFlinger> mFlinger;
sp<Looper> mLooper;
- sp<EventThreadConnection> mEvents;
struct Vsync {
frametimeline::TokenManager* tokenManager = nullptr;
@@ -113,14 +111,19 @@
TracedOrdinal<int> value = {"VSYNC-sf", 0};
};
- Vsync mVsync;
+ struct Injector {
+ gui::BitTube tube;
+ std::mutex mutex;
+ sp<EventThreadConnection> connection GUARDED_BY(mutex);
+ };
- gui::BitTube mEventTube;
+ Vsync mVsync;
+ Injector mInjector;
+
sp<Handler> mHandler;
- static int cb_eventReceiver(int fd, int events, void* data);
- int eventReceiver(int fd, int events);
void vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime);
+ void injectorCallback();
public:
~MessageQueue() override = default;
@@ -128,7 +131,7 @@
void initVsync(scheduler::VSyncDispatch&, frametimeline::TokenManager&,
std::chrono::nanoseconds workDuration) override;
void setDuration(std::chrono::nanoseconds workDuration) override;
- void setEventConnection(const sp<EventThreadConnection>& connection) override;
+ void setInjector(sp<EventThreadConnection>) override;
void waitMessage() override;
void postMessage(sp<MessageHandler>&&) override;