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

Commit d7725b52 authored by Chris Li's avatar Chris Li
Browse files

Only override ActivityEmbedding animation for embedded activities

Before, we check if there is any split rule meeting the bounds
requirement for the given Task bounds in order to determine whether or
not to override the animation.

This can cause issue when the apps later unregister the split rules
while there is existing split. Also, this is hard to determine as we now
have SplitAttributesCalculator which can change the split state for the
same bounds.

To fix these problem, we now check if the app transition contains any
embedded activity (embedded TaskFragment that is not filling Task), to
determine if the animation should be played by the organizer.

Fix: 242051445
Test: atest WmTests:AppTransitionControllerTest
Change-Id: Ie90ba085cab3d4072f47cc3599d0494324fa39a9
parent 4c430266
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -39,13 +39,13 @@ interface ITaskFragmentOrganizerController {
     * animations if the transition only contains windows that belong to the organized
     * TaskFragments in the given Task.
     */
    void registerRemoteAnimations(in ITaskFragmentOrganizer organizer, int taskId,
    void registerRemoteAnimations(in ITaskFragmentOrganizer organizer,
        in RemoteAnimationDefinition definition);

    /**
     * Unregisters remote animations per transition type for the organizer.
     */
    void unregisterRemoteAnimations(in ITaskFragmentOrganizer organizer, int taskId);
    void unregisterRemoteAnimations(in ITaskFragmentOrganizer organizer);

    /**
     * Checks if an activity organized by a {@link android.window.TaskFragmentOrganizer} and
+5 −8
Original line number Diff line number Diff line
@@ -140,16 +140,13 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
    /**
     * Registers remote animations per transition type for the organizer. It will override the
     * animations if the transition only contains windows that belong to the organized
     * TaskFragments in the given Task.
     *
     * @param taskId overrides if the transition only contains windows belonging to this Task.
     * TaskFragments, and at least one of the transition window is embedded (not filling the Task).
     * @hide
     */
    @CallSuper
    public void registerRemoteAnimations(int taskId,
            @NonNull RemoteAnimationDefinition definition) {
    public void registerRemoteAnimations(@NonNull RemoteAnimationDefinition definition) {
        try {
            getController().registerRemoteAnimations(mInterface, taskId, definition);
            getController().registerRemoteAnimations(mInterface, definition);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -160,9 +157,9 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
     * @hide
     */
    @CallSuper
    public void unregisterRemoteAnimations(int taskId) {
    public void unregisterRemoteAnimations() {
        try {
            getController().unregisterRemoteAnimations(mInterface, taskId);
            getController().unregisterRemoteAnimations(mInterface);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
+6 −13
Original line number Diff line number Diff line
@@ -31,7 +31,6 @@ import android.window.TaskFragmentOrganizer;
import android.window.TaskFragmentTransaction;
import android.window.WindowContainerTransaction;

import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

@@ -79,26 +78,20 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
    @Override
    public void unregisterOrganizer() {
        if (mAnimationController != null) {
            mAnimationController.unregisterAllRemoteAnimations();
            mAnimationController.unregisterRemoteAnimations();
            mAnimationController = null;
        }
        super.unregisterOrganizer();
    }

    /** Overrides the animation if the transition is on the given Task. */
    void startOverrideSplitAnimation(int taskId) {
    /**
     * Overrides the animation for transitions of embedded activities organized by this organizer.
     */
    void overrideSplitAnimation() {
        if (mAnimationController == null) {
            mAnimationController = new TaskFragmentAnimationController(this);
        }
        mAnimationController.registerRemoteAnimations(taskId);
    }

    /** No longer overrides the animation if the transition is on the given Task. */
    @GuardedBy("mLock")
    void stopOverrideSplitAnimation(int taskId) {
        if (mAnimationController != null) {
            mAnimationController.unregisterRemoteAnimations(taskId);
        }
        mAnimationController.registerRemoteAnimations();
    }

    /**
+1 −43
Original line number Diff line number Diff line
@@ -193,7 +193,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
                        continue;
                    }
                    updateContainersInTask(wct, taskContainer);
                    updateAnimationOverride(taskContainer);
                }
                // The WCT should be applied and merged to the device state change transition if
                // there is one.
@@ -208,9 +207,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
        synchronized (mLock) {
            mSplitRules.clear();
            mSplitRules.addAll(rules);
            for (int i = mTaskContainers.size() - 1; i >= 0; i--) {
                updateAnimationOverride(mTaskContainers.valueAt(i));
            }
        }
    }

@@ -608,7 +604,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
            }
            if (taskContainer.isEmpty()) {
                // Cleanup the TaskContainer if it becomes empty.
                mPresenter.stopOverrideSplitAnimation(taskContainer.getTaskId());
                mTaskContainers.remove(taskContainer.getTaskId());
            }
            return;
@@ -618,43 +613,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
    @GuardedBy("mLock")
    private void onTaskContainerInfoChanged(@NonNull TaskContainer taskContainer,
            @NonNull Configuration config) {
        final boolean wasInPip = taskContainer.isInPictureInPicture();
        final boolean isInPIp = isInPictureInPicture(config);

        // We need to check the animation override when enter/exit PIP or has bounds changed.
        boolean shouldUpdateAnimationOverride = wasInPip != isInPIp;
        if (taskContainer.setTaskBounds(config.windowConfiguration.getBounds())
                && !isInPIp) {
            // We don't care the bounds change when it has already entered PIP.
            shouldUpdateAnimationOverride = true;
        }
        if (shouldUpdateAnimationOverride) {
            updateAnimationOverride(taskContainer);
        }
    }

    /**
     * Updates if we should override transition animation. We only want to override if the Task
     * bounds is large enough for at least one split rule.
     */
    @GuardedBy("mLock")
    private void updateAnimationOverride(@NonNull TaskContainer taskContainer) {
        if (ENABLE_SHELL_TRANSITIONS) {
            // TODO(b/207070762): cleanup with legacy app transition
            // Animation will be handled by WM Shell with Shell transition enabled.
            return;
        }
        if (!taskContainer.isTaskBoundsInitialized()) {
            // We don't know about the Task bounds/windowingMode yet.
            return;
        }

        // We only want to override if the TaskContainer may show split.
        if (mayShowSplit(taskContainer)) {
            mPresenter.startOverrideSplitAnimation(taskContainer.getTaskId());
        } else {
            mPresenter.stopOverrideSplitAnimation(taskContainer.getTaskId());
        }
        taskContainer.setTaskBounds(config.windowConfiguration.getBounds());
    }

    /** Returns whether the given {@link TaskContainer} may show in split. */
@@ -1279,7 +1238,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
                Log.w(TAG, "Can't find bounds from activity=" + activityInTask);
            }
        }
        updateAnimationOverride(taskContainer);
        return container;
    }

+5 −0
Original line number Diff line number Diff line
@@ -139,6 +139,11 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
        super(executor, controller);
        mController = controller;
        registerOrganizer();
        if (!SplitController.ENABLE_SHELL_TRANSITIONS) {
            // TODO(b/207070762): cleanup with legacy app transition
            // Animation will be handled by WM Shell when Shell transition is enabled.
            overrideSplitAnimation();
        }
    }

    /**
Loading