Move starting window dim layers behind the activity window layers
- Currently, the dim layer is shown directly behind the requested window,
which for translucent snapshot starting windows can cause the dim layer
to show above the app window which is animating behind the starting
window. Instead, when applying the dim layer to the starting window,
override the layer to be behind the last window layer for the activity
that the starting window represents.
- Also fix issue where the dim amount was not being copied for the snapshot
starting window.
Bug: 63076430
Test: Launch assistant from Recents
Change-Id: I1f031e517a51ef7e1d6243b792c69997e10ea5b2
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 8afc4fd..ad3ad508 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -1573,6 +1573,17 @@
return null;
}
+ int getLowestAnimLayer() {
+ for (int i = 0; i < mChildren.size(); i++) {
+ final WindowState w = mChildren.get(i);
+ if (w.mRemoved) {
+ continue;
+ }
+ return w.mWinAnimator.mAnimLayer;
+ }
+ return Integer.MAX_VALUE;
+ }
+
WindowState getHighestAnimLayerWindow(WindowState currentTarget) {
WindowState candidate = null;
for (int i = mChildren.indexOf(currentTarget); i >= 0; i--) {
diff --git a/services/core/java/com/android/server/wm/DimLayer.java b/services/core/java/com/android/server/wm/DimLayer.java
index 015c084..708973d 100644
--- a/services/core/java/com/android/server/wm/DimLayer.java
+++ b/services/core/java/com/android/server/wm/DimLayer.java
@@ -81,6 +81,12 @@
boolean isAttachedToDisplay();
/** Gets the bounds of the dim layer user. */
void getDimBounds(Rect outBounds);
+ /** Returns the layer to place a dim layer. */
+ default int getLayerForDim(WindowStateAnimator animator, int layerOffset,
+ int defaultLayer) {
+ return defaultLayer;
+ }
+
String toShortString();
}
/** The user of this dim layer. */
diff --git a/services/core/java/com/android/server/wm/DimLayerController.java b/services/core/java/com/android/server/wm/DimLayerController.java
index d44cd13..49f5ee6 100644
--- a/services/core/java/com/android/server/wm/DimLayerController.java
+++ b/services/core/java/com/android/server/wm/DimLayerController.java
@@ -261,7 +261,8 @@
dimLayer = state.animator.mAnimLayer + LAYER_OFFSET_DIM;
dimAmount = DEFAULT_DIM_AMOUNT_DEAD_WINDOW;
} else {
- dimLayer = state.animator.mAnimLayer - LAYER_OFFSET_DIM;
+ dimLayer = dimLayerUser.getLayerForDim(state.animator, LAYER_OFFSET_DIM,
+ state.animator.mAnimLayer - LAYER_OFFSET_DIM);
dimAmount = state.animator.mWin.mAttrs.dimAmount;
}
}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index bfebca8..cc3b146 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -23,6 +23,8 @@
import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY;
import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+
import static com.android.server.EventLogTags.WM_TASK_REMOVED;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -39,6 +41,7 @@
import android.view.Surface;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.wm.DimLayer.DimLayerUser;
import java.io.PrintWriter;
import java.util.function.Consumer;
@@ -637,6 +640,18 @@
return isFullscreen();
}
+ @Override
+ public int getLayerForDim(WindowStateAnimator animator, int layerOffset, int defaultLayer) {
+ // If the dim layer is for a starting window, move the dim layer back in the z-order behind
+ // the lowest activity window to ensure it does not occlude the main window if it is
+ // translucent
+ final AppWindowToken appToken = animator.mWin.mAppToken;
+ if (animator.mAttrType == TYPE_APPLICATION_STARTING && hasChild(appToken) ) {
+ return Math.min(defaultLayer, appToken.getLowestAnimLayer() - layerOffset);
+ }
+ return defaultLayer;
+ }
+
boolean isFullscreen() {
if (useCurrentBounds()) {
return mFillsParent;
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
index a96d224..469dab4 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
@@ -20,6 +20,7 @@
import static android.graphics.Color.alpha;
import static android.view.SurfaceControl.HIDDEN;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
import static android.view.WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES;
import static android.view.WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE;
@@ -159,6 +160,7 @@
windowFlags = mainWindow.getAttrs().flags;
windowPrivateFlags = mainWindow.getAttrs().privateFlags;
+ layoutParams.dimAmount = mainWindow.getAttrs().dimAmount;
layoutParams.type = TYPE_APPLICATION_STARTING;
layoutParams.format = snapshot.getSnapshot().getFormat();
layoutParams.flags = (windowFlags & ~FLAG_INHERIT_EXCLUDES)