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

Commit 3be325fb authored by Maryam Dehaini's avatar Maryam Dehaini Committed by Android (Google) Code Review
Browse files

Merge "Block relayout during transition to desktop" into udc-dev

parents fa17e75b 1ed33484
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -153,6 +153,8 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs

    @Override
    public void onTransitionMerged(@NonNull IBinder merged, @NonNull IBinder playing) {
        mWindowDecorViewModel.onTransitionMerged(merged, playing);

        final List<ActivityManager.RunningTaskInfo> infoOfMerged =
                mTransitionToTaskInfo.get(merged);
        if (infoOfMerged == null) {
@@ -169,8 +171,6 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs
        } else {
            mTransitionToTaskInfo.put(playing, infoOfMerged);
        }

        mWindowDecorViewModel.onTransitionMerged(merged, playing);
    }

    @Override
+23 −23
Original line number Diff line number Diff line
@@ -113,11 +113,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
    private boolean mDragToDesktopAnimationStarted;
    private float mCaptionDragStartX;

    // These values keep track of any transitions to freeform to stop relayout from running on
    // changing task so that shellTransitions has a chance to animate the transition
    private int mPauseRelayoutForTask = -1;
    private IBinder mTransitionPausingRelayout;

    public DesktopModeWindowDecorViewModel(
            Context context,
            Handler mainHandler,
@@ -195,22 +190,25 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
            @NonNull TransitionInfo info,
            @NonNull TransitionInfo.Change change) {
        if (change.getMode() == WindowManager.TRANSIT_CHANGE
                && info.getType() == Transitions.TRANSIT_ENTER_DESKTOP_MODE) {
            mTransitionPausingRelayout = transition;
                && (info.getType() == Transitions.TRANSIT_ENTER_DESKTOP_MODE)) {
            mWindowDecorByTaskId.get(change.getTaskInfo().taskId)
                    .addTransitionPausingRelayout(transition);
        }
    }

    @Override
    public void onTransitionMerged(@NonNull IBinder merged, @NonNull IBinder playing) {
        if (merged.equals(mTransitionPausingRelayout)) {
            mTransitionPausingRelayout = playing;
        for (int i = 0; i < mWindowDecorByTaskId.size(); i++) {
            final DesktopModeWindowDecoration decor = mWindowDecorByTaskId.valueAt(i);
            decor.mergeTransitionPausingRelayout(merged, playing);
        }
    }

    @Override
    public void onTransitionFinished(@NonNull IBinder transition) {
        if (transition.equals(mTransitionPausingRelayout)) {
            mPauseRelayoutForTask = -1;
        for (int i = 0; i < mWindowDecorByTaskId.size(); i++) {
            final DesktopModeWindowDecoration decor = mWindowDecorByTaskId.valueAt(i);
            decor.removeTransitionPausingRelayout(transition);
        }
    }

@@ -225,13 +223,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
            incrementEventReceiverTasks(taskInfo.displayId);
        }

        // TaskListener callbacks and shell transitions aren't synchronized, so starting a shell
        // transition can trigger an onTaskInfoChanged call that updates the task's SurfaceControl
        // and interferes with the transition animation that is playing at the same time.
        if (taskInfo.taskId != mPauseRelayoutForTask) {
        decoration.relayout(taskInfo);
    }
    }

    @Override
    public void onTaskChanging(
@@ -555,8 +548,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
                            relevantDecor.mTaskInfo.displayId);
                    if (ev.getY() > 2 * statusBarHeight) {
                        if (DesktopModeStatus.isProto2Enabled()) {
                            mPauseRelayoutForTask = relevantDecor.mTaskInfo.taskId;
                            centerAndMoveToDesktopWithAnimation(relevantDecor, ev);
                            animateToDesktop(relevantDecor, ev);
                        } else if (DesktopModeStatus.isProto1Enabled()) {
                            mDesktopModeController.ifPresent(c -> c.setDesktopModeActive(true));
                        }
@@ -631,6 +623,15 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
        return endBounds;
    }

    /**
     * Blocks relayout until transition is finished and transitions to Desktop
     */
    private void animateToDesktop(DesktopModeWindowDecoration relevantDecor,
            MotionEvent ev) {
        relevantDecor.incrementRelayoutBlock();
        centerAndMoveToDesktopWithAnimation(relevantDecor, ev);
    }

    /**
     * Animates a window to the center, grows to freeform size, and transitions to Desktop Mode.
     * @param relevantDecor the window decor of the task to be animated
@@ -658,9 +659,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                mDesktopTasksController.ifPresent(
                        c -> c.onDragPositioningEndThroughStatusBar(
                                relevantDecor.mTaskInfo,
                mDesktopTasksController.ifPresent(c ->
                        c.onDragPositioningEndThroughStatusBar(relevantDecor.mTaskInfo,
                            calculateFreeformBounds(FINAL_FREEFORM_SCALE)));
            }
        });
+48 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.view.Choreographer;
import android.view.MotionEvent;
@@ -49,6 +50,9 @@ import com.android.wm.shell.windowdecor.viewholder.DesktopModeAppControlsWindowD
import com.android.wm.shell.windowdecor.viewholder.DesktopModeFocusedWindowDecorationViewHolder;
import com.android.wm.shell.windowdecor.viewholder.DesktopModeWindowDecorationViewHolder;

import java.util.HashSet;
import java.util.Set;

/**
 * Defines visuals and behaviors of a window decoration of a caption bar and shadows. It works with
 * {@link DesktopModeWindowDecorViewModel}.
@@ -83,6 +87,9 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin

    private TaskCornersListener mCornersListener;

    private final Set<IBinder> mTransitionsPausingRelayout = new HashSet<>();
    private int mRelayoutBlock;

    DesktopModeWindowDecoration(
            Context context,
            DisplayController displayController,
@@ -134,6 +141,13 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin

    @Override
    void relayout(ActivityManager.RunningTaskInfo taskInfo) {
        // TaskListener callbacks and shell transitions aren't synchronized, so starting a shell
        // transition can trigger an onTaskInfoChanged call that updates the task's SurfaceControl
        // and interferes with the transition animation that is playing at the same time.
        if (mRelayoutBlock > 0) {
            return;
        }

        final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
        // Use |applyStartTransactionOnDraw| so that the transaction (that applies task crop) is
        // synced with the buffer transaction (that draws the View). Both will be shown on screen
@@ -455,6 +469,40 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
        return cornersRegion;
    }

    /**
     * If transition exists in mTransitionsPausingRelayout, remove the transition and decrement
     * mRelayoutBlock
     */
    void removeTransitionPausingRelayout(IBinder transition) {
        if (mTransitionsPausingRelayout.remove(transition)) {
            mRelayoutBlock--;
        }
    }

    /**
     * Add transition to mTransitionsPausingRelayout
     */
    void addTransitionPausingRelayout(IBinder transition) {
        mTransitionsPausingRelayout.add(transition);
    }

    /**
     * If two transitions merge and the merged transition is in mTransitionsPausingRelayout,
     * remove the merged transition from the set and add the transition it was merged into.
     */
    public void mergeTransitionPausingRelayout(IBinder merged, IBinder playing) {
        if (mTransitionsPausingRelayout.remove(merged)) {
            mTransitionsPausingRelayout.add(playing);
        }
    }

    /**
     * Increase mRelayoutBlock, stopping relayout if mRelayoutBlock is now greater than 0.
     */
    public void incrementRelayoutBlock() {
        mRelayoutBlock++;
    }

    static class Factory {

        DesktopModeWindowDecoration create(