Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3bcc3950 authored by Jerry Chang's avatar Jerry Chang
Browse files

Fix Launcher being occluded during rotate transition

I1177b1ef removed independent checks and reparent all transition-leashes
to root leash. Which result to wrong z-order setup during rotation
transition because it also reparents task display area transition-leash
to root leash.

This brings back independent change checks and overrides root task
targets with corresponding child task info. This is needed because
Launcher monitors leaf task id to perform recent apps transition.
Otherwise child task targets might get transformed twice with the flow
like RecentsView#redrawLiveTile.

Bug: 206487881
Test: close landscape app to portrait home, observed Launcher stays on
      top of wallpaper during transition.
Test: swipe up split pair to recent apps panel transformes thumbnail
      pair properly.

Change-Id: I234e329c40938cec7e35a62dc51d00cdf2e84b0b
parent d73fb507
Loading
Loading
Loading
Loading
+51 −11
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.shared.system;

import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_BACK;
@@ -31,6 +32,7 @@ import android.app.WindowConfiguration;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.ArrayMap;
import android.util.SparseArray;
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
import android.view.WindowManager;
@@ -55,7 +57,7 @@ public class RemoteAnimationTargetCompat {
    public static final int ACTIVITY_TYPE_ASSISTANT = WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
    public final int activityType;

    public final int taskId;
    public int taskId;
    public final SurfaceControl leash;
    public final boolean isTranslucent;
    public final Rect clipRect;
@@ -67,7 +69,7 @@ public class RemoteAnimationTargetCompat {
    public final Rect startScreenSpaceBounds;
    public final boolean isNotInRecents;
    public final Rect contentInsets;
    public final ActivityManager.RunningTaskInfo taskInfo;
    public ActivityManager.RunningTaskInfo taskInfo;
    public final boolean allowEnterPip;
    public final int rotationChange;
    public final int windowType;
@@ -139,12 +141,21 @@ public class RemoteAnimationTargetCompat {
        // changes should be ordered top-to-bottom in z
        final int mode = change.getMode();

        // Launcher animates leaf tasks directly, so always reparent all task leashes to root leash.
        // Don't move anything that isn't independent within its parents
        if (!TransitionInfo.isIndependent(change, info)) {
            if (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT || mode == TRANSIT_CHANGE) {
                t.setPosition(leash, change.getEndRelOffset().x, change.getEndRelOffset().y);
            }
            return;
        }

        final boolean hasParent = change.getParent() != null;

        if (!hasParent) {
            t.reparent(leash, info.getRootLeash());
            t.setPosition(leash, change.getStartAbsBounds().left - info.getRootOffset().x,
                    change.getStartAbsBounds().top - info.getRootOffset().y);

        t.show(leash);
        }
        // Put all the OPEN/SHOW on top
        if (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT) {
            if (isOpening) {
@@ -181,8 +192,12 @@ public class RemoteAnimationTargetCompat {
        }
        SurfaceControl leashSurface = new SurfaceControl.Builder()
                .setName(change.getLeash().toString() + "_transition-leash")
                .setContainerLayer().setParent(change.getParent() == null ? info.getRootLeash()
                        : info.getChange(change.getParent()).getLeash()).build();
                .setContainerLayer()
                // Initial the surface visible to respect the visibility of the original surface.
                .setHidden(false)
                .setParent(change.getParent() == null ? info.getRootLeash()
                        : info.getChange(change.getParent()).getLeash())
                .build();
        // Copied Transitions setup code (which expects bottom-to-top order, so we swap here)
        setupLeash(leashSurface, change, info.getChanges().size() - order, info, t);
        t.reparent(change.getLeash(), leashSurface);
@@ -253,17 +268,42 @@ public class RemoteAnimationTargetCompat {
    public static RemoteAnimationTargetCompat[] wrap(TransitionInfo info, boolean wallpapers,
            SurfaceControl.Transaction t, ArrayMap<SurfaceControl, SurfaceControl> leashMap) {
        final ArrayList<RemoteAnimationTargetCompat> out = new ArrayList<>();
        final SparseArray<RemoteAnimationTargetCompat> childTaskTargets = new SparseArray<>();
        for (int i = 0; i < info.getChanges().size(); i++) {
            final TransitionInfo.Change change = info.getChanges().get(i);
            final boolean changeIsWallpaper =
                    (change.getFlags() & TransitionInfo.FLAG_IS_WALLPAPER) != 0;
            if (wallpapers != changeIsWallpaper) continue;

            out.add(new RemoteAnimationTargetCompat(change, info.getChanges().size() - i, info, t));
            final RemoteAnimationTargetCompat targetCompat =
                    new RemoteAnimationTargetCompat(change, info.getChanges().size() - i, info, t);
            if (leashMap != null) {
                leashMap.put(change.getLeash(), out.get(out.size() - 1).leash);
                leashMap.put(change.getLeash(), targetCompat.leash);
            }
            final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
            if (taskInfo != null) {
                if (taskInfo.parentTaskId != -1) {
                    // Cache child task targets to override its parent target later and exclude
                    // child task while wrapping up animate targets. Otherwise the child task might
                    // get transformed twice with the flow like RecentsView#redrawLiveTile.
                    childTaskTargets.put(taskInfo.parentTaskId, targetCompat);
                    continue;
                }

                final RemoteAnimationTargetCompat childTaskTarget =
                        childTaskTargets.get(taskInfo.taskId);
                if (childTaskTarget != null) {
                    // Launcher monitors leaf tasks to perform animation, hence override the parent
                    // task target with child task info so Launcher can locate and animate root
                    // surface directly with leaf task information.
                    targetCompat.taskInfo = childTaskTarget.taskInfo;
                    targetCompat.taskId = childTaskTarget.taskId;
                }
            }

            out.add(targetCompat);
        }

        return out.toArray(new RemoteAnimationTargetCompat[out.size()]);
    }