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

Commit 97402ef1 authored by Liran Binyamin's avatar Liran Binyamin Committed by Android (Google) Code Review
Browse files

Merge "Create a floating to bar transition" into main

parents d992f91e f387df55
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -634,6 +634,7 @@ public class Bubble implements BubbleViewProvider {
        return (mMetadataShortcutId != null && !mMetadataShortcutId.isEmpty());
    }

    @Nullable
    public BubbleTransitions.BubbleTransition getPreparingTransition() {
        return mPreparingTransition;
    }
@@ -718,6 +719,12 @@ public class Bubble implements BubbleViewProvider {
        mPreparingTransition = transit;
    }

    /** Whether this bubble is currently converting to bubble bar. */
    public boolean isConvertingToBar() {
        return getPreparingTransition() != null
                && getPreparingTransition().isConvertingBubbleToBar();
    }

    /**
     * Sets whether this bubble is considered text changed. This method is purely for
     * testing.
@@ -1360,6 +1367,7 @@ public class Bubble implements BubbleViewProvider {
        pw.print("  autoExpand:    "); pw.println(shouldAutoExpand());
        pw.print("  isDismissable: "); pw.println(mIsDismissable);
        pw.println("  bubbleMetadataFlagListener null?: " + (mBubbleMetadataFlagListener == null));
        pw.println("  preparingTransition null?: " + (mPreparingTransition == null));
        if (mExpandedView != null) {
            mExpandedView.dump(pw, "  ");
        }
+194 −2
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import static com.android.wm.shell.bubbles.util.BubbleUtilsKt.getExitBubbleTrans
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BUBBLES;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BUBBLES_NOISY;
import static com.android.wm.shell.shared.TransitionUtil.isOpeningMode;
import static com.android.wm.shell.transition.Transitions.TRANSIT_BUBBLE_CONVERT_FLOATING_TO_BAR;
import static com.android.wm.shell.transition.Transitions.TRANSIT_CONVERT_TO_BUBBLE;

import android.app.ActivityManager;
@@ -206,6 +207,27 @@ public class BubbleTransitions {
        return null;
    }

    /** Notifies when the unfold transition is starting. */
    public void notifyUnfoldTransitionStarting(@NonNull IBinder transition) {
        // this is used to block task view transitions from coming in while the unfold transition is
        // playing, and allows us to create a specific transition and merge it into unfold. for now
        // we only do this when switching from floating bubbles to bar bubbles so guard this with
        // the bubble bar flag, but once these are combined we should be able to remove this.
        if (com.android.wm.shell.Flags.enableBubbleBar()
                && mBubbleData.getSelectedBubble() instanceof Bubble) {
            Bubble bubble = (Bubble) mBubbleData.getSelectedBubble();
            mTaskViewTransitions.enqueueExternal(
                    bubble.getTaskView().getController(), () -> transition);
        }
    }

    /** Notifies when the unfold transition has finished. */
    public void notifyUnfoldTransitionFinished(@NonNull IBinder transition) {
        if (com.android.wm.shell.Flags.enableBubbleBar()) {
            mTaskViewTransitions.onExternalDone(transition);
        }
    }

    /**
     * Starts a new launch or convert transition to show the given bubble.
     */
