Merge "Fix input infos are inconsistent between WMS and InputFlinger (1/2)" into rvc-dev
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 0b22586..e6129b9 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -76,7 +76,6 @@
 import android.view.InputDevice;
 import android.view.InputEvent;
 import android.view.InputMonitor;
-import android.view.InputWindowHandle;
 import android.view.KeyEvent;
 import android.view.PointerIcon;
 import android.view.Surface;
@@ -221,8 +220,7 @@
             int policyFlags);
     private static native VerifiedInputEvent nativeVerifyInputEvent(long ptr, InputEvent event);
     private static native void nativeToggleCapsLock(long ptr, int deviceId);
-    private static native void nativeSetInputWindows(long ptr, InputWindowHandle[] windowHandles,
-            int displayId);
+    private static native void nativeDisplayRemoved(long ptr, int displayId);
     private static native void nativeSetInputDispatchMode(long ptr, boolean enabled, boolean frozen);
     private static native void nativeSetSystemUiVisibility(long ptr, int visibility);
     private static native void nativeSetFocusedApplication(long ptr,
@@ -1536,7 +1534,7 @@
 
     /** Clean up input window handles of the given display. */
     public void onDisplayRemoved(int displayId) {
-        nativeSetInputWindows(mPtr, null /* windowHandles */, displayId);
+        nativeDisplayRemoved(mPtr, displayId);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 88cdd17..18332b9 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -62,7 +62,7 @@
     // When true, need to call updateInputWindowsLw().
     private boolean mUpdateInputWindowsNeeded = true;
     private boolean mUpdateInputWindowsPending;
-    private boolean mApplyImmediately;
+    private boolean mUpdateInputWindowsImmediately;
 
     // Currently focused input window handle.
     private InputWindowHandle mFocusedInputWindowHandle;
@@ -347,14 +347,20 @@
         }
     }
 
