InputDispatcher: dump window in a separate function
This makes it more convenient to dump windows from other places during
debugging. For example, this could also be called from setInputWindows
to inspect all of the window flags that might be changing.
Bug: 312714754
Test: adb shell dumpsys input
Change-Id: I2ace23bec1231f3a318e1b6a19f146b588e077b6
diff --git a/include/input/PrintTools.h b/include/input/PrintTools.h
index 63c0e40..83fffa3 100644
--- a/include/input/PrintTools.h
+++ b/include/input/PrintTools.h
@@ -20,6 +20,7 @@
#include <map>
#include <optional>
#include <set>
+#include <sstream>
#include <string>
#include <vector>
@@ -33,6 +34,13 @@
return bitset.to_string();
}
+template <class T>
+std::string streamableToString(const T& streamable) {
+ std::stringstream out;
+ out << streamable;
+ return out.str();
+}
+
template <typename T>
inline std::string constToString(const T& v) {
return std::to_string(v);
diff --git a/libs/gui/WindowInfo.cpp b/libs/gui/WindowInfo.cpp
index 6a4460b..ba1d196 100644
--- a/libs/gui/WindowInfo.cpp
+++ b/libs/gui/WindowInfo.cpp
@@ -26,6 +26,41 @@
namespace android::gui {
+namespace {
+
+std::ostream& operator<<(std::ostream& out, const sp<IBinder>& binder) {
+ if (binder == nullptr) {
+ out << "<null>";
+ } else {
+ out << binder.get();
+ }
+ return out;
+}
+
+std::ostream& operator<<(std::ostream& out, const Region& region) {
+ if (region.isEmpty()) {
+ out << "<empty>";
+ return out;
+ }
+
+ bool first = true;
+ Region::const_iterator cur = region.begin();
+ Region::const_iterator const tail = region.end();
+ while (cur != tail) {
+ if (first) {
+ first = false;
+ } else {
+ out << "|";
+ }
+ out << "[" << cur->left << "," << cur->top << "][" << cur->right << "," << cur->bottom
+ << "]";
+ cur++;
+ }
+ return out;
+}
+
+} // namespace
+
void WindowInfo::setInputConfig(ftl::Flags<InputConfig> config, bool value) {
if (value) {
inputConfig |= config;
@@ -222,4 +257,24 @@
void WindowInfoHandle::updateFrom(sp<WindowInfoHandle> handle) {
mInfo = handle->mInfo;
}
+
+std::ostream& operator<<(std::ostream& out, const WindowInfoHandle& window) {
+ const WindowInfo& info = *window.getInfo();
+ std::string transform;
+ info.transform.dump(transform, "transform", " ");
+ out << "name=" << info.name << ", id=" << info.id << ", displayId=" << info.displayId
+ << ", inputConfig=" << info.inputConfig.string() << ", alpha=" << info.alpha << ", frame=["
+ << info.frame.left << "," << info.frame.top << "][" << info.frame.right << ","
+ << info.frame.bottom << "], globalScale=" << info.globalScaleFactor
+ << ", applicationInfo.name=" << info.applicationInfo.name
+ << ", applicationInfo.token=" << info.applicationInfo.token
+ << ", touchableRegion=" << info.touchableRegion << ", ownerPid=" << info.ownerPid.toString()
+ << ", ownerUid=" << info.ownerUid.toString() << ", dispatchingTimeout="
+ << std::chrono::duration_cast<std::chrono::milliseconds>(info.dispatchingTimeout).count()
+ << "ms, token=" << info.token.get()
+ << ", touchOcclusionMode=" << ftl::enum_string(info.touchOcclusionMode) << "\n"
+ << transform;
+ return out;
+}
+
} // namespace android::gui
diff --git a/libs/gui/android/gui/TouchOcclusionMode.aidl b/libs/gui/android/gui/TouchOcclusionMode.aidl
index d91d052..ed72105 100644
--- a/libs/gui/android/gui/TouchOcclusionMode.aidl
+++ b/libs/gui/android/gui/TouchOcclusionMode.aidl
@@ -43,5 +43,6 @@
* The window won't count for touch occlusion rules if the touch passes
* through it.
*/
- ALLOW
+ ALLOW,
+ ftl_last=ALLOW,
}
diff --git a/libs/gui/include/gui/WindowInfo.h b/libs/gui/include/gui/WindowInfo.h
index dcc38d7..4d4c5e4 100644
--- a/libs/gui/include/gui/WindowInfo.h
+++ b/libs/gui/include/gui/WindowInfo.h
@@ -315,4 +315,7 @@
WindowInfo mInfo;
};
+
+std::ostream& operator<<(std::ostream& out, const WindowInfoHandle& window);
+
} // namespace android::gui
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 1a94f41..6033398 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -126,10 +126,6 @@
return systemTime(SYSTEM_TIME_MONOTONIC);
}
-bool isEmpty(const std::stringstream& ss) {
- return ss.rdbuf()->in_avail() == 0;
-}
-
inline const std::string binderToString(const sp<IBinder>& binder) {
if (binder == nullptr) {
return "<null>";
@@ -5129,7 +5125,7 @@
for (const sp<WindowInfoHandle>& iwh : windowInfoHandles) {
windowList += iwh->getName() + " ";
}
- ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
+ LOG(INFO) << "setInputWindows displayId=" << displayId << " " << windowList;
}
// Check preconditions for new input windows
@@ -5687,33 +5683,8 @@
if (!windowHandles.empty()) {
dump += INDENT2 "Windows:\n";
for (size_t i = 0; i < windowHandles.size(); i++) {
- const sp<WindowInfoHandle>& windowHandle = windowHandles[i];
- const WindowInfo* windowInfo = windowHandle->getInfo();
-
- dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
- "inputConfig=%s, alpha=%.2f, "
- "frame=[%d,%d][%d,%d], globalScale=%f, "
- "applicationInfo.name=%s, "
- "applicationInfo.token=%s, "
- "touchableRegion=",
- i, windowInfo->name.c_str(), windowInfo->id,
- windowInfo->displayId,
- windowInfo->inputConfig.string().c_str(),
- windowInfo->alpha, windowInfo->frame.left,
- windowInfo->frame.top, windowInfo->frame.right,
- windowInfo->frame.bottom, windowInfo->globalScaleFactor,
- windowInfo->applicationInfo.name.c_str(),
- binderToString(windowInfo->applicationInfo.token).c_str());
- dump += dumpRegion(windowInfo->touchableRegion);
- dump += StringPrintf(", ownerPid=%s, ownerUid=%s, dispatchingTimeout=%" PRId64
- "ms, hasToken=%s, "
- "touchOcclusionMode=%s\n",
- windowInfo->ownerPid.toString().c_str(),
- windowInfo->ownerUid.toString().c_str(),
- millis(windowInfo->dispatchingTimeout),
- binderToString(windowInfo->token).c_str(),
- toString(windowInfo->touchOcclusionMode).c_str());
- windowInfo->transform.dump(dump, "transform", INDENT4);
+ dump += StringPrintf(INDENT3 "%zu: %s", i,
+ streamableToString(*windowHandles[i]).c_str());
}
} else {
dump += INDENT2 "Windows: <none>\n";
@@ -5802,11 +5773,10 @@
} else {
dump += INDENT3 "WaitQueue: <empty>\n";
}
- std::stringstream inputStateDump;
- inputStateDump << connection->inputState;
- if (!isEmpty(inputStateDump)) {
+ std::string inputStateDump = streamableToString(connection->inputState);
+ if (!inputStateDump.empty()) {
dump += INDENT3 "InputState: ";
- dump += inputStateDump.str() + "\n";
+ dump += inputStateDump + "\n";
}
}
} else {