From 7ac304d09a0513dd3583eb072423339932ac3e70 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Wed, 31 Mar 2021 17:55:18 +0800 Subject: [PATCH] Use last reported configuration for apps that are going-away This aligns the same condition as commit e3f5afa and a841c15 in WindowState#reportResized. Otherwise the app may get inconsistent configuration. For example, switching activities from one with show-when-locked to another one without the flag with a secured lock and orientation change. The starting activity needs to resume and relayout (mClientVisible) once, but its visible-requested has been updated to false because lockscreen is still showing. Then the app becomes out of sync with ActivityRecord#mLastReportedConfiguration. Bug: 183889107 Test: 1. Enable secured lock. 2. Launch a landscape show-when-locked activity. 3. Off/on screen to enter lockscreen. 4. Press home key and unlock. Launcher should not get landscape configuration. Change-Id: I19af6cf7f9a4a27fbc987d920630e2de95ced602 --- .../server/wm/WindowManagerService.java | 3 ++- .../com/android/server/wm/WindowState.java | 25 ++++++++++++------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index a670b390cb947..c23cc2e709c0d 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2468,7 +2468,8 @@ public class WindowManagerService extends IWindowManager.Stub // to the client erroneously accepting a configuration that would have otherwise caused // an activity restart. We instead hand back the last reported // {@link MergedConfiguration}. - if (shouldRelayout) { + if (shouldRelayout && (!win.shouldCheckTokenVisibleRequested() + || win.mToken.isVisibleRequested())) { win.getMergedConfiguration(mergedConfiguration); } else { win.getLastReportedMergedConfiguration(mergedConfiguration); diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 92c95221f102a..171e93fb4df9c 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -186,6 +186,7 @@ import static com.android.server.wm.WindowStateProto.WINDOW_CONTAINER; import static com.android.server.wm.WindowStateProto.WINDOW_FRAMES; import android.annotation.CallSuper; +import android.annotation.NonNull; import android.annotation.Nullable; import android.app.AppOpsManager; import android.app.admin.DevicePolicyCache; @@ -298,7 +299,7 @@ class WindowState extends WindowContainer implements WindowManagerP /** The owner has {@link android.Manifest.permission#INTERNAL_SYSTEM_WINDOW} */ final boolean mOwnerCanAddInternalSystemWindow; final WindowId mWindowId; - WindowToken mToken; + @NonNull WindowToken mToken; // The same object as mToken if this is an app window and null for non-app windows. ActivityRecord mActivityRecord; @@ -1814,13 +1815,22 @@ class WindowState extends WindowContainer implements WindowManagerP @Override boolean isVisibleRequested() { - if (mToken != null && (mActivityRecord != null || mToken.asWallpaperToken() != null)) { - // Currently only ActivityRecord and WallpaperToken support visibleRequested. + if (shouldCheckTokenVisibleRequested()) { return isVisible() && mToken.isVisibleRequested(); } return isVisible(); } + /** + * Returns {@code true} if {@link WindowToken#isVisibleRequested()} should be considered + * before dispatching the latest configuration. Currently only {@link + * ActivityRecord#isVisibleRequested()} and {@link WallpaperWindowToken#isVisibleRequested()} + * implement explicit visible-requested. + */ + boolean shouldCheckTokenVisibleRequested() { + return mActivityRecord != null || mToken.asWallpaperToken() != null; + } + /** * Ensures that all the policy visibility bits are set. * @return {@code true} if all flags about visiblity are set @@ -1851,7 +1861,7 @@ class WindowState extends WindowContainer implements WindowManagerP if (!mHasSurface || isParentWindowHidden() || mAnimatingExit || mDestroying) { return false; } - final boolean isWallpaper = mToken != null && mToken.asWallpaperToken() != null; + final boolean isWallpaper = mToken.asWallpaperToken() != null; return !isWallpaper || mToken.isVisible(); } @@ -2053,7 +2063,7 @@ class WindowState extends WindowContainer implements WindowManagerP // When there is keyguard, wallpaper could be placed over the secure app // window but invisible. We need to check wallpaper visibility explicitly // to determine if it's occluding apps. - final boolean isWallpaper = mToken != null && mToken.asWallpaperToken() != null; + final boolean isWallpaper = mToken.asWallpaperToken() != null; return ((!isWallpaper && mAttrs.format == PixelFormat.OPAQUE) || (isWallpaper && mToken.isVisible())) && isDrawn() && !isAnimating(TRANSITION | PARENTS); @@ -3340,8 +3350,6 @@ class WindowState extends WindowContainer implements WindowManagerP void sendAppVisibilityToClients() { super.sendAppVisibilityToClients(); - if (mToken == null) return; - final boolean clientVisible = mToken.isClientVisible(); // TODO(shell-transitions): This is currently only applicable to app windows, BUT we // want to extend the "starting" concept to other windows. @@ -3734,8 +3742,7 @@ class WindowState extends WindowContainer implements WindowManagerP // If this is an activity or wallpaper and is invisible or going invisible, don't report // either since it is going away. This is likely during a transition so we want to preserve // the original state. - if ((mActivityRecord != null || mToken.asWallpaperToken() != null) - && !mToken.isVisibleRequested()) { + if (shouldCheckTokenVisibleRequested() && !mToken.isVisibleRequested()) { return; }