Add Window Infos state to dumpsys
Update SurfaceFlinger and InputDispatcher dumpsys output to include
the vsync id and timestamp of Window Infos changes.
Bug: 279792237
Test: presubmits
Change-Id: I17fba2d09972467cfdd452e5041666ffbeabddc9
diff --git a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
index f852001..becf70a 100644
--- a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
+++ b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
@@ -343,8 +343,10 @@
std::vector<gui::DisplayInfo> displayInfos{info};
for (auto _ : state) {
- dispatcher.onWindowInfosChanged(windowInfos, displayInfos);
- dispatcher.onWindowInfosChanged(/*windowInfos=*/{}, /*displayInfos=*/{});
+ dispatcher.onWindowInfosChanged(
+ {windowInfos, displayInfos, /*vsyncId=*/0, /*timestamp=*/0});
+ dispatcher.onWindowInfosChanged(
+ {/*windowInfos=*/{}, /*displayInfos=*/{}, /*vsyncId=*/{}, /*timestamp=*/0});
}
dispatcher.stop();
}
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 8c08ef2..bf52502 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -5572,6 +5572,14 @@
} else {
dump += INDENT "Displays: <none>\n";
}
+ dump += INDENT "Window Infos:\n";
+ dump += StringPrintf(INDENT2 "vsync id: %" PRId64 "\n", mWindowInfosVsyncId);
+ dump += StringPrintf(INDENT2 "timestamp (ns): %" PRId64 "\n", mWindowInfosTimestamp);
+ dump += "\n";
+ dump += StringPrintf(INDENT2 "max update delay (ns): %" PRId64 "\n", mMaxWindowInfosDelay);
+ dump += StringPrintf(INDENT2 "max update delay vsync id: %" PRId64 "\n",
+ mMaxWindowInfosDelayVsyncId);
+ dump += "\n";
if (!mGlobalMonitorsByDisplay.empty()) {
for (const auto& [displayId, monitors] : mGlobalMonitorsByDisplay) {
@@ -6580,12 +6588,11 @@
mLooper->wake();
}
-void InputDispatcher::onWindowInfosChanged(const std::vector<WindowInfo>& windowInfos,
- const std::vector<DisplayInfo>& displayInfos) {
+void InputDispatcher::onWindowInfosChanged(const gui::WindowInfosUpdate& update) {
// The listener sends the windows as a flattened array. Separate the windows by display for
// more convenient parsing.
std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> handlesPerDisplay;
- for (const auto& info : windowInfos) {
+ for (const auto& info : update.windowInfos) {
handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
handlesPerDisplay[info.displayId].push_back(sp<WindowInfoHandle>::make(info));
}
@@ -6600,13 +6607,22 @@
}
mDisplayInfos.clear();
- for (const auto& displayInfo : displayInfos) {
+ for (const auto& displayInfo : update.displayInfos) {
mDisplayInfos.emplace(displayInfo.displayId, displayInfo);
}
for (const auto& [displayId, handles] : handlesPerDisplay) {
setInputWindowsLocked(handles, displayId);
}
+
+ mWindowInfosVsyncId = update.vsyncId;
+ mWindowInfosTimestamp = update.timestamp;
+
+ int64_t delay = systemTime() - update.timestamp;
+ if (delay > mMaxWindowInfosDelay) {
+ mMaxWindowInfosDelay = delay;
+ mMaxWindowInfosDelayVsyncId = update.vsyncId;
+ }
}
// Wake up poll loop since it may need to make new input dispatching choices.
mLooper->wake();
@@ -6629,9 +6645,8 @@
}
void InputDispatcher::DispatcherWindowListener::onWindowInfosChanged(
- const std::vector<gui::WindowInfo>& windowInfos,
- const std::vector<DisplayInfo>& displayInfos) {
- mDispatcher.onWindowInfosChanged(windowInfos, displayInfos);
+ const gui::WindowInfosUpdate& update) {
+ mDispatcher.onWindowInfosChanged(update);
}
void InputDispatcher::cancelCurrentTouch() {
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index dd7f7fe..791dd63 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -36,7 +36,7 @@
#include <attestation/HmacKeyManager.h>
#include <gui/InputApplication.h>
-#include <gui/WindowInfo.h>
+#include <gui/WindowInfosUpdate.h>
#include <input/Input.h>
#include <input/InputTransport.h>
#include <limits.h>
@@ -144,8 +144,7 @@
void displayRemoved(int32_t displayId) override;
// Public because it's also used by tests to simulate the WindowInfosListener callback
- void onWindowInfosChanged(const std::vector<android::gui::WindowInfo>& windowInfos,
- const std::vector<android::gui::DisplayInfo>& displayInfos);
+ void onWindowInfosChanged(const gui::WindowInfosUpdate&);
void cancelCurrentTouch() override;
@@ -205,6 +204,11 @@
const IdGenerator mIdGenerator;
+ int64_t mWindowInfosVsyncId GUARDED_BY(mLock);
+ int64_t mWindowInfosTimestamp GUARDED_BY(mLock);
+ int64_t mMaxWindowInfosDelay GUARDED_BY(mLock) = -1;
+ int64_t mMaxWindowInfosDelayVsyncId GUARDED_BY(mLock) = -1;
+
// With each iteration, InputDispatcher nominally processes one queued event,
// a timeout, or a response from an input consumer.
// This method should only be called on the input dispatcher's own thread.
@@ -356,9 +360,7 @@
class DispatcherWindowListener : public gui::WindowInfosListener {
public:
explicit DispatcherWindowListener(InputDispatcher& dispatcher) : mDispatcher(dispatcher){};
- void onWindowInfosChanged(
- const std::vector<android::gui::WindowInfo>& windowInfos,
- const std::vector<android::gui::DisplayInfo>& displayInfos) override;
+ void onWindowInfosChanged(const gui::WindowInfosUpdate&) override;
private:
InputDispatcher& mDispatcher;
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index b3c5095..c0bc68c 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -3771,7 +3771,7 @@
"Fake Window", ADISPLAY_ID_DEFAULT);
window->setFocusable(true);
- mDispatcher->onWindowInfosChanged({*window->getInfo()}, {});
+ mDispatcher->onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0});
setFocusedWindow(window);
window->consumeFocusEvent(true);
@@ -3785,7 +3785,7 @@
window->consumeKeyUp(ADISPLAY_ID_DEFAULT);
// All windows are removed from the display. Ensure that we can no longer dispatch to it.
- mDispatcher->onWindowInfosChanged({}, {});
+ mDispatcher->onWindowInfosChanged({{}, {}, 0, 0});
window->consumeFocusEvent(false);
@@ -3801,7 +3801,7 @@
// Ensure window is non-split and have some transform.
window->setPreventSplitting(true);
window->setWindowOffset(20, 40);
- mDispatcher->onWindowInfosChanged({*window->getInfo()}, {});
+ mDispatcher->onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0});
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
@@ -3848,12 +3848,12 @@
info.displayId = displayId;
info.transform = transform;
mDisplayInfos.push_back(std::move(info));
- mDispatcher->onWindowInfosChanged(mWindowInfos, mDisplayInfos);
+ mDispatcher->onWindowInfosChanged({mWindowInfos, mDisplayInfos, 0, 0});
}
void addWindow(const sp<WindowInfoHandle>& windowHandle) {
mWindowInfos.push_back(*windowHandle->getInfo());
- mDispatcher->onWindowInfosChanged(mWindowInfos, mDisplayInfos);
+ mDispatcher->onWindowInfosChanged({mWindowInfos, mDisplayInfos, 0, 0});
}
void removeAllWindowsAndDisplays() {
@@ -4952,7 +4952,7 @@
displayInfo.displayId = ADISPLAY_ID_DEFAULT;
displayInfo.transform = transform;
- mDispatcher->onWindowInfosChanged({*window->getInfo()}, {displayInfo});
+ mDispatcher->onWindowInfosChanged({{*window->getInfo()}, {displayInfo}, 0, 0});
const NotifyMotionArgs motionArgs =
generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
@@ -5722,7 +5722,7 @@
displayInfos[1].displayId = SECOND_DISPLAY_ID;
displayInfos[1].transform = secondDisplayTransform;
- mDispatcher->onWindowInfosChanged({}, displayInfos);
+ mDispatcher->onWindowInfosChanged({{}, displayInfos, 0, 0});
// Enable InputFilter
mDispatcher->setInputFilterEnabled(true);