Merge "Wait for dispatcher idle before asserting policy callbacks" into udc-qpr-dev
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 045d0d6..6f0f022 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -6598,7 +6598,7 @@
  * this method can be safely called from any thread, as long as you've ensured that
  * the work you are interested in completing has already been queued.
  */
-bool InputDispatcher::waitForIdle() {
+bool InputDispatcher::waitForIdle() const {
     /**
      * Timeout should represent the longest possible time that a device might spend processing
      * events and commands.
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 58283c9..2038bb8 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -89,7 +89,7 @@
 
     void dump(std::string& dump) override;
     void monitor() override;
-    bool waitForIdle() override;
+    bool waitForIdle() const override;
     status_t start() override;
     status_t stop() override;
 
@@ -169,10 +169,10 @@
     InputDispatcherPolicyInterface& mPolicy;
     android::InputDispatcherConfiguration mConfig GUARDED_BY(mLock);
 
-    std::mutex mLock;
+    mutable std::mutex mLock;
 
     std::condition_variable mDispatcherIsAlive;
-    std::condition_variable mDispatcherEnteredIdle;
+    mutable std::condition_variable mDispatcherEnteredIdle;
 
     sp<Looper> mLooper;
 
diff --git a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
index 1c82521..e8c95c6 100644
--- a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
+++ b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
@@ -50,7 +50,7 @@
      * Return true if the dispatcher is idle.
      * Return false if the timeout waiting for the dispatcher to become idle has expired.
      */
-    virtual bool waitForIdle() = 0;
+    virtual bool waitForIdle() const = 0;
 
     /* Make the dispatcher start processing events.
      *
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 3bbb729..499d944 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -383,7 +383,9 @@
         mPointerCaptureRequest.reset();
     }
 
-    void assertDropTargetEquals(const sp<IBinder>& targetToken) {
+    void assertDropTargetEquals(const InputDispatcherInterface& dispatcher,
+                                const sp<IBinder>& targetToken) {
+        dispatcher.waitForIdle();
         std::scoped_lock lock(mLock);
         ASSERT_TRUE(mNotifyDropWindowWasCalled);
         ASSERT_EQ(targetToken, mDropTargetWindowToken);
@@ -8450,7 +8452,7 @@
                              {150, 50}))
             << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
     mDragWindow->consumeMotionUp(ADISPLAY_ID_DEFAULT);
-    mFakePolicy->assertDropTargetEquals(mSecondWindow->getToken());
+    mFakePolicy->assertDropTargetEquals(*mDispatcher, mSecondWindow->getToken());
     mWindow->assertNoEvents();
     mSecondWindow->assertNoEvents();
 }
@@ -8481,7 +8483,7 @@
     mDragWindow->consumeMotionMove(ADISPLAY_ID_DEFAULT);
     mWindow->assertNoEvents();
     mSecondWindow->assertNoEvents();
-    mFakePolicy->assertDropTargetEquals(mSecondWindow->getToken());
+    mFakePolicy->assertDropTargetEquals(*mDispatcher, mSecondWindow->getToken());
 
     // nothing to the window.
     ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
@@ -8527,7 +8529,7 @@
                              {150, 50}))
             << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
     mDragWindow->consumeMotionUp(ADISPLAY_ID_DEFAULT);
-    mFakePolicy->assertDropTargetEquals(nullptr);
+    mFakePolicy->assertDropTargetEquals(*mDispatcher, nullptr);
     mWindow->assertNoEvents();
     mSecondWindow->assertNoEvents();
 }
@@ -8610,7 +8612,7 @@
               injectMotionEvent(mDispatcher, secondFingerUpEvent, INJECT_EVENT_TIMEOUT,
                                 InputEventInjectionSync::WAIT_FOR_RESULT));
     mDragWindow->consumeMotionUp(ADISPLAY_ID_DEFAULT);
-    mFakePolicy->assertDropTargetEquals(mWindow->getToken());
+    mFakePolicy->assertDropTargetEquals(*mDispatcher, mWindow->getToken());
     mWindow->assertNoEvents();
     mSecondWindow->consumeMotionMove();
 }
@@ -8660,7 +8662,7 @@
                              {150, 50}))
             << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
     mDragWindow->consumeMotionUp(ADISPLAY_ID_DEFAULT);
-    mFakePolicy->assertDropTargetEquals(mSecondWindow->getToken());
+    mFakePolicy->assertDropTargetEquals(*mDispatcher, mSecondWindow->getToken());
     mWindow->assertNoEvents();
     mSecondWindow->assertNoEvents();
 }
@@ -8709,7 +8711,7 @@
                                         .build()))
             << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
     mDragWindow->consumeMotionUp(ADISPLAY_ID_DEFAULT);
-    mFakePolicy->assertDropTargetEquals(mSecondWindow->getToken());
+    mFakePolicy->assertDropTargetEquals(*mDispatcher, mSecondWindow->getToken());
     mWindow->assertNoEvents();
     mSecondWindow->assertNoEvents();
 }