diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index a01113b26a1e019aecbc86194c88edfa8963fc49..9fa5ed2cfde97a45bc2716c810739b94d03df752 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -4030,6 +4030,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
         if (mAppStopped) {
             abortAndClearOptionsAnimation();
         }
+        if (mDisplayContent != null) {
+            mDisplayContent.mUnknownAppVisibilityController.appRemovedOrHidden(this);
+        }
     }
 
     boolean isFinishing() {
@@ -5388,12 +5391,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
         mLastDeferHidingClient = deferHidingClient;
 
         if (!visible) {
-            // If this activity is about to finish/stopped and now becomes invisible, remove it
-            // from the unknownApp list in case the activity does not want to draw anything, which
-            // keep the user waiting for the next transition to start.
-            if (finishing || isState(STOPPED)) {
-                displayContent.mUnknownAppVisibilityController.appRemovedOrHidden(this);
-            }
             // Because starting window was transferred, this activity may be a trampoline which has
             // been occluded by next activity. If it has added windows, set client visibility
             // immediately to avoid the client getting RELAYOUT_RES_FIRST_TIME from relayout and
@@ -5837,6 +5834,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                 break;
             case STOPPED:
                 mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_STOPPED);
+                if (mDisplayContent != null) {
+                    mDisplayContent.mUnknownAppVisibilityController.appRemovedOrHidden(this);
+                }
                 break;
             case DESTROYED:
                 if (app != null && (mVisible || mVisibleRequested)) {
@@ -6517,7 +6517,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
         }
         // Reset the last saved PiP snap fraction on app stop.
         mDisplayContent.mPinnedTaskController.onActivityHidden(mActivityComponent);
-        mDisplayContent.mUnknownAppVisibilityController.appRemovedOrHidden(this);
         if (isClientVisible()) {
             // Though this is usually unlikely to happen, still make sure the client is invisible.
             setClientVisible(false);
diff --git a/services/core/java/com/android/server/wm/BLASTSyncEngine.java b/services/core/java/com/android/server/wm/BLASTSyncEngine.java
index 444470952c5dcbdf7ab98fe6db3fba7aa16b8820..c79a8b6b13a167bad426e6aa88399acd5359cda3 100644
--- a/services/core/java/com/android/server/wm/BLASTSyncEngine.java
+++ b/services/core/java/com/android/server/wm/BLASTSyncEngine.java
@@ -378,8 +378,23 @@ class BLASTSyncEngine {
                 if (!wc.isSyncFinished(this)) {
                     allFinished = false;
                     Slog.i(TAG, "Unfinished container: " + wc);
+                    wc.forAllActivities(a -> {
+                        if (a.isVisibleRequested()) {
+                            if (a.isRelaunching()) {
+                                Slog.i(TAG, "  " + a + " is relaunching");
+                            }
+                            a.forAllWindows(w -> {
+                                Slog.i(TAG, "  " + w + " " + w.mWinAnimator.drawStateToString());
+                            }, true /* traverseTopToBottom */);
+                        } else if (a.mDisplayContent != null && !a.mDisplayContent
+                                .mUnknownAppVisibilityController.allResolved()) {
+                            Slog.i(TAG, "  UnknownAppVisibility: " + a.mDisplayContent
+                                    .mUnknownAppVisibilityController.getDebugMessage());
+                        }
+                    });
                 }
             }
+
             for (int i = mDependencies.size() - 1; i >= 0; --i) {
                 allFinished = false;
                 Slog.i(TAG, "Unfinished dependency: " + mDependencies.get(i).mSyncId);
diff --git a/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java b/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java
index 41c1e793dd90181b494690d4fca86ba1d9e4200d..c0713966d8de80d6d9b2a369e8cc7cc216a576a8 100644
--- a/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java
+++ b/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java
@@ -70,6 +70,9 @@ class UnknownAppVisibilityController {
     }
 
     boolean isVisibilityUnknown(ActivityRecord r) {
+        if (mUnknownApps.isEmpty()) {
+            return false;
+        }
         return mUnknownApps.containsKey(r);
     }
 
@@ -90,6 +93,9 @@ class UnknownAppVisibilityController {
     }
 
     void appRemovedOrHidden(@NonNull ActivityRecord activity) {
+        if (mUnknownApps.isEmpty()) {
+            return;
+        }
         if (DEBUG_UNKNOWN_APP_VISIBILITY) {
             Slog.d(TAG, "App removed or hidden activity=" + activity);
         }
@@ -117,8 +123,11 @@ class UnknownAppVisibilityController {
      * Notifies that {@param activity} has finished resuming.
      */
     void notifyAppResumedFinished(@NonNull ActivityRecord activity) {
-        if (mUnknownApps.containsKey(activity)
-                && mUnknownApps.get(activity) == UNKNOWN_STATE_WAITING_RESUME) {
+        if (mUnknownApps.isEmpty()) {
+            return;
+        }
+        final Integer state = mUnknownApps.get(activity);
+        if (state != null && state == UNKNOWN_STATE_WAITING_RESUME) {
             if (DEBUG_UNKNOWN_APP_VISIBILITY) {
                 Slog.d(TAG, "App resume finished activity=" + activity);
             }
@@ -130,13 +139,16 @@ class UnknownAppVisibilityController {
      * Notifies that {@param activity} has relaid out.
      */
     void notifyRelayouted(@NonNull ActivityRecord activity) {
-        if (!mUnknownApps.containsKey(activity)) {
+        if (mUnknownApps.isEmpty()) {
+            return;
+        }
+        final Integer state = mUnknownApps.get(activity);
+        if (state == null) {
             return;
         }
         if (DEBUG_UNKNOWN_APP_VISIBILITY) {
             Slog.d(TAG, "App relayouted appWindow=" + activity);
         }
-        int state = mUnknownApps.get(activity);
         if (state == UNKNOWN_STATE_WAITING_RELAYOUT || activity.mStartingWindow != null) {
             mUnknownApps.put(activity, UNKNOWN_STATE_WAITING_VISIBILITY_UPDATE);
             mDisplayContent.notifyKeyguardFlagsChanged();
diff --git a/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
index 75a8dd822914b6c3266ce713f8ae4bbca3e55fb1..085eddd2e73d808459a108441919d98fe7e8ef8d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 import android.platform.test.annotations.Presubmit;
@@ -94,10 +95,14 @@ public class UnknownAppVisibilityControllerTest extends WindowTestsBase {
     public void testRemoveFinishingInvisibleActivityFromUnknown() {
         final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true).build();
         mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(activity);
-        activity.finishing = true;
-        activity.setVisibleRequested(true);
-        activity.setVisibility(false);
+        assertFalse(mDisplayContent.mUnknownAppVisibilityController.allResolved());
+        activity.makeFinishingLocked();
         assertTrue(mDisplayContent.mUnknownAppVisibilityController.allResolved());
+
+        mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(activity);
+        assertTrue(mDisplayContent.mUnknownAppVisibilityController.isVisibilityUnknown(activity));
+        activity.setState(ActivityRecord.State.STOPPED, "test");
+        assertFalse(mDisplayContent.mUnknownAppVisibilityController.isVisibilityUnknown(activity));
     }
 
     @Test