Introduced WindowContainer.hasContentToDisplay

We have lots of "is visible" methods and this change is an attempt
to rename one of the methods to match closer to what is actually does
and differentiate it from other "is visible" methods.

WC.hasContentToDisplay() returns true if the container or one of its
children as some content it can display or wants to display
(e.g. app views or saved surface).

WC.isVisible() returns true if the container or one of its children
is considered visible from the WindowManager perspective which usually
means valid surface and some other internal state are true.

Bug: 30060889
Change-Id: Ifbd6c277eb65a53b8035b6f34fc45196962632c1
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index 5ddf283..93e9559 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -17,7 +17,6 @@
 package com.android.server.wm;
 
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -119,7 +118,7 @@
             int stackClip) {
         if (WindowManagerService.localLOGV) Slog.v(TAG, "Setting animation in " + mAppToken
                 + ": " + anim + " wxh=" + width + "x" + height
-                + " isVisible=" + mAppToken.isVisible());
+                + " hasContentToDisplay=" + mAppToken.hasContentToDisplay());
         animation = anim;
         animating = false;
         if (!anim.isInitialized()) {
@@ -141,7 +140,7 @@
         }
         // Start out animation gone if window is gone, or visible if window is visible.
         transformation.clear();
-        transformation.setAlpha(mAppToken.isVisible() ? 1 : 0);
+        transformation.setAlpha(mAppToken.hasContentToDisplay() ? 1 : 0);
         hasTransformation = true;
         mStackClip = stackClip;
 
@@ -164,11 +163,11 @@
 
     public void setDummyAnimation() {
         if (WindowManagerService.localLOGV) Slog.v(TAG, "Setting dummy animation in " + mAppToken
-                + " isVisible=" + mAppToken.isVisible());
+                + " hasContentToDisplay=" + mAppToken.hasContentToDisplay());
         animation = sDummyAnimation;
         hasTransformation = true;
         transformation.clear();
-        transformation.setAlpha(mAppToken.isVisible() ? 1 : 0);
+        transformation.setAlpha(mAppToken.hasContentToDisplay() ? 1 : 0);
     }
 
     void setNullAnimation() {
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 47b5f3d..d7e7f81 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -359,6 +359,15 @@
     }
 
     @Override
+    boolean isVisible() {
+        if (hidden) {
+            // TODO: Should this be checking hiddenRequested instead of hidden?
+            return false;
+        }
+        return super.isVisible();
+    }
+
+    @Override
     void removeIfPossible() {
         mIsExiting = false;
         removeAllWindows();
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 754a9a6..545a439 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -579,6 +579,16 @@
         return (tokensCount != 0) && mAppTokens.get(tokensCount - 1).showForAllUsers;
     }
 
