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

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

Do not override animation when the parent bounds doesn't support split

Without this cl, we always override animation as long as there is any
organzied TaskFragment. And users may see different animation on the
same small screen before and after they have unfold and fold.

The idea is to only register the remote handler if the app currently has
at least one split rule that can fit the current Task bounds.

When there can be split, we want to always override the animation to
make it consistent.

When there won't be any split, we want to allow app to override
animation, so they can still provide the same experience as normal phone
on small screen.

Fix: 207804116
Fix: 196173550
Test: manual test with fold/unfold
Change-Id: I3ae194f89b35afc5734338fd3bb350e0cd364c85
parent 091aba97
Loading
Loading
Loading
Loading
+10 −9
Original line number Diff line number Diff line
@@ -79,22 +79,23 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
    }

    @Override
    public void registerOrganizer() {
        if (mAnimationController != null) {
            throw new IllegalStateException("Must unregister the organizer before re-register.");
    public void unregisterOrganizer() {
        stopOverrideSplitAnimation();
        mAnimationController = null;
        super.unregisterOrganizer();
    }
        super.registerOrganizer();

    void startOverrideSplitAnimation() {
        if (mAnimationController == null) {
            mAnimationController = new TaskFragmentAnimationController(this);
        }
        mAnimationController.registerRemoteAnimations();
    }

    @Override
    public void unregisterOrganizer() {
    void stopOverrideSplitAnimation() {
        if (mAnimationController != null) {
            mAnimationController.unregisterRemoteAnimations();
            mAnimationController = null;
        }
        super.unregisterOrganizer();
    }

    /**
+58 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.app.Instrumentation;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -63,6 +64,9 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
    private @NonNull Consumer<List<SplitInfo>> mEmbeddingCallback;
    private final List<SplitInfo> mLastReportedSplitStates = new ArrayList<>();

    // We currently only support split activity embedding within the one root Task.
    private final Rect mParentBounds = new Rect();

    public SplitController() {
        mPresenter = new SplitPresenter(new MainThreadExecutor(), this);
        ActivityThread activityThread = ActivityThread.currentActivityThread();
@@ -79,6 +83,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
    public void setEmbeddingRules(@NonNull Set<EmbeddingRule> rules) {
        mSplitRules.clear();
        mSplitRules.addAll(rules);
        updateAnimationOverride();
    }

    @NonNull
@@ -158,6 +163,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
    @Override
    public void onTaskFragmentParentInfoChanged(@NonNull IBinder fragmentToken,
            @NonNull Configuration parentConfig) {
        onParentBoundsMayChange(parentConfig.windowConfiguration.getBounds());
        TaskFragmentContainer container = getContainer(fragmentToken);
        if (container != null) {
            mPresenter.updateContainer(container);
@@ -165,6 +171,51 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
        }
    }

    private void onParentBoundsMayChange(Activity activity) {
        if (activity.isFinishing()) {
            return;
        }

        onParentBoundsMayChange(mPresenter.getParentContainerBounds(activity));
    }

    private void onParentBoundsMayChange(Rect parentBounds) {
        if (!parentBounds.isEmpty() && !mParentBounds.equals(parentBounds)) {
            mParentBounds.set(parentBounds);
            updateAnimationOverride();
        }
    }

    /**
     * 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.
     */
    private void updateAnimationOverride() {
        if (mParentBounds.isEmpty()) {
            // We don't know about the parent bounds yet.
            return;
        }

        // Check if the parent container bounds can support any split rule.
        boolean supportSplit = false;
        for (EmbeddingRule rule : mSplitRules) {
            if (!(rule instanceof SplitRule)) {
                continue;
            }
            if (mPresenter.shouldShowSideBySide(mParentBounds, (SplitRule) rule)) {
                supportSplit = true;
                break;
            }
        }

        // We only want to override if it supports split.
        if (supportSplit) {
            mPresenter.startOverrideSplitAnimation();
        } else {
            mPresenter.stopOverrideSplitAnimation();
        }
    }

    void onActivityCreated(@NonNull Activity launchedActivity) {
        handleActivityCreated(launchedActivity);
        updateCallbackIfNecessary();
@@ -180,6 +231,11 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
        final TaskFragmentContainer currentContainer = getContainerWithActivity(
                launchedActivity.getActivityToken());

        if (currentContainer == null) {
            // Initial check before any TaskFragment is created.
            onParentBoundsMayChange(launchedActivity);
        }

        // Check if the activity is configured to always be expanded.
        if (shouldExpand(launchedActivity, null, splitRules)) {
            if (shouldContainerBeExpanded(currentContainer)) {
@@ -257,6 +313,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
            // onTaskFragmentParentInfoChanged
            return;
        }
        // The bounds of the container may have been changed.
        onParentBoundsMayChange(activity);

        // Check if activity requires a placeholder
        launchPlaceholderIfNecessary(activity);
+21 −11
Original line number Diff line number Diff line
@@ -37,32 +37,42 @@ class TaskFragmentAnimationController {

    private final TaskFragmentOrganizer mOrganizer;
    private final TaskFragmentAnimationRunner mRemoteRunner = new TaskFragmentAnimationRunner();
    private final RemoteAnimationDefinition mDefinition;
    private boolean mIsRegister;

    TaskFragmentAnimationController(TaskFragmentOrganizer organizer) {
        mOrganizer = organizer;
        mDefinition = new RemoteAnimationDefinition();
        final RemoteAnimationAdapter animationAdapter =
                new RemoteAnimationAdapter(mRemoteRunner, 0, 0, true /* changeNeedsSnapshot */);
        mDefinition.addRemoteAnimation(TRANSIT_OLD_ACTIVITY_OPEN, animationAdapter);
        mDefinition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_OPEN, animationAdapter);
        mDefinition.addRemoteAnimation(TRANSIT_OLD_TASK_OPEN, animationAdapter);
        mDefinition.addRemoteAnimation(TRANSIT_OLD_ACTIVITY_CLOSE, animationAdapter);
        mDefinition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_CLOSE, animationAdapter);
        mDefinition.addRemoteAnimation(TRANSIT_OLD_TASK_CLOSE, animationAdapter);
        mDefinition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_CHANGE, animationAdapter);
    }

    void registerRemoteAnimations() {
        if (DEBUG) {
            Log.v(TAG, "registerRemoteAnimations");
        }
        final RemoteAnimationDefinition definition = new RemoteAnimationDefinition();
        final RemoteAnimationAdapter animationAdapter =
                new RemoteAnimationAdapter(mRemoteRunner, 0, 0, true /* changeNeedsSnapshot */);
        definition.addRemoteAnimation(TRANSIT_OLD_ACTIVITY_OPEN, animationAdapter);
        definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_OPEN, animationAdapter);
        definition.addRemoteAnimation(TRANSIT_OLD_TASK_OPEN, animationAdapter);
        definition.addRemoteAnimation(TRANSIT_OLD_ACTIVITY_CLOSE, animationAdapter);
        definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_CLOSE, animationAdapter);
        definition.addRemoteAnimation(TRANSIT_OLD_TASK_CLOSE, animationAdapter);
        definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_CHANGE, animationAdapter);
        mOrganizer.registerRemoteAnimations(definition);
        if (mIsRegister) {
            return;
        }
        mOrganizer.registerRemoteAnimations(mDefinition);
        mIsRegister = true;
    }

    void unregisterRemoteAnimations() {
        if (DEBUG) {
            Log.v(TAG, "unregisterRemoteAnimations");
        }
        if (!mIsRegister) {
            return;
        }
        mOrganizer.unregisterRemoteAnimations();
        mIsRegister = false;
    }
}