Fine turn divider transition on enter/exit split
Make divider could fade-in/out with split surface change. Bug: 245472831 Test: manual Test: pass existing tests Change-Id: Ifd129ceae1db1fffc9bf4ad3b0f85279138581ef
This commit is contained in:
@@ -897,7 +897,7 @@ public class PipTransition extends PipTransitionController {
|
||||
.setWindowCrop(leash, endBounds.width(), endBounds.height());
|
||||
}
|
||||
}
|
||||
mSplitScreenOptional.get().finishEnterSplitScreen(startTransaction);
|
||||
mSplitScreenOptional.get().finishEnterSplitScreen(finishTransaction);
|
||||
startTransaction.apply();
|
||||
|
||||
mPipOrganizer.onExitPipFinished(taskInfo);
|
||||
|
||||
@@ -22,6 +22,7 @@ import static android.view.WindowManager.TRANSIT_OPEN;
|
||||
import static android.view.WindowManager.TRANSIT_TO_BACK;
|
||||
import static android.view.WindowManager.TRANSIT_TO_FRONT;
|
||||
|
||||
import static com.android.wm.shell.common.split.SplitScreenConstants.FLAG_IS_DIVIDER_BAR;
|
||||
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_MAIN;
|
||||
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
|
||||
import static com.android.wm.shell.splitscreen.SplitScreen.stageTypeToString;
|
||||
@@ -155,8 +156,10 @@ class SplitScreenTransitions {
|
||||
}
|
||||
boolean isRootOrSplitSideRoot = change.getParent() == null
|
||||
|| topRoot.equals(change.getParent());
|
||||
// For enter or exit, we only want to animate the side roots but not the top-root.
|
||||
if (!isRootOrSplitSideRoot || topRoot.equals(change.getContainer())) {
|
||||
boolean isDivider = change.getFlags() == FLAG_IS_DIVIDER_BAR;
|
||||
// For enter or exit, we only want to animate side roots and the divider but not the
|
||||
// top-root.
|
||||
if (!isRootOrSplitSideRoot || topRoot.equals(change.getContainer()) || isDivider) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -165,6 +168,10 @@ class SplitScreenTransitions {
|
||||
t.setPosition(leash, change.getEndAbsBounds().left, change.getEndAbsBounds().top);
|
||||
t.setWindowCrop(leash, change.getEndAbsBounds().width(),
|
||||
change.getEndAbsBounds().height());
|
||||
} else if (isDivider) {
|
||||
t.setPosition(leash, change.getEndAbsBounds().left, change.getEndAbsBounds().top);
|
||||
t.setLayer(leash, Integer.MAX_VALUE);
|
||||
t.show(leash);
|
||||
}
|
||||
boolean isOpening = isOpeningTransition(info);
|
||||
if (isOpening && (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT)) {
|
||||
|
||||
@@ -891,10 +891,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
mSyncQueue.queue(wrapAsSplitRemoteAnimation(adapter), WindowManager.TRANSIT_OPEN, wct);
|
||||
}
|
||||
|
||||
mSyncQueue.runInSync(t -> {
|
||||
setDividerVisibility(true, t);
|
||||
});
|
||||
|
||||
setEnterInstanceId(instanceId);
|
||||
}
|
||||
|
||||
@@ -933,6 +929,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
@Override
|
||||
public void onAnimationCancelled(boolean isKeyguardOccluded) {
|
||||
onRemoteAnimationFinishedOrCancelled(evictWct);
|
||||
setDividerVisibility(true, null);
|
||||
try {
|
||||
adapter.getRunner().onAnimationCancelled(isKeyguardOccluded);
|
||||
} catch (RemoteException e) {
|
||||
@@ -973,6 +970,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
t.setPosition(apps[i].leash, 0, 0);
|
||||
}
|
||||
}
|
||||
setDividerVisibility(true, t);
|
||||
t.apply();
|
||||
|
||||
IRemoteAnimationFinishedCallback wrapCallback =
|
||||
@@ -1463,6 +1461,10 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
void finishEnterSplitScreen(SurfaceControl.Transaction t) {
|
||||
mSplitLayout.init();
|
||||
setDividerVisibility(true, t);
|
||||
// Ensure divider surface are re-parented back into the hierarchy at the end of the
|
||||
// transition. See Transition#buildFinishTransaction for more detail.
|
||||
t.reparent(mSplitLayout.getDividerLeash(), mRootTaskLeash);
|
||||
|
||||
updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
|
||||
t.show(mRootTaskLeash);
|
||||
setSplitsVisible(true);
|
||||
@@ -1772,6 +1774,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
setDividerVisibility(mainStageVisible, null);
|
||||
}
|
||||
|
||||
// Set divider visibility flag and try to apply it, the param transaction is used to apply.
|
||||
// See applyDividerVisibility for more detail.
|
||||
private void setDividerVisibility(boolean visible, @Nullable SurfaceControl.Transaction t) {
|
||||
if (visible == mDividerVisible) {
|
||||
return;
|
||||
@@ -1798,14 +1802,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
return;
|
||||
}
|
||||
|
||||
if (t != null) {
|
||||
applyDividerVisibility(t);
|
||||
} else {
|
||||
mSyncQueue.runInSync(transaction -> applyDividerVisibility(transaction));
|
||||
}
|
||||
applyDividerVisibility(t);
|
||||
}
|
||||
|
||||
private void applyDividerVisibility(SurfaceControl.Transaction t) {
|
||||
// Apply divider visibility by current visibility flag. If param transaction is non-null, it
|
||||
// will apply by that transaction, if it is null and visible, it will run a fade-in animation,
|
||||
// otherwise hide immediately.
|
||||
private void applyDividerVisibility(@Nullable SurfaceControl.Transaction t) {
|
||||
final SurfaceControl dividerLeash = mSplitLayout.getDividerLeash();
|
||||
if (dividerLeash == null) {
|
||||
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
|
||||
@@ -1822,7 +1825,12 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
mDividerFadeInAnimator.cancel();
|
||||
}
|
||||
|
||||
if (mDividerVisible) {
|
||||
mSplitLayout.getRefDividerBounds(mTempRect1);
|
||||
if (t != null) {
|
||||
t.setVisibility(dividerLeash, mDividerVisible);
|
||||
t.setLayer(dividerLeash, Integer.MAX_VALUE);
|
||||
t.setPosition(dividerLeash, mTempRect1.left, mTempRect1.top);
|
||||
} else if (mDividerVisible) {
|
||||
final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
|
||||
mDividerFadeInAnimator = ValueAnimator.ofFloat(0f, 1f);
|
||||
mDividerFadeInAnimator.addUpdateListener(animation -> {
|
||||
@@ -1862,7 +1870,10 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
|
||||
mDividerFadeInAnimator.start();
|
||||
} else {
|
||||
t.hide(dividerLeash);
|
||||
final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
|
||||
transaction.hide(dividerLeash);
|
||||
transaction.apply();
|
||||
mTransactionPool.release(transaction);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2446,7 +2457,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
}
|
||||
|
||||
finishEnterSplitScreen(finishT);
|
||||
addDividerBarToTransition(info, finishT, true /* show */);
|
||||
addDividerBarToTransition(info, true /* show */);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2589,7 +2600,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
if (dismissTransition.mDismissTop == STAGE_TYPE_UNDEFINED) {
|
||||
// TODO: Have a proper remote for this. Until then, though, reset state and use the
|
||||
// normal animation stuff (which falls back to the normal launcher remote).
|
||||
t.hide(mSplitLayout.getDividerLeash());
|
||||
setDividerVisibility(false, t);
|
||||
mSplitLayout.release(t);
|
||||
mSplitTransitions.mPendingDismiss = null;
|
||||
return false;
|
||||
@@ -2607,7 +2618,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
});
|
||||
}
|
||||
|
||||
addDividerBarToTransition(info, finishT, false /* show */);
|
||||
addDividerBarToTransition(info, false /* show */);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2648,11 +2659,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
logExit(EXIT_REASON_UNKNOWN);
|
||||
}
|
||||
|
||||
private void addDividerBarToTransition(@NonNull TransitionInfo info,
|
||||
@NonNull SurfaceControl.Transaction finishT, boolean show) {
|
||||
private void addDividerBarToTransition(@NonNull TransitionInfo info, boolean show) {
|
||||
final SurfaceControl leash = mSplitLayout.getDividerLeash();
|
||||
final TransitionInfo.Change barChange = new TransitionInfo.Change(null /* token */, leash);
|
||||
mSplitLayout.getRefDividerBounds(mTempRect1);
|
||||
barChange.setParent(mRootTaskInfo.token);
|
||||
barChange.setStartAbsBounds(mTempRect1);
|
||||
barChange.setEndAbsBounds(mTempRect1);
|
||||
barChange.setMode(show ? TRANSIT_TO_FRONT : TRANSIT_TO_BACK);
|
||||
@@ -2660,15 +2671,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
// Technically this should be order-0, but this is running after layer assignment
|
||||
// and it's a special case, so just add to end.
|
||||
info.addChange(barChange);
|
||||
|
||||
if (show) {
|
||||
finishT.setLayer(leash, Integer.MAX_VALUE);
|
||||
finishT.setPosition(leash, mTempRect1.left, mTempRect1.top);
|
||||
finishT.show(leash);
|
||||
// Ensure divider surface are re-parented back into the hierarchy at the end of the
|
||||
// transition. See Transition#buildFinishTransaction for more detail.
|
||||
finishT.reparent(leash, mRootTaskLeash);
|
||||
}
|
||||
}
|
||||
|
||||
RemoteAnimationTarget getDividerBarLegacyTarget() {
|
||||
|
||||
@@ -113,6 +113,7 @@ public class StageCoordinatorTests extends ShellTestCase {
|
||||
|
||||
private SurfaceSession mSurfaceSession = new SurfaceSession();
|
||||
private SurfaceControl mRootLeash;
|
||||
private SurfaceControl mDividerLeash;
|
||||
private ActivityManager.RunningTaskInfo mRootTask;
|
||||
private StageCoordinator mStageCoordinator;
|
||||
private Transitions mTransitions;
|
||||
@@ -129,12 +130,14 @@ public class StageCoordinatorTests extends ShellTestCase {
|
||||
mTaskOrganizer, mMainStage, mSideStage, mDisplayController, mDisplayImeController,
|
||||
mDisplayInsetsController, mSplitLayout, mTransitions, mTransactionPool,
|
||||
mMainExecutor, Optional.empty()));
|
||||
mDividerLeash = new SurfaceControl.Builder(mSurfaceSession).setName("fakeDivider").build();
|
||||
|
||||
when(mSplitLayout.getBounds1()).thenReturn(mBounds1);
|
||||
when(mSplitLayout.getBounds2()).thenReturn(mBounds2);
|
||||
when(mSplitLayout.getRootBounds()).thenReturn(mRootBounds);
|
||||
when(mSplitLayout.isLandscape()).thenReturn(false);
|
||||
when(mSplitLayout.applyTaskChanges(any(), any(), any())).thenReturn(true);
|
||||
when(mSplitLayout.getDividerLeash()).thenReturn(mDividerLeash);
|
||||
|
||||
mRootTask = new TestRunningTaskInfoBuilder().build();
|
||||
mRootLeash = new SurfaceControl.Builder(mSurfaceSession).setName("test").build();
|
||||
|
||||
Reference in New Issue
Block a user