@@ -271,8 +293,12 @@ public class BubbleTransitions {
     */
    public BubbleTransition startConvertFromBubble(Bubble bubble,
            TaskInfo taskInfo) {
        ConvertFromBubble convert = new ConvertFromBubble(bubble, taskInfo);
        return convert;
        return new ConvertFromBubble(bubble, taskInfo);
    }

    /** Starts a transition that converts a floating expanded bubble to a bar bubble. */
    public BubbleTransition startFloatingToBarConversion(Bubble bubble) {
        return new FloatingToBarConversion(bubble);
    }

    /** Starts a transition that converts a dragged bubble icon to a full screen task. */
@@ -317,6 +343,15 @@ public class BubbleTransitions {
        default void continueExpand() {}
        default void skip() {}
        default void continueCollapse() {}
        /** Continues the conversion transition. */
        default void continueConvert(BubbleBarLayerView layerView) {}
        /** Merge this transition with the unfold transition. */
        default void mergeWithUnfold(
                SurfaceControl taskLeash, SurfaceControl.Transaction finishT) {}
        /** Whether this transition is for converting a floating bubble to a bubble bar bubble. */
        default boolean isConvertingBubbleToBar() {
            return (this instanceof FloatingToBarConversion);
        }
    }

    /**
@@ -1567,6 +1602,163 @@ public class BubbleTransitions {
        }
    }

    /**
     * A transition to convert an expanded floating bubble to a bar bubble.
     *
     * <p>This transition class should be created after switching over to the new Bubbles window for
     * bubble bar mode, and adding the TaskView to the new window.
     *
     * <p>The transition is only started after calling {@link #continueConvert(BubbleBarLayerView)}
     * once the bubble bar location on the screen is known.
     */
    class FloatingToBarConversion implements TransitionHandler, BubbleTransition {

        private final Bubble mBubble;
        private final TransactionProvider mTransactionProvider;
        IBinder mTransition;
        private final Rect mBounds = new Rect();
        private final WindowContainerTransaction mWct = new WindowContainerTransaction();
        private SurfaceControl mTaskLeash;
        private SurfaceControl.Transaction mFinishTransaction;
        private boolean mIsStarted = false;

        FloatingToBarConversion(Bubble bubble) {
            this(bubble, SurfaceControl.Transaction::new);
        }

        @VisibleForTesting
        FloatingToBarConversion(Bubble bubble, TransactionProvider transactionProvider) {
            mBubble = bubble;
            mBubble.setPreparingTransition(this);
            mTransactionProvider = transactionProvider;
        }

        @Override
        public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
                @Nullable TransitionRequestInfo request) {
            return null;
        }

        @Override
        public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
                @NonNull SurfaceControl.Transaction startT,
                @NonNull SurfaceControl.Transaction finishT,
                @NonNull IBinder mergeTarget,
                @NonNull Transitions.TransitionFinishCallback finishCallback) {
        }

        @Override
        public void onTransitionConsumed(@NonNull IBinder transition, boolean aborted,
                @Nullable SurfaceControl.Transaction finishTransaction) {
            if (!aborted) return;
            mTransition = null;
            mTaskViewTransitions.onExternalDone(transition);
        }

        @Override
        public boolean startAnimation(@NonNull IBinder transition,
                @NonNull TransitionInfo info,
                @NonNull SurfaceControl.Transaction startTransaction,
                @NonNull SurfaceControl.Transaction finishTransaction,
                @NonNull Transitions.TransitionFinishCallback finishCallback) {
            if (mTransition != transition) {
                return false;
            }

            final TaskViewTaskController taskViewTaskController =
                    mBubble.getTaskView().getController();
            if (taskViewTaskController == null) {
                mTaskViewTransitions.onExternalDone(transition);
                finishCallback.onTransitionFinished(null);
                return true;
            }

            TransitionInfo.Change change = findTransitionChange(info);
            if (change == null) {
                Slog.w(TAG, "Expected a TaskView transition to front but didn't find "
                        + "one, cleaning up the task view");
                taskViewTaskController.setTaskNotFound();
                mTaskViewTransitions.onExternalDone(transition);
                finishCallback.onTransitionFinished(null);
                return true;
            }

            mTaskLeash = change.getLeash();
            mFinishTransaction = finishTransaction;
            updateBubbleTask();
            return true;
        }

        private TransitionInfo.Change findTransitionChange(TransitionInfo info) {
            WindowContainerToken token = mBubble.getTaskView().getTaskInfo().getToken();
            for (int i = 0; i < info.getChanges().size(); ++i) {
                final TransitionInfo.Change change = info.getChanges().get(i);
                if (change.getTaskInfo() == null) {
                    continue;
                }
                if (!token.equals(change.getTaskInfo().token)) {
                    continue;
                }
                return change;
            }
            return null;
        }

        @Override
        public void continueConvert(BubbleBarLayerView layerView) {
            layerView.getExpandedViewRestBounds(mBounds);
            mWct.setBounds(mBubble.getTaskView().getTaskInfo().token, mBounds);
            if (!mIsStarted) {
                startTransition();
            }
        }

        private void startTransition() {
            mIsStarted = true;
            final TaskView tv = mBubble.getTaskView();
            mTransition = mTransitions.startTransition(TRANSIT_BUBBLE_CONVERT_FLOATING_TO_BAR,
                    mWct, this);
            mTaskViewTransitions.enqueueExternal(tv.getController(), () -> mTransition);
        }

        @Override
        public void mergeWithUnfold(SurfaceControl taskLeash, SurfaceControl.Transaction finishT) {
            mTaskLeash = taskLeash;
            mFinishTransaction = finishT;
            updateBubbleTask();
        }

        private void updateBubbleTask() {
            final TaskViewTaskController tvc = mBubble.getTaskView().getController();
            final SurfaceControl taskViewSurface = mBubble.getTaskView().getSurfaceControl();
            final TaskViewRepository.TaskViewState state = mRepository.byTaskView(tvc);
            if (state == null) return;
            state.mVisible = true;
            state.mBounds.set(mBounds);
            final SurfaceControl.Transaction startT = mTransactionProvider.get();

            // since the task view is switching windows, its surface needs to be moved over to the
            // new bubble window surface
            startT.reparent(taskViewSurface,
                    mBubble.getBubbleBarExpandedView()
                            .getViewRootImpl()
                            .updateAndGetBoundsLayer(startT));

            startT.reparent(mTaskLeash, taskViewSurface);
            startT.setPosition(mTaskLeash, 0, 0);
            startT.setCornerRadius(mTaskLeash,
                    mBubble.getBubbleBarExpandedView().getRestingCornerRadius());
            startT.setWindowCrop(mTaskLeash, mBounds.width(), mBounds.height());
            startT.apply();
            mBubble.setPreparingTransition(null);
            mFinishTransaction.reparent(mTaskLeash, taskViewSurface);
            mFinishTransaction.setPosition(mTaskLeash, 0, 0);
            mFinishTransaction.setWindowCrop(mTaskLeash, mBounds.width(), mBounds.height());
            mTaskViewTransitions.onExternalDone(mTransition);
            mTransition = null;
        }
    }

    interface TransactionProvider {
        SurfaceControl.Transaction get();
    }
