Loading services/core/java/com/android/server/wm/ActivityRecord.java +6 −7 Original line number Diff line number Diff line Loading @@ -4030,6 +4030,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (mAppStopped) { abortAndClearOptionsAnimation(); } if (mDisplayContent != null) { mDisplayContent.mUnknownAppVisibilityController.appRemovedOrHidden(this); } } boolean isFinishing() { Loading Loading @@ -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 Loading Loading @@ -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)) { Loading Loading @@ -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); Loading services/core/java/com/android/server/wm/BLASTSyncEngine.java +15 −0 Original line number Diff line number Diff line Loading @@ -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); Loading services/core/java/com/android/server/wm/UnknownAppVisibilityController.java +16 −4 Original line number Diff line number Diff line Loading @@ -70,6 +70,9 @@ class UnknownAppVisibilityController { } boolean isVisibilityUnknown(ActivityRecord r) { if (mUnknownApps.isEmpty()) { return false; } return mUnknownApps.containsKey(r); } Loading @@ -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); } Loading Loading @@ -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); } Loading @@ -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(); Loading services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java +8 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading Loading
services/core/java/com/android/server/wm/ActivityRecord.java +6 −7 Original line number Diff line number Diff line Loading @@ -4030,6 +4030,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (mAppStopped) { abortAndClearOptionsAnimation(); } if (mDisplayContent != null) { mDisplayContent.mUnknownAppVisibilityController.appRemovedOrHidden(this); } } boolean isFinishing() { Loading Loading @@ -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 Loading Loading @@ -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)) { Loading Loading @@ -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); Loading
services/core/java/com/android/server/wm/BLASTSyncEngine.java +15 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
services/core/java/com/android/server/wm/UnknownAppVisibilityController.java +16 −4 Original line number Diff line number Diff line Loading @@ -70,6 +70,9 @@ class UnknownAppVisibilityController { } boolean isVisibilityUnknown(ActivityRecord r) { if (mUnknownApps.isEmpty()) { return false; } return mUnknownApps.containsKey(r); } Loading @@ -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); } Loading Loading @@ -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); } Loading @@ -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(); Loading
services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java +8 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading