SyncPointerCapture (1/n): Notify PointerCaptureChanged through InputListener

This CL adds notifyPointerCaptureChanged(NotifyPointerCaptureChangedArgs)
to the InputListener interface so that InputReader can notify the Dispatcher
about changes in its PointerCapture state synchronously with the
processing of input events.

Notifying the Dispatcher about the pointer capture state through the
InputListener interface will synchronize the state change notification
with input events that are reported through the same interface.

Bug: 141749603
Test: atest inputflinger_tests
Change-Id: I7bfd45334fa70eccdd5a0f002cbb00e7a1de8d14
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index a72d5c3..99eaac6 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -1792,6 +1792,29 @@
               mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD, AKEYCODE_C));
 }
 
+TEST_F(InputReaderTest, ChangingPointerCaptureNotifiesInputListener) {
+    NotifyPointerCaptureChangedArgs args;
+
+    mFakePolicy->setPointerCapture(true);
+    mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
+    mReader->loopOnce();
+    mFakeListener->assertNotifyCaptureWasCalled(&args);
+    ASSERT_TRUE(args.enabled) << "Pointer Capture should be enabled.";
+
+    mFakePolicy->setPointerCapture(false);
+    mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
+    mReader->loopOnce();
+    mFakeListener->assertNotifyCaptureWasCalled(&args);
+    ASSERT_FALSE(args.enabled) << "Pointer Capture should be disabled.";
+
+    // Verify that the Pointer Capture state is re-configured correctly when the configuration value
+    // does not change.
+    mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
+    mReader->loopOnce();
+    mFakeListener->assertNotifyCaptureWasCalled(&args);
+    ASSERT_FALSE(args.enabled) << "Pointer Capture should be disabled.";
+}
+
 // --- InputReaderIntegrationTest ---
 
 // These tests create and interact with the InputReader only through its interface.
diff --git a/services/inputflinger/tests/TestInputListener.cpp b/services/inputflinger/tests/TestInputListener.cpp
index 9bff166..352995c 100644
--- a/services/inputflinger/tests/TestInputListener.cpp
+++ b/services/inputflinger/tests/TestInputListener.cpp
@@ -82,6 +82,14 @@
                                            "Expected notifySwitch() to have been called."));
 }
 
+void TestInputListener::assertNotifyCaptureWasCalled(
+        NotifyPointerCaptureChangedArgs* outEventArgs) {
+    ASSERT_NO_FATAL_FAILURE(
+            assertCalled<NotifyPointerCaptureChangedArgs>(outEventArgs,
+                                                          "Expected notifyPointerCaptureChanged() "
+                                                          "to have been called."));
+}
+
 template <class NotifyArgsType>
 void TestInputListener::assertCalled(NotifyArgsType* outEventArgs, std::string message) {
     std::unique_lock<std::mutex> lock(mLock);
@@ -145,4 +153,8 @@
     notify<NotifySwitchArgs>(args);
 }
 
+void TestInputListener::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
+    notify<NotifyPointerCaptureChangedArgs>(args);
+}
+
 } // namespace android
diff --git a/services/inputflinger/tests/TestInputListener.h b/services/inputflinger/tests/TestInputListener.h
index d50c6bc..887d4ea 100644
--- a/services/inputflinger/tests/TestInputListener.h
+++ b/services/inputflinger/tests/TestInputListener.h
@@ -54,6 +54,8 @@
 
     void assertNotifySwitchWasCalled(NotifySwitchArgs* outEventArgs = nullptr);
 
+    void assertNotifyCaptureWasCalled(NotifyPointerCaptureChangedArgs* outEventArgs = nullptr);
+
 private:
     template <class NotifyArgsType>
     void assertCalled(NotifyArgsType* outEventArgs, std::string message);
@@ -74,16 +76,19 @@
 
     virtual void notifySwitch(const NotifySwitchArgs* args) override;
 
+    virtual void notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) override;
+
     std::mutex mLock;
     std::condition_variable mCondition;
     const std::chrono::milliseconds mEventHappenedTimeout;
     const std::chrono::milliseconds mEventDidNotHappenTimeout;
 
-    std::tuple<std::vector<NotifyConfigurationChangedArgs>, //
-               std::vector<NotifyDeviceResetArgs>,          //
-               std::vector<NotifyKeyArgs>,                  //
-               std::vector<NotifyMotionArgs>,               //
-               std::vector<NotifySwitchArgs>>               //
+    std::tuple<std::vector<NotifyConfigurationChangedArgs>,  //
+               std::vector<NotifyDeviceResetArgs>,           //
+               std::vector<NotifyKeyArgs>,                   //
+               std::vector<NotifyMotionArgs>,                //
+               std::vector<NotifySwitchArgs>,                //
+               std::vector<NotifyPointerCaptureChangedArgs>> //
             mQueues GUARDED_BY(mLock);
 };