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

Commit 7df1f96d authored by Gustav Sennton's avatar Gustav Sennton
Browse files

Reland "Swipe-up Recents transition: override desktop tasks corner..."

Fix an issue where the corner radius and shadow of Desktop tasks are
incorrectly applied during the Recents swipe-up transition:
Shell and Launcher uses different leashes to control Desktop tasks
during transitions, and there is a bug (b/200300845 ) where applying
different corner radii to several ancestors (with different bounds) of
a single task causes bad results (it's unclear clear what corner radii
is applied, and the task shadow might leak outside an ancestor as well).

With this CL we
1. tell WindowDecoration to avoid updating the corner radius of Desktop
   tasks during Recents transitions, and
2. pass a TransitionInfo object to Launcher during Recents transitions
   to allow Launcher to access the task leashes used by Shell, and
   override the corner radius of the relevant tasks.

Bug: 378657004
Test: manual
Flag: com.android.window.flags.enable_desktop_recents_transitions_corners_bugfix
Change-Id: Ie714406143c0590e0f2f1374d2b64f48a6b9c632
parent 4f783b4e
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -946,7 +946,8 @@ public abstract class WMShellModule {
            FocusTransitionObserver focusTransitionObserver,
            DesktopModeEventLogger desktopModeEventLogger,
            DesktopModeUiEventLogger desktopModeUiEventLogger,
            WindowDecorTaskResourceLoader taskResourceLoader
            WindowDecorTaskResourceLoader taskResourceLoader,
            RecentsTransitionHandler recentsTransitionHandler
    ) {
        if (!DesktopModeStatus.canEnterDesktopModeOrShowAppHandle(context)) {
            return Optional.empty();
@@ -962,7 +963,7 @@ public abstract class WMShellModule {
                desktopTasksLimiter, appHandleEducationController, appToWebEducationController,
                windowDecorCaptionHandleRepository, activityOrientationChangeHandler,
                focusTransitionObserver, desktopModeEventLogger, desktopModeUiEventLogger,
                taskResourceLoader));
                taskResourceLoader, recentsTransitionHandler));
    }

    @WMSingleton
+4 −2
Original line number Diff line number Diff line
@@ -17,9 +17,10 @@
package com.android.wm.shell.recents;

import android.graphics.Rect;
import android.os.Bundle;
import android.view.RemoteAnimationTarget;
import android.window.TaskSnapshot;
import android.os.Bundle;
import android.window.TransitionInfo;

import com.android.wm.shell.recents.IRecentsAnimationController;

