Allow spy windows to prevent splitting

To avoid a crash in dispatcher, allow spy window to prevent splitting.
This would get the behaviour more in line with the existing app windows.
In the future, we need to holistically revisit the splitting behaviour.

The crash that this fixes can happen as follows:
In freeform window scenario, enable outbound event verification and
repeatedly touch the corners of the freeform window while
attempting to resize.
The spy windows are being used for capturing the window resizing
gesture, and also for interaction with the window's caption bar for
repositioning.

The test in this patch reproduces this scenario.

In this fix, we add a splitting behaviour to spy window to roughly match
the behaviour of the regular windows - if a first pointer lands into a
window that prevents splitting, then the remaining pointers will
continue going to that window, even if they are outside. This behaviour
is not very clear in various window configurations where one window
supports splitting while another doesn't. This will be revisited in
subsequent patches. The goal with this CL is to just fix the crash.

Bug: 347700797
Flag: EXEMPT bugfix
Test: TEST=inputflinger_tests; m $TEST && $ANDROID_HOST_OUT/nativetest64/$TEST/$TEST --gtest_break_on_failure --gtest_filter="*SpyThatPreventsSplittingWithApplication*"
Change-Id: I7d7c8668e993e66da0e39d1da8bb81831f6b3cc9
diff --git a/services/inputflinger/tests/TestEventMatchers.h b/services/inputflinger/tests/TestEventMatchers.h
index f8e3c22..cfedc6e 100644
--- a/services/inputflinger/tests/TestEventMatchers.h
+++ b/services/inputflinger/tests/TestEventMatchers.h
@@ -609,10 +609,33 @@
     return arg.getRepeatCount() == repeatCount;
 }
 
-MATCHER_P2(WithPointerId, index, id, "MotionEvent with specified pointer ID for pointer index") {
-    const auto argPointerId = arg.pointerProperties[index].id;
-    *result_listener << "expected pointer with index " << index << " to have ID " << argPointerId;
-    return argPointerId == id;
+class WithPointerIdMatcher {
+public:
+    using is_gtest_matcher = void;
+    explicit WithPointerIdMatcher(size_t index, int32_t pointerId)
+          : mIndex(index), mPointerId(pointerId) {}
+
+    bool MatchAndExplain(const NotifyMotionArgs& args, std::ostream*) const {
+        return args.pointerProperties[mIndex].id == mPointerId;
+    }
+
+    bool MatchAndExplain(const MotionEvent& event, std::ostream*) const {
+        return event.getPointerId(mIndex) == mPointerId;
+    }
+
+    void DescribeTo(std::ostream* os) const {
+        *os << "with pointer[" << mIndex << "] id = " << mPointerId;
+    }
+
+    void DescribeNegationTo(std::ostream* os) const { *os << "wrong pointerId"; }
+
+private:
+    const size_t mIndex;
+    const int32_t mPointerId;
+};
+
+inline WithPointerIdMatcher WithPointerId(size_t index, int32_t pointerId) {
+    return WithPointerIdMatcher(index, pointerId);
 }
 
 MATCHER_P2(WithCursorPosition, x, y, "InputEvent with specified cursor position") {