Fix NavigationBar overlapping with the IME window

As WindowToken#setInsetsFrozen that introduced by CL[1], [2] that used
for freezing dispathcing insets state when the app transitioning or
becoming invisible.

To prevent unnecessary app UI glitch during dispatching insets changes
while animating, the method call ends up setting frozen insets state
for all children windows.

Since forAllWindows will call forAllImeWindows to also set frozen
insets state for IME window when the window is IME layering targets
and not in split-screen windowing mode, which is not expected because
the IME window is controlled by IME insets provider and should not
have frozen insets state to make IME UI been overlapped with navbar
because of wrong insets state.

Make sure to set frozen state only for the window belongs to the same
window token.

[1]: Iae5025beaed7d70a4623b446a1bb73574d420663
[2]: I56418733c1abbd73e88a8918a5d55ecc15344c5e

Fix: 181840663
Test: manual as issue steps:
   1) Factory reset device.
   2) Skip Setup Wizard.
   3) Select a WIFI hotspot which require a password to
      show up keyboard
   4) Verify if IME layout correctly without overlapping with navbar.
Test: atest WindowTokenTests#testSetInsetsFrozen_notAffectImeWindowState
Change-Id: I9442095e833bf430f49cd824af2ab430da5d662c
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 8867aa7..193c74f 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -758,10 +758,14 @@
 
     /** @see WindowState#freezeInsetsState() */
     void setInsetsFrozen(boolean freeze) {
-        if (freeze) {
-            forAllWindows(WindowState::freezeInsetsState, true /* traverseTopToBottom */);
-        } else {
-            forAllWindows(WindowState::clearFrozenInsetsState, true /* traverseTopToBottom */);
-        }
+        forAllWindows(w -> {
+            if (w.mToken == this) {
+                if (freeze) {
+                    w.freezeInsetsState();
+                } else {
+                    w.clearFrozenInsetsState();
+                }
+            }
+        },  true /* traverseTopToBottom */);
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
index e2585e5..16e0d90 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.view.InsetsState.ITYPE_IME;
 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
@@ -250,4 +251,29 @@
 
         verify(selectFunc).apply(token2.windowType, options);
     }
+
+    /**
+     * Test that {@link WindowToken#setInsetsFrozen(boolean)} will set the frozen insets
+     * states for its children windows and by default it shouldn't let IME window setting
+     * the frozen insets state even the window of the window token is the IME layering target.
+     */
+    @UseTestDisplay(addWindows = W_INPUT_METHOD)
+    @Test
+    public void testSetInsetsFrozen_notAffectImeWindowState() {
+        // Pre-condition: make the IME window be controlled by IME insets provider.
+        mDisplayContent.getInsetsStateController().getSourceProvider(ITYPE_IME).setWindow(
+                mDisplayContent.mInputMethodWindow, null, null);
+
+        // Simulate an app window to be the IME layering target, assume the app window has no
+        // frozen insets state by default.
+        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+        mDisplayContent.setImeLayeringTarget(app);
+        assertNull(app.getFrozenInsetsState());
+        assertTrue(app.isImeLayeringTarget());
+
+        // Verify invoking setInsetsFrozen shouldn't let IME window setting the frozen insets state.
+        app.mToken.setInsetsFrozen(true);
+        assertNotNull(app.getFrozenInsetsState());
+        assertNull(mDisplayContent.mInputMethodWindow.getFrozenInsetsState());
+    }
 }