Fixed issue with ordering of non-app token windows

We tried to fix this issue in I83357975c87c704af9d0702c939ca99984462365
but the fix introduced other problems. So, we are going to have sys-ui
create a separate binder for object for each type of window it adds.
Long term we want to allow one binder object to map to multiple window
tokens on the same display in window manager.

Change-Id: Iee53b8bf95b87f79ab7a1b574a54111c678f7413
Fixes: 33567674
Fixes: 33538278
Test: bit FrameworksServicesTests:com.android.server.wm.DisplayContentTests
(cherry picked from commit 6ce0fb8ddbdc726d55c81a4bf797f028e441e448)
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index 9eceeac..3f9ae55 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -13,6 +13,7 @@
 import android.content.res.Resources;
 import android.graphics.PixelFormat;
 import android.os.AsyncTask;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -155,6 +156,7 @@
                         | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                         | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                 PixelFormat.TRANSLUCENT);
+        lp.token = new Binder();
         if (ActivityManager.isHighEndGfx()) {
             lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
index cf75c4f..002515d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
@@ -27,6 +27,7 @@
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
+import android.os.Binder;
 import android.os.RemoteException;
 import android.util.DisplayMetrics;
 import android.view.Gravity;
@@ -106,6 +107,7 @@
                         | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
                 ,
                 PixelFormat.TRANSLUCENT);
+        lp.token = new Binder();
         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
         lp.setTitle("ScreenPinningConfirmation");
         lp.gravity = Gravity.FILL;
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java
index 3db03d0..cb9453b 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.graphics.PixelFormat;
+import android.os.Binder;
 import android.view.View;
 import android.view.WindowManager;
 
@@ -51,6 +52,7 @@
                 FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL
                         | FLAG_WATCH_OUTSIDE_TOUCH | FLAG_SPLIT_TOUCH | FLAG_SLIPPERY,
                 PixelFormat.TRANSLUCENT);
+        mLp.token = new Binder();
         mLp.setTitle(WINDOW_TITLE);
         mLp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
         view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index ae9d068..252b5c9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -74,6 +74,7 @@
 import android.media.session.PlaybackState;
 import android.net.Uri;
 import android.os.AsyncTask;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -1531,6 +1532,7 @@
                     | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
                     | WindowManager.LayoutParams.FLAG_SLIPPERY,
                 PixelFormat.TRANSLUCENT);
+        lp.token = new Binder();
         // this will allow the navbar to run in an overlay on devices that support this
         if (ActivityManager.isHighEndGfx()) {
             lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
index 29c0705..0660054 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
@@ -22,6 +22,7 @@
 import android.content.pm.ActivityInfo;
 import android.content.res.Resources;
 import android.graphics.PixelFormat;
+import android.os.Binder;
 import android.os.RemoteException;
 import android.os.SystemProperties;
 import android.os.Trace;
@@ -97,6 +98,7 @@
                         | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                         | WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
                 PixelFormat.TRANSLUCENT);