@@ -57,7 +58,8 @@ oneway interface IRecentsAnimationRunner {
     */
    void onAnimationStart(in IRecentsAnimationController controller,
            in RemoteAnimationTarget[] apps, in RemoteAnimationTarget[] wallpapers,
            in Rect homeContentInsets, in Rect minimizedHomeBounds, in Bundle extras) = 2;
            in Rect homeContentInsets, in Rect minimizedHomeBounds, in Bundle extras,
            in TransitionInfo info) = 2;

    /**
     * Called when the task of an activity that has been started while the recents animation
+3 −2
Original line number Diff line number Diff line
@@ -587,7 +587,8 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler,
                mListener.onAnimationStart(this,
                        apps.toArray(new RemoteAnimationTarget[apps.size()]),
                        new RemoteAnimationTarget[0],
                        new Rect(0, 0, 0, 0), new Rect(), new Bundle());
                        new Rect(0, 0, 0, 0), new Rect(), new Bundle(),
                        null);
                for (int i = 0; i < mStateListeners.size(); i++) {
                    mStateListeners.get(i).onTransitionStateChanged(TRANSITION_STATE_ANIMATING);
                }
@@ -818,7 +819,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler,
                mListener.onAnimationStart(this,
                        apps.toArray(new RemoteAnimationTarget[apps.size()]),
                        wallpapers.toArray(new RemoteAnimationTarget[wallpapers.size()]),
                        new Rect(0, 0, 0, 0), new Rect(), b);
                        new Rect(0, 0, 0, 0), new Rect(), b, info);
                for (int i = 0; i < mStateListeners.size(); i++) {
                    mStateListeners.get(i).onTransitionStateChanged(TRANSITION_STATE_ANIMATING);
                }
+48 −3
Original line number Diff line number Diff line
@@ -126,6 +126,8 @@ import com.android.wm.shell.desktopmode.common.ToggleTaskSizeUtilsKt;
import com.android.wm.shell.desktopmode.education.AppHandleEducationController;
import com.android.wm.shell.desktopmode.education.AppToWebEducationController;
import com.android.wm.shell.freeform.FreeformTaskTransitionStarter;
import com.android.wm.shell.recents.RecentsTransitionHandler;
import com.android.wm.shell.recents.RecentsTransitionStateListener;
import com.android.wm.shell.shared.FocusTransitionListener;
import com.android.wm.shell.shared.annotations.ShellBackgroundThread;
import com.android.wm.shell.shared.annotations.ShellMainThread;
@@ -157,8 +159,10 @@ import kotlinx.coroutines.MainCoroutineDispatcher;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.Supplier;

/**
@@ -247,6 +251,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
    private final DesktopModeEventLogger mDesktopModeEventLogger;
    private final DesktopModeUiEventLogger mDesktopModeUiEventLogger;
    private final WindowDecorTaskResourceLoader mTaskResourceLoader;
    private final RecentsTransitionHandler mRecentsTransitionHandler;

    public DesktopModeWindowDecorViewModel(
            Context context,
@@ -282,7 +287,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
            FocusTransitionObserver focusTransitionObserver,
            DesktopModeEventLogger desktopModeEventLogger,
            DesktopModeUiEventLogger desktopModeUiEventLogger,
            WindowDecorTaskResourceLoader taskResourceLoader) {
            WindowDecorTaskResourceLoader taskResourceLoader,
            RecentsTransitionHandler recentsTransitionHandler) {
        this(
                context,
                shellExecutor,
@@ -323,7 +329,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
                focusTransitionObserver,
                desktopModeEventLogger,
                desktopModeUiEventLogger,
                taskResourceLoader);
                taskResourceLoader,
                recentsTransitionHandler);
    }

    @VisibleForTesting
@@ -367,7 +374,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
            FocusTransitionObserver focusTransitionObserver,
            DesktopModeEventLogger desktopModeEventLogger,
            DesktopModeUiEventLogger desktopModeUiEventLogger,
            WindowDecorTaskResourceLoader taskResourceLoader) {
            WindowDecorTaskResourceLoader taskResourceLoader,
            RecentsTransitionHandler recentsTransitionHandler) {
        mContext = context;
        mMainExecutor = shellExecutor;
        mMainHandler = mainHandler;
@@ -436,6 +444,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
        mDesktopModeEventLogger = desktopModeEventLogger;
        mDesktopModeUiEventLogger = desktopModeUiEventLogger;
        mTaskResourceLoader = taskResourceLoader;
        mRecentsTransitionHandler = recentsTransitionHandler;

        shellInit.addInitCallback(this::onInit, this);
    }
@@ -450,6 +459,10 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
                new DesktopModeOnTaskResizeAnimationListener());
        mDesktopTasksController.setOnTaskRepositionAnimationListener(
                new DesktopModeOnTaskRepositionAnimationListener());
        if (Flags.enableDesktopRecentsTransitionsCornersBugfix()) {
            mRecentsTransitionHandler.addTransitionStateListener(
                    new DesktopModeRecentsTransitionStateListener());
        }
        mDisplayController.addDisplayChangingController(mOnDisplayChangingListener);
        try {
            mWindowManager.registerSystemGestureExclusionListener(mGestureExclusionListener,
@@ -1859,6 +1872,38 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
        }
    }

    private class DesktopModeRecentsTransitionStateListener
            implements RecentsTransitionStateListener {
        final Set<Integer> mAnimatingTaskIds = new HashSet<>();

        @Override
        public void onTransitionStateChanged(int state) {
            switch (state) {
                case RecentsTransitionStateListener.TRANSITION_STATE_REQUESTED:
                    for (int n = 0; n < mWindowDecorByTaskId.size(); n++) {
                        int taskId = mWindowDecorByTaskId.keyAt(n);
                        mAnimatingTaskIds.add(taskId);
                        setIsRecentsTransitionRunningForTask(taskId, true);
                    }
                    return;
                case RecentsTransitionStateListener.TRANSITION_STATE_NOT_RUNNING:
                    // No Recents transition running - clean up window decorations
                    for (int taskId : mAnimatingTaskIds) {
                        setIsRecentsTransitionRunningForTask(taskId, false);
                    }
                    mAnimatingTaskIds.clear();
                    return;
                default:
            }
        }

        private void setIsRecentsTransitionRunningForTask(int taskId, boolean isRecentsRunning) {
            final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskId);
            if (decoration == null) return;
            decoration.setIsRecentsTransitionRunning(isRecentsRunning);
        }
    }

    private class DragEventListenerImpl
            implements DragPositioningCallbackUtility.DragEventListener {
        @Override
+25 −6
Original line number Diff line number Diff line
@@ -204,6 +204,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
    private final MultiInstanceHelper mMultiInstanceHelper;
    private final WindowDecorCaptionHandleRepository mWindowDecorCaptionHandleRepository;
    private final DesktopUserRepositories mDesktopUserRepositories;
    private boolean mIsRecentsTransitionRunning = false;

    private Runnable mLoadAppInfoRunnable;
    private Runnable mSetAppInfoRunnable;
@@ -498,7 +499,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
                applyStartTransactionOnDraw, shouldSetTaskVisibilityPositionAndCrop,
                mIsStatusBarVisible, mIsKeyguardVisibleAndOccluded, inFullImmersive,
                mDisplayController.getInsetsState(taskInfo.displayId), hasGlobalFocus,
                displayExclusionRegion);
                displayExclusionRegion, mIsRecentsTransitionRunning);

        final WindowDecorLinearLayout oldRootView = mResult.mRootView;
        final SurfaceControl oldDecorationSurface = mDecorationContainerSurface;
@@ -869,7 +870,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
            boolean inFullImmersiveMode,
            @NonNull InsetsState displayInsetsState,
            boolean hasGlobalFocus,
            @NonNull Region displayExclusionRegion) {
            @NonNull Region displayExclusionRegion,
            boolean shouldIgnoreCornerRadius) {
        final int captionLayoutId = getDesktopModeWindowDecorLayoutId(taskInfo.getWindowingMode());
        final boolean isAppHeader =
                captionLayoutId == R.layout.desktop_mode_app_header;
@@ -1006,13 +1008,19 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
        relayoutParams.mWindowDecorConfig = windowDecorConfig;

        if (DesktopModeStatus.useRoundedCorners()) {
            relayoutParams.mCornerRadius = taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM
                    ? loadDimensionPixelSize(context.getResources(),
                    R.dimen.desktop_windowing_freeform_rounded_corner_radius)
                    : INVALID_CORNER_RADIUS;
            relayoutParams.mCornerRadius = shouldIgnoreCornerRadius ? INVALID_CORNER_RADIUS :
                    getCornerRadius(context, relayoutParams.mLayoutResId);
        }
    }

    private static int getCornerRadius(@NonNull Context context, int layoutResId) {
        if (layoutResId == R.layout.desktop_mode_app_header) {
            return loadDimensionPixelSize(context.getResources(),
                    R.dimen.desktop_windowing_freeform_rounded_corner_radius);
        }
        return INVALID_CORNER_RADIUS;
    }

    /**
     * If task has focused window decor, return the caption id of the fullscreen caption size
     * resource. Otherwise, return ID_NULL and caption width be set to task width.
@@ -1739,6 +1747,17 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
                /* maximizeHoverEnabled= */ canOpenMaximizeMenu(animatingTaskResizeOrReposition)));
    }

    /**
     * Declares whether a Recents transition is currently active.
     *
     * <p> When a Recents transition is active we allow that transition to take ownership of the
     * corner radius of its task surfaces, so each window decoration should stop updating the corner
     * radius of its task surface during that time.
     */
    void setIsRecentsTransitionRunning(boolean isRecentsTransitionRunning) {
        mIsRecentsTransitionRunning = isRecentsTransitionRunning;
    }

    /**
     * Called when there is a {@link MotionEvent#ACTION_HOVER_EXIT} on the maximize window button.
     */
Loading