-    void updateInputWindowsImmediately() {
+    /**
+     * Immediately update the input transaction and merge into the passing Transaction that could be
+     * collected and applied later.
+     */
+    void updateInputWindowsImmediately(SurfaceControl.Transaction t) {
         mHandler.removeCallbacks(mUpdateInputWindows);
-        mApplyImmediately = true;
+        mUpdateInputWindowsImmediately = true;
         mUpdateInputWindows.run();
-        mApplyImmediately = false;
+        mUpdateInputWindowsImmediately = false;
+        t.merge(mInputTransaction);
     }
 
-    /* Called when the current input focus changes.
+    /**
+     * Called when the current input focus changes.
      * Layer assignment is assumed to be complete by the time this is called.
      */
     public void setInputFocusLw(WindowState newWindow, boolean updateInputWindows) {
@@ -465,10 +471,7 @@
             if (mAddWallpaperInputConsumerHandle) {
                 mWallpaperInputConsumer.show(mInputTransaction, 0);
             }
-
-            if (mApplyImmediately) {
-                mInputTransaction.apply();
-            } else {
+            if (!mUpdateInputWindowsImmediately) {
                 mDisplayContent.getPendingTransaction().merge(mInputTransaction);
                 mDisplayContent.scheduleAnimation();
             }
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index f046e8a..be0d6f8 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -268,8 +268,9 @@
         mDisplayContent.getDisplayRotation().pause();
 
         // Notify InputMonitor to take mDragWindowHandle.
-        mDisplayContent.getInputMonitor().updateInputWindowsImmediately();
-        new SurfaceControl.Transaction().syncInputWindows().apply(true);
+        final SurfaceControl.Transaction t = mService.mTransactionFactory.get();
+        mDisplayContent.getInputMonitor().updateInputWindowsImmediately(t);
+        t.syncInputWindows().apply();
 
         final DisplayMetrics displayMetrics = displayContent.getDisplayMetrics();
         mMinVisibleWidth = dipToPixel(MINIMUM_VISIBLE_WIDTH_IN_DP, displayMetrics);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 23ba528..0757725 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -7746,19 +7746,23 @@
     public void syncInputTransactions() {
         waitForAnimationsToComplete();
 
+        // Collect all input transactions from all displays to make sure we could sync all input
+        // windows at same time.
+        final SurfaceControl.Transaction t = mTransactionFactory.get();
         synchronized (mGlobalLock) {
             mWindowPlacerLocked.performSurfacePlacementIfScheduled();
             mRoot.forAllDisplays(displayContent ->
-                    displayContent.getInputMonitor().updateInputWindowsImmediately());
+                    displayContent.getInputMonitor().updateInputWindowsImmediately(t));
         }
 
-        mTransactionFactory.get().syncInputWindows().apply(true);
+        t.syncInputWindows().apply();
     }
 
     private void waitForAnimationsToComplete() {
         synchronized (mGlobalLock) {
             long timeoutRemaining = ANIMATION_COMPLETED_TIMEOUT_MS;
-            while (mRoot.isAnimating(TRANSITION | CHILDREN) && timeoutRemaining > 0) {
+            while ((mAnimator.isAnimationScheduled()
+                    || mRoot.isAnimating(TRANSITION | CHILDREN)) && timeoutRemaining > 0) {
                 long startTime = System.currentTimeMillis();
                 try {
                     mGlobalLock.wait(timeoutRemaining);
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index e3f9ae8..9bc5d34 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -206,7 +206,7 @@
     status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
     status_t pilferPointers(const sp<IBinder>& token);
 
-    void setInputWindows(JNIEnv* env, jobjectArray windowHandleObjArray, int32_t displayId);
+    void displayRemoved(JNIEnv* env, int32_t displayId);
     void setFocusedApplication(JNIEnv* env, int32_t displayId, jobject applicationHandleObj);
     void setFocusedDisplay(JNIEnv* env, int32_t displayId);
     void setInputDispatchMode(bool enabled, bool frozen);
@@ -771,55 +771,10 @@
     }
 }
 
-void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowHandleObjArray,
-         int32_t displayId) {
-    std::vector<sp<InputWindowHandle> > windowHandles;
-
-    if (windowHandleObjArray) {
-        jsize length = env->GetArrayLength(windowHandleObjArray);
-        for (jsize i = 0; i < length; i++) {
-            jobject windowHandleObj = env->GetObjectArrayElement(windowHandleObjArray, i);
-            if (! windowHandleObj) {
-                break; // found null element indicating end of used portion of the array
-            }
-
-            sp<InputWindowHandle> windowHandle =
-                    android_view_InputWindowHandle_getHandle(env, windowHandleObj);
-            if (windowHandle != nullptr) {
-                windowHandles.push_back(windowHandle);
-            }
-            env->DeleteLocalRef(windowHandleObj);
-        }
-    }
-
-    mInputManager->getDispatcher()->setInputWindows(windowHandles, displayId);
-
-    // Do this after the dispatcher has updated the window handle state.
-    bool newPointerGesturesEnabled = true;
-    size_t numWindows = windowHandles.size();
-    for (size_t i = 0; i < numWindows; i++) {
-        const sp<InputWindowHandle>& windowHandle = windowHandles[i];
-        const InputWindowInfo* windowInfo = windowHandle->getInfo();
-        if (windowInfo && windowInfo->hasFocus && (windowInfo->inputFeatures
-                & InputWindowInfo::INPUT_FEATURE_DISABLE_TOUCH_PAD_GESTURES)) {
-            newPointerGesturesEnabled = false;
-        }
-    }
-
-    bool pointerGesturesEnabledChanged = false;
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        if (mLocked.pointerGesturesEnabled != newPointerGesturesEnabled) {
-            mLocked.pointerGesturesEnabled = newPointerGesturesEnabled;
-            pointerGesturesEnabledChanged = true;
-        }
-    } // release lock
-
-    if (pointerGesturesEnabledChanged) {
-        mInputManager->getReader()->requestRefreshConfiguration(
-                InputReaderConfiguration::CHANGE_POINTER_GESTURE_ENABLEMENT);
-    }
+void NativeInputManager::displayRemoved(JNIEnv* env, int32_t displayId) {
+    // Set an empty list to remove all handles from the specific display.
+    std::vector<sp<InputWindowHandle>> windowHandles;
+    mInputManager->getDispatcher()->setInputWindows({{displayId, windowHandles}});
 }
 
 void NativeInputManager::setFocusedApplication(JNIEnv* env, int32_t displayId,
@@ -1567,11 +1522,10 @@
     im->getInputManager()->getReader()->toggleCapsLockState(deviceId);
 }
 
-static void nativeSetInputWindows(JNIEnv* env, jclass /* clazz */,
-        jlong ptr, jobjectArray windowHandleObjArray, jint displayId) {
+static void nativeDisplayRemoved(JNIEnv* env, jclass /* clazz */, jlong ptr, jint displayId) {
     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
-    im->setInputWindows(env, windowHandleObjArray, displayId);
+    im->displayRemoved(env, displayId);
 }
 
 static void nativeSetFocusedApplication(JNIEnv* env, jclass /* clazz */,
@@ -1815,8 +1769,7 @@
         {"nativeVerifyInputEvent", "(JLandroid/view/InputEvent;)Landroid/view/VerifiedInputEvent;",
          (void*)nativeVerifyInputEvent},
         {"nativeToggleCapsLock", "(JI)V", (void*)nativeToggleCapsLock},
-        {"nativeSetInputWindows", "(J[Landroid/view/InputWindowHandle;I)V",
-         (void*)nativeSetInputWindows},
+        {"nativeDisplayRemoved", "(JI)V", (void*)nativeDisplayRemoved},
         {"nativeSetFocusedApplication", "(JILandroid/view/InputApplicationHandle;)V",
          (void*)nativeSetFocusedApplication},
         {"nativeSetFocusedDisplay", "(JI)V", (void*)nativeSetFocusedDisplay},