+1 −0
Original line number Diff line number Diff line
@@ -437,6 +437,7 @@ public class DefaultMixedHandler implements MixedTransitionHandler,
            if (wct != null) {
                mActiveTransitions.add(createDefaultMixedTransition(
                        MixedTransition.TYPE_UNFOLD, transition));
                mBubbleTransitions.notifyUnfoldTransitionStarting(transition);
            }
            return wct;
        } else if (mDesktopTasksController != null
+4 −1
Original line number Diff line number Diff line
@@ -109,7 +109,8 @@ class DefaultMixedTransition extends DefaultMixedHandler.MixedTransition {
                    animateOpenIntentWithRemoteAndPipOrDesktop(transition, info, startTransaction,
                            finishTransaction, finishCallback);
            case TYPE_UNFOLD ->
                    animateUnfold(info, startTransaction, finishTransaction, finishCallback);
                    animateUnfold(transition, info, startTransaction, finishTransaction,
                            finishCallback);
            case TYPE_OPEN_IN_DESKTOP ->
                    animateOpenInDesktop(
                            transition, info, startTransaction, finishTransaction, finishCallback);
@@ -405,6 +406,7 @@ class DefaultMixedTransition extends DefaultMixedHandler.MixedTransition {
    }

    private boolean animateUnfold(
            @NonNull IBinder transition,
            @NonNull TransitionInfo info,
            @NonNull SurfaceControl.Transaction startTransaction,
            @NonNull SurfaceControl.Transaction finishTransaction,
@@ -416,6 +418,7 @@ class DefaultMixedTransition extends DefaultMixedHandler.MixedTransition {
            mInFlightSubAnimations--;
            if (mInFlightSubAnimations > 0) return;
            finishCallback.onTransitionFinished(wct);
            mBubbleTransitions.notifyUnfoldTransitionFinished(transition);
        };
        mInFlightSubAnimations = 1;
        // Sync pip state.
+4 −0
Original line number Diff line number Diff line
@@ -209,6 +209,9 @@ public class Transitions implements RemoteCallable<Transitions>,
    /** Transition type for converting a task to a bubble. */
    public static final int TRANSIT_CONVERT_TO_BUBBLE = TRANSIT_FIRST_CUSTOM + 24;

    /** Transition type for converting a floating bubble to a bar bubble. */
    public static final int TRANSIT_BUBBLE_CONVERT_FLOATING_TO_BAR = TRANSIT_FIRST_CUSTOM + 25;

    /** Transition type for desktop mode transitions. */
    public static final int TRANSIT_DESKTOP_MODE_TYPES =
            WindowManager.TRANSIT_FIRST_CUSTOM + 100;
@@ -1918,6 +1921,7 @@ public class Transitions implements RemoteCallable<Transitions>,
            case TRANSIT_START_RECENTS_TRANSITION -> "START_RECENTS_TRANSITION";
            case TRANSIT_END_RECENTS_TRANSITION -> "END_RECENTS_TRANSITION";
            case TRANSIT_CONVERT_TO_BUBBLE -> "CONVERT_TO_BUBBLE";
            case TRANSIT_BUBBLE_CONVERT_FLOATING_TO_BAR -> "BUBBLE_CONVERT_FLOATING_TO_BAR";
            default -> "";
        };
        if (typeStr.isEmpty()) {
Loading