summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Riddle Hsu <riddlehsu@google.com> 2024-10-21 02:20:39 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-10-21 02:20:39 +0000
commitacfb66a3203298f73e399246ee08e07571f82f11 (patch)
tree42faa7f6d8037f8181a1e8adcfc8b98b9bdc2e50
parentf58acb9fba7c87034dee6f6f65f26aea6b322148 (diff)
parent92ff7c75e4fed791a51202f95541ab62791136fe (diff)
Merge "Reset draw state after notifying invisible to activity window" into main
-rw-r--r--core/java/android/window/flags/windowing_frontend.aconfig10
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java3
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java10
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java21
4 files changed, 37 insertions, 7 deletions
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index 0d235ffad9b5..d15f52c39efa 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -9,6 +9,16 @@ flag {
}
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"
description: "Waits for Shell transition to start before unblocking the screen after display switch"
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 460de01a7d1d..d4dccc30b4eb 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -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();
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 76f2437cbc3f..614187682ef4 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -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() {
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 577b02a4ff7a..c30b4bb6f65d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -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