+    boolean hasContentToDisplay() {
+        for (int i = mAppTokens.size() - 1; i >= 0; i--) {
+            final AppWindowToken appToken = mAppTokens.get(i);
+            if (appToken.hasContentToDisplay()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     boolean isVisible() {
         for (int i = mAppTokens.size() - 1; i >= 0; i--) {
             final AppWindowToken appToken = mAppTokens.get(i);
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 21fc08b..87ad639 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -43,7 +43,6 @@
 import android.util.SparseArray;
 import android.view.DisplayInfo;
 import android.view.Surface;
-import android.view.SurfaceControl;
 import android.view.animation.Animation;
 
 import com.android.internal.policy.DividerSnapAlgorithm;
@@ -898,7 +897,7 @@
     void beginImeAdjustAnimation() {
         for (int j = mTasks.size() - 1; j >= 0; j--) {
             final Task task = mTasks.get(j);
-            if (task.isVisible()) {
+            if (task.hasContentToDisplay()) {
                 task.setDragResizing(true, DRAG_RESIZE_MODE_DOCKED_DIVIDER);
                 task.setWaitingForDrawnIfResizingChanged();
             }
@@ -1201,10 +1200,8 @@
 
         for (int i = mTasks.size() - 1; i >= 0; i--) {
             final Task task = mTasks.get(i);
-            for (int j = task.mAppTokens.size() - 1; j >= 0; j--) {
-                if (!task.mAppTokens.get(j).hidden) {
-                    return true;
-                }
+            if (task.isVisible()) {
+                return true;
             }
         }
 
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index d37d0e1..fa05c0c 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -193,6 +193,33 @@
         }
     }
 
+    /**
+     * Returns true if the container or one of its children as some content it can display or wants
+     * to display (e.g. app views or saved surface).
+     *
+     * NOTE: While this method will return true if the there is some content to display, it doesn't
+     * mean the container is visible. Use {@link #isVisible()} to determine if the container is
+     * visible.
+     */
+    boolean hasContentToDisplay() {
+        for (int i = mChildren.size() - 1; i >= 0; --i) {
+            final WindowContainer wc = mChildren.get(i);
+            if (wc.hasContentToDisplay()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns true if the container or one of its children is considered visible from the
+     * WindowManager perspective which usually means valid surface and some other internal state
+     * are true.
+     *
+     * NOTE: While this method will return true if the surface is visible, it doesn't mean the
+     * client has actually displayed any content. Use {@link #hasContentToDisplay()} to determine if
+     * the container has any content to display.
+     */
     boolean isVisible() {
         for (int i = mChildren.size() - 1; i >= 0; --i) {
             final WindowContainer wc = mChildren.get(i);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 5c681d5..e6f2acb 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -10039,7 +10039,7 @@
     public void setWillReplaceWindow(IBinder token, boolean animate) {
         synchronized (mWindowMap) {
             final AppWindowToken appWindowToken = findAppWindowToken(token);
-            if (appWindowToken == null || !appWindowToken.isVisible()) {
+            if (appWindowToken == null || !appWindowToken.hasContentToDisplay()) {
                 Slog.w(TAG_WM, "Attempted to set replacing window on non-existing app token "
                         + token);
                 return;
@@ -10063,7 +10063,7 @@
     public void setWillReplaceWindows(IBinder token, boolean childrenOnly) {
         synchronized (mWindowMap) {
             final AppWindowToken appWindowToken = findAppWindowToken(token);
-            if (appWindowToken == null || !appWindowToken.isVisible()) {
+            if (appWindowToken == null || !appWindowToken.hasContentToDisplay()) {
                 Slog.w(TAG_WM, "Attempted to set replacing window on non-existing app token "
                         + token);
                 return;
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index fd47f5b..fccd2d9 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1181,10 +1181,8 @@
         }
     }
 
-    // TODO: Sigh...another is visible method...tried to consolidate with other isVisible methods
-    // below, but failed. Need to figure-out a good way to handle this long term...
     @Override
-    boolean isVisible() {
+    boolean hasContentToDisplay() {
         // If we're animating with a saved surface, we're already visible.
         // Return true so that the alpha doesn't get cleared.
         if (!mAppFreezing && isDrawnLw()
@@ -1193,6 +1191,17 @@
             return true;
         }
 
+        return super.hasContentToDisplay();
+    }
+
+    @Override
+    boolean isVisible() {
+        if ((mAppToken == null || !mAppToken.hiddenRequested) && isVisibleUnchecked()) {
+            // Is this window visible?  It is not visible if there is no surface, or we are in the
+            // process of running an exit animation that will remove the surface, or its app token
+            // has been hidden.
+            return true;
+        }
         return super.isVisible();
     }
 
@@ -1206,13 +1215,9 @@
                 && !mAnimatingExit && !mDestroying && (!mIsWallpaper || mWallpaperVisible);
     }
 
-    /**
-     * Is this window visible?  It is not visible if there is no surface, or we are in the process
-     * of running an exit animation that will remove the surface, or its app token has been hidden.
-     */
     @Override
     public boolean isVisibleLw() {
-        return (mAppToken == null || !mAppToken.hiddenRequested) && isVisibleUnchecked();
+        return isVisible();
     }
 
     /**
@@ -1238,7 +1243,8 @@
      * Is this window visible, ignoring its app token? It is not visible if there is no surface,
      * or we are in the process of running an exit animation that will remove the surface.
      */
-    public boolean isWinVisibleLw() {
+    // TODO: Can we consolidate this with #isVisible() or have a more appropriate name for this?
+    boolean isWinVisibleLw() {
         return (mAppToken == null || !mAppToken.hiddenRequested || mAppToken.mAppAnimator.animating)
                 && isVisibleUnchecked();
     }
@@ -1287,7 +1293,7 @@
      * Like isOnScreen(), but ignores any force hiding of the window due
      * to the keyguard.
      */
-    boolean isOnScreenIgnoringKeyguard() {
+    private boolean isOnScreenIgnoringKeyguard() {
         if (!mHasSurface || mDestroying) {
             return false;
         }