diff options
| author | 2021-12-09 15:25:20 +0800 | |
|---|---|---|
| committer | 2022-01-12 14:45:56 +0800 | |
| commit | c0acf094f24d772f4e69d0fc5e0db62a8c900d4a (patch) | |
| tree | 0af7fb63b35cbb6e9b41f1984e6c6fd1ea822a12 | |
| parent | 091aba9717f189ed6d99379079b6c3c339c3ac91 (diff) | |
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
3 files changed, 89 insertions, 20 deletions
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java index df751fc9fa48..180c77250fd1 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java @@ -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(); + } + + void startOverrideSplitAnimation() { + if (mAnimationController == null) { + mAnimationController = new TaskFragmentAnimationController(this); } - super.registerOrganizer(); - mAnimationController = new TaskFragmentAnimationController(this); mAnimationController.registerRemoteAnimations(); } - @Override - public void unregisterOrganizer() { + void stopOverrideSplitAnimation() { if (mAnimationController != null) { mAnimationController.unregisterRemoteAnimations(); - mAnimationController = null; } - super.unregisterOrganizer(); } /** diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java index b8e8b0114b47..530fb00facbb 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java @@ -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); diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationController.java index 3c7d2de6165f..a801dc8193fd 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationController.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationController.java @@ -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; } } |