+        mLp.token = new Binder();
         mLp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
         mLp.gravity = Gravity.TOP;
         mLp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 73f68f8..203137d 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -2622,22 +2622,6 @@
      * Apps. E.g. status bar.
      */
     private final class NonAppWindowContainers extends DisplayChildWindowContainer<WindowToken> {
-        final LinkedList<WindowState> mTmpWindows = new LinkedList();
-
-        private final ToBooleanFunction<WindowState> mCollectWindowsInOrder = w -> {
-            int addIndex = mTmpWindows.size();
-            for (int i = mTmpWindows.size() - 1; i >= 0; --i) {
-                final WindowState current = mTmpWindows.get(i);
-                if (w.mBaseLayer > current.mBaseLayer) {
-                    break;
-                }
-                addIndex = i;
-            }
-
-            mTmpWindows.add(addIndex, w);
-            return false;
-        };
-
         /**
          * Compares two child window tokens returns -1 if the first is lesser than the second in
          * terms of z-order and 1 otherwise.
@@ -2669,29 +2653,6 @@
         }
 
         @Override
-        boolean forAllWindows(ToBooleanFunction<WindowState> callback,
-                boolean traverseTopToBottom) {
-            // Hack to work around WindowToken containing windows of various types there by causing
-            // the windows not to be returned in visual order if there is another token with a
-            // window that should be z-order in-between the windows of the first token. This is an
-            // issue due to the various window types sys-ui adds with its token.
-            // TODO: Have a separate token for each type of window sys-ui wants to add. Would
-            // require some changes to sys-ui on the token it uses for window creation vs. just
-            // using the default token of its process.
-            mTmpWindows.clear();
-            super.forAllWindows(mCollectWindowsInOrder, false /* traverseTopToBottom */);
-
-            while(!mTmpWindows.isEmpty()) {
-                final WindowState current = traverseTopToBottom
-                        ? mTmpWindows.pollLast() : mTmpWindows.pollFirst();
-                if (callback.apply(current)) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        @Override
         int getOrientation() {
             final WindowManagerPolicy policy = mService.mPolicy;
             // Find a window requesting orientation.
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
index 0e20c4e..01808cb 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -83,7 +83,7 @@
     }
 
     @Test
-    public void testForAllWindows_WithImeTarget() throws Exception {
+    public void testForAllWindows_WithAppImeTarget() throws Exception {
         final WindowState imeAppTarget =
                 createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "imeAppTarget");
 
@@ -126,6 +126,44 @@
     }
 
     @Test
+    public void testForAllWindows_WithStatusBarImeTarget() throws Exception {
+
+        sWm.mInputMethodTarget = sStatusBarWindow;
+
+        final ArrayList<WindowState> windows = new ArrayList();
+
+        // Test forward traversal.
+        sDisplayContent.forAllWindows(w -> {windows.add(w);}, false /* traverseTopToBottom */);
+
+        assertEquals(sWallpaperWindow, windows.get(0));
+        assertEquals(sChildAppWindowBelow, windows.get(1));
+        assertEquals(sAppWindow, windows.get(2));
+        assertEquals(sChildAppWindowAbove, windows.get(3));
+        assertEquals(sDockedDividerWindow, windows.get(4));
+        assertEquals(sStatusBarWindow, windows.get(5));
+        assertEquals(sImeWindow, windows.get(6));
+        assertEquals(sImeDialogWindow, windows.get(7));
+        assertEquals(sNavBarWindow, windows.get(8));
+
+        // Test backward traversal.
+        windows.clear();
+        sDisplayContent.forAllWindows(w -> {windows.add(w);}, true /* traverseTopToBottom */);
+
+        assertEquals(sWallpaperWindow, windows.get(8));
+        assertEquals(sChildAppWindowBelow, windows.get(7));
+        assertEquals(sAppWindow, windows.get(6));
+        assertEquals(sChildAppWindowAbove, windows.get(5));
+        assertEquals(sDockedDividerWindow, windows.get(4));
+        assertEquals(sStatusBarWindow, windows.get(3));
+        assertEquals(sImeWindow, windows.get(2));
+        assertEquals(sImeDialogWindow, windows.get(1));
+        assertEquals(sNavBarWindow, windows.get(0));
+
+        // Clean-up
+        sWm.mInputMethodTarget = null;
+    }
+
+    @Test
     public void testForAllWindows_WithInBetweenWindowToken() throws Exception {
         // This window is set-up to be z-ordered between some windows that go in the same token like
         // the nav bar and status bar.
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
index 05101e4..41bf646 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
@@ -82,11 +82,10 @@
         sImeDialogWindow =
                 createWindow(null, TYPE_INPUT_METHOD_DIALOG, sDisplayContent, "sImeDialogWindow");
         sStatusBarWindow = createWindow(null, TYPE_STATUS_BAR, sDisplayContent, "sStatusBarWindow");
-        final WindowToken statusBarToken = sStatusBarWindow.mToken;
         sNavBarWindow =
-                createWindow(null, TYPE_NAVIGATION_BAR, statusBarToken, "sNavBarWindow");
+                createWindow(null, TYPE_NAVIGATION_BAR, sDisplayContent, "sNavBarWindow");
         sDockedDividerWindow =
-                createWindow(null, TYPE_DOCK_DIVIDER, statusBarToken, "sDockedDividerWindow");
+                createWindow(null, TYPE_DOCK_DIVIDER, sDisplayContent, "sDockedDividerWindow");
         sAppWindow = createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "sAppWindow");
         sChildAppWindowAbove = createWindow(sAppWindow,
                 TYPE_APPLICATION_ATTACHED_DIALOG, sAppWindow.mToken, "sChildAppWindowAbove");