Loading core/java/android/window/flags/windowing_frontend.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,16 @@ flag { bug: "232195501" } flag { name: "reset_draw_state_on_client_invisible" namespace: "windowing_frontend" description: "Reset draw state if the client is notified to be invisible" bug: "373023636" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "wait_for_transition_on_display_switch" namespace: "windowing_frontend" Loading services/core/java/com/android/server/wm/ActivityRecord.java +2 −1 Original line number Diff line number Diff line Loading @@ -5508,7 +5508,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A clearAllDrawn(); // Reset the draw state in order to prevent the starting window to be immediately // dismissed when the app still has the surface. if (!isVisible() && !isClientVisible()) { if (!Flags.resetDrawStateOnClientInvisible() && !isVisible() && !isClientVisible()) { forAllWindows(w -> { if (w.mWinAnimator.mDrawState == HAS_DRAWN) { w.mWinAnimator.resetDrawState(); Loading services/core/java/com/android/server/wm/WindowState.java +10 −0 Original line number Diff line number Diff line Loading @@ -3304,6 +3304,16 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP android.os.Process.killProcess(mSession.mPid); } } // Because the client is notified to be invisible, it should no longer be considered as // drawn state. This prevent the app from showing incomplete content if the app is // requested to be visible in a short time (e.g. before activity stopped). if (Flags.resetDrawStateOnClientInvisible() && !clientVisible && mActivityRecord != null && mWinAnimator.mDrawState == HAS_DRAWN) { mWinAnimator.resetDrawState(); // Make sure the app can report drawn if it becomes visible again. forceReportingResized(); } } void onStartFreezingScreen() { Loading services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +15 −6 Original line number Diff line number Diff line Loading @@ -3214,23 +3214,32 @@ public class ActivityRecordTests extends WindowTestsBase { assertFalse(activity.mDisplayContent.mClosingApps.contains(activity)); } @SetupWindows(addWindows = W_ACTIVITY) @Test public void testSetVisibility_visibleToInvisible() { final ActivityRecord activity = new ActivityBuilder(mAtm) .setCreateTask(true).build(); final TestTransitionPlayer player = registerTestTransitionPlayer(); final ActivityRecord activity = mAppWindow.mActivityRecord; makeWindowVisibleAndDrawn(mAppWindow); // By default, activity is visible. assertTrue(activity.isVisible()); assertTrue(activity.isVisibleRequested()); assertFalse(activity.mDisplayContent.mClosingApps.contains(activity)); assertTrue(mAppWindow.isDrawn()); assertFalse(mAppWindow.setReportResizeHints()); // Request the activity to be invisible. Since the visibility changes, app transition // animation should be applied on this activity. mDisplayContent.prepareAppTransition(0); activity.mTransitionController.requestCloseTransitionIfNeeded(activity); activity.setVisibility(false); assertTrue(activity.isVisible()); assertFalse(activity.isVisibleRequested()); assertFalse(activity.mDisplayContent.mOpeningApps.contains(activity)); assertTrue(activity.mDisplayContent.mClosingApps.contains(activity)); player.start(); mSetFlagsRule.enableFlags(Flags.FLAG_RESET_DRAW_STATE_ON_CLIENT_INVISIBLE); // ActivityRecord#commitVisibility(false) -> WindowState#sendAppVisibilityToClients(). player.finish(); assertFalse(activity.isVisible()); assertFalse("Reset draw state after committing invisible", mAppWindow.isDrawn()); assertTrue("Set pending redraw hint", mAppWindow.setReportResizeHints()); } @Test Loading Loading
core/java/android/window/flags/windowing_frontend.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,16 @@ flag { bug: "232195501" } flag { name: "reset_draw_state_on_client_invisible" namespace: "windowing_frontend" description: "Reset draw state if the client is notified to be invisible" bug: "373023636" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "wait_for_transition_on_display_switch" namespace: "windowing_frontend" Loading
services/core/java/com/android/server/wm/ActivityRecord.java +2 −1 Original line number Diff line number Diff line Loading @@ -5508,7 +5508,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A clearAllDrawn(); // Reset the draw state in order to prevent the starting window to be immediately // dismissed when the app still has the surface. if (!isVisible() && !isClientVisible()) { if (!Flags.resetDrawStateOnClientInvisible() && !isVisible() && !isClientVisible()) { forAllWindows(w -> { if (w.mWinAnimator.mDrawState == HAS_DRAWN) { w.mWinAnimator.resetDrawState(); Loading
services/core/java/com/android/server/wm/WindowState.java +10 −0 Original line number Diff line number Diff line Loading @@ -3304,6 +3304,16 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP android.os.Process.killProcess(mSession.mPid); } } // Because the client is notified to be invisible, it should no longer be considered as // drawn state. This prevent the app from showing incomplete content if the app is // requested to be visible in a short time (e.g. before activity stopped). if (Flags.resetDrawStateOnClientInvisible() && !clientVisible && mActivityRecord != null && mWinAnimator.mDrawState == HAS_DRAWN) { mWinAnimator.resetDrawState(); // Make sure the app can report drawn if it becomes visible again. forceReportingResized(); } } void onStartFreezingScreen() { Loading
services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +15 −6 Original line number Diff line number Diff line Loading @@ -3214,23 +3214,32 @@ public class ActivityRecordTests extends WindowTestsBase { assertFalse(activity.mDisplayContent.mClosingApps.contains(activity)); } @SetupWindows(addWindows = W_ACTIVITY) @Test public void testSetVisibility_visibleToInvisible() { final ActivityRecord activity = new ActivityBuilder(mAtm) .setCreateTask(true).build(); final TestTransitionPlayer player = registerTestTransitionPlayer(); final ActivityRecord activity = mAppWindow.mActivityRecord; makeWindowVisibleAndDrawn(mAppWindow); // By default, activity is visible. assertTrue(activity.isVisible()); assertTrue(activity.isVisibleRequested()); assertFalse(activity.mDisplayContent.mClosingApps.contains(activity)); assertTrue(mAppWindow.isDrawn()); assertFalse(mAppWindow.setReportResizeHints()); // Request the activity to be invisible. Since the visibility changes, app transition // animation should be applied on this activity. mDisplayContent.prepareAppTransition(0); activity.mTransitionController.requestCloseTransitionIfNeeded(activity); activity.setVisibility(false); assertTrue(activity.isVisible()); assertFalse(activity.isVisibleRequested()); assertFalse(activity.mDisplayContent.mOpeningApps.contains(activity)); assertTrue(activity.mDisplayContent.mClosingApps.contains(activity)); player.start(); mSetFlagsRule.enableFlags(Flags.FLAG_RESET_DRAW_STATE_ON_CLIENT_INVISIBLE); // ActivityRecord#commitVisibility(false) -> WindowState#sendAppVisibilityToClients(). player.finish(); assertFalse(activity.isVisible()); assertFalse("Reset draw state after committing invisible", mAppWindow.isDrawn()); assertTrue("Set pending redraw hint", mAppWindow.setReportResizeHints()); } @Test Loading