Handle auto-pip change in split handling transitions
An auto-pip change might get collected into the transition which has
already claimed by split handler. This makes sure to handle the mixed
transition between split handler and pip handler.
Fix: 285816139
Test: open a fullscreen app on top of a split pair with auto-pip app.
verified expanding the pip window, split pair is dismissed in
overview.
Change-Id: I5c723000e7ddc6a96b8992960845400c152ed3d2
This commit is contained in:
@@ -2453,6 +2453,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
|
|
||||||
mSplitLayout.setFreezeDividerWindow(false);
|
mSplitLayout.setFreezeDividerWindow(false);
|
||||||
final StageChangeRecord record = new StageChangeRecord();
|
final StageChangeRecord record = new StageChangeRecord();
|
||||||
|
final int transitType = info.getType();
|
||||||
|
boolean hasEnteringPip = false;
|
||||||
for (int iC = 0; iC < info.getChanges().size(); ++iC) {
|
for (int iC = 0; iC < info.getChanges().size(); ++iC) {
|
||||||
final TransitionInfo.Change change = info.getChanges().get(iC);
|
final TransitionInfo.Change change = info.getChanges().get(iC);
|
||||||
if (change.getMode() == TRANSIT_CHANGE
|
if (change.getMode() == TRANSIT_CHANGE
|
||||||
@@ -2460,6 +2462,10 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
mSplitLayout.update(startTransaction);
|
mSplitLayout.update(startTransaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mMixedHandler.isEnteringPip(change, transitType)) {
|
||||||
|
hasEnteringPip = true;
|
||||||
|
}
|
||||||
|
|
||||||
final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
|
final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
|
||||||
if (taskInfo == null) continue;
|
if (taskInfo == null) continue;
|
||||||
if (taskInfo.token.equals(mRootTaskInfo.token)) {
|
if (taskInfo.token.equals(mRootTaskInfo.token)) {
|
||||||
@@ -2508,6 +2514,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasEnteringPip) {
|
||||||
|
mMixedHandler.animatePendingEnterPipFromSplit(transition, info,
|
||||||
|
startTransaction, finishTransaction, finishCallback);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
final ArraySet<StageTaskListener> dismissStages = record.getShouldDismissedStage();
|
final ArraySet<StageTaskListener> dismissStages = record.getShouldDismissedStage();
|
||||||
if (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0
|
if (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0
|
||||||
|| dismissStages.size() == 1) {
|
|| dismissStages.size() == 1) {
|
||||||
|
|||||||
@@ -42,10 +42,10 @@ import android.window.WindowContainerTransaction;
|
|||||||
import android.window.WindowContainerTransactionCallback;
|
import android.window.WindowContainerTransactionCallback;
|
||||||
|
|
||||||
import com.android.internal.protolog.common.ProtoLog;
|
import com.android.internal.protolog.common.ProtoLog;
|
||||||
|
import com.android.wm.shell.common.split.SplitScreenUtils;
|
||||||
import com.android.wm.shell.desktopmode.DesktopModeController;
|
import com.android.wm.shell.desktopmode.DesktopModeController;
|
||||||
import com.android.wm.shell.desktopmode.DesktopModeStatus;
|
import com.android.wm.shell.desktopmode.DesktopModeStatus;
|
||||||
import com.android.wm.shell.desktopmode.DesktopTasksController;
|
import com.android.wm.shell.desktopmode.DesktopTasksController;
|
||||||
import com.android.wm.shell.common.split.SplitScreenUtils;
|
|
||||||
import com.android.wm.shell.keyguard.KeyguardTransitionHandler;
|
import com.android.wm.shell.keyguard.KeyguardTransitionHandler;
|
||||||
import com.android.wm.shell.pip.PipTransitionController;
|
import com.android.wm.shell.pip.PipTransitionController;
|
||||||
import com.android.wm.shell.pip.phone.PipTouchHandler;
|
import com.android.wm.shell.pip.phone.PipTouchHandler;
|
||||||
@@ -470,7 +470,8 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
|
|||||||
}
|
}
|
||||||
finishCallback.onTransitionFinished(mixed.mFinishWCT, wctCB);
|
finishCallback.onTransitionFinished(mixed.mFinishWCT, wctCB);
|
||||||
};
|
};
|
||||||
if (isGoingHome) {
|
if (isGoingHome || mSplitHandler.getSplitItemPosition(pipChange.getLastParent())
|
||||||
|
!= SPLIT_POSITION_UNDEFINED) {
|
||||||
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Animation is actually mixed "
|
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Animation is actually mixed "
|
||||||
+ "since entering-PiP caused us to leave split and return home.");
|
+ "since entering-PiP caused us to leave split and return home.");
|
||||||
// We need to split the transition into 2 parts: the pip part (animated by pip)
|
// We need to split the transition into 2 parts: the pip part (animated by pip)
|
||||||
@@ -538,11 +539,28 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is intended to be called by SplitCoordinator as a helper to mix a split handling
|
||||||
|
* transition with an entering-pip change. The use-case for this is when an auto-pip change
|
||||||
|
* gets collected into the transition which has already claimed by
|
||||||
|
* StageCoordinator.handleRequest. This happens when launching a fullscreen app while having an
|
||||||
|
* auto-pip activity in the foreground split pair.
|
||||||
|
*/
|
||||||
|
// TODO(b/287704263): Remove when split/mixed are reversed.
|
||||||
|
public boolean animatePendingEnterPipFromSplit(IBinder transition, TransitionInfo info,
|
||||||
|
SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
|
||||||
|
Transitions.TransitionFinishCallback finishCallback) {
|
||||||
|
final MixedTransition mixed = new MixedTransition(
|
||||||
|
MixedTransition.TYPE_ENTER_PIP_FROM_SPLIT, transition);
|
||||||
|
mActiveTransitions.add(mixed);
|
||||||
|
return animateEnterPipFromSplit(mixed, info, startT, finishT, finishCallback);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is intended to be called by SplitCoordinator as a helper to mix an already-pending
|
* This is intended to be called by SplitCoordinator as a helper to mix an already-pending
|
||||||
* split transition with a display-change. The use-case for this is when a display
|
* split transition with a display-change. The use-case for this is when a display
|
||||||
* change/rotation gets collected into a split-screen enter/exit transition which has already
|
* change/rotation gets collected into a split-screen enter/exit transition which has already
|
||||||
* been claimed by StageCoordinator.handleRequest . This happens during launcher tests.
|
* been claimed by StageCoordinator.handleRequest. This happens during launcher tests.
|
||||||
*/
|
*/
|
||||||
public boolean animatePendingSplitWithDisplayChange(@NonNull IBinder transition,
|
public boolean animatePendingSplitWithDisplayChange(@NonNull IBinder transition,
|
||||||
@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startT,
|
@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startT,
|
||||||
@@ -715,6 +733,13 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
|
|||||||
return mPipHandler.requestHasPipEnter(request);
|
return mPipHandler.requestHasPipEnter(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Whether a particular change is a window that is entering pip. */
|
||||||
|
// TODO(b/287704263): Remove when split/mixed are reversed.
|
||||||
|
public boolean isEnteringPip(TransitionInfo.Change change,
|
||||||
|
@WindowManager.TransitionType int transitType) {
|
||||||
|
return mPipHandler.isEnteringPip(change, transitType);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
|
public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
|
||||||
@NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget,
|
@NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget,
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ import com.android.wm.shell.common.SyncTransactionQueue;
|
|||||||
import com.android.wm.shell.common.TransactionPool;
|
import com.android.wm.shell.common.TransactionPool;
|
||||||
import com.android.wm.shell.common.split.SplitDecorManager;
|
import com.android.wm.shell.common.split.SplitDecorManager;
|
||||||
import com.android.wm.shell.common.split.SplitLayout;
|
import com.android.wm.shell.common.split.SplitLayout;
|
||||||
|
import com.android.wm.shell.transition.DefaultMixedHandler;
|
||||||
import com.android.wm.shell.transition.Transitions;
|
import com.android.wm.shell.transition.Transitions;
|
||||||
import com.android.wm.shell.windowdecor.WindowDecorViewModel;
|
import com.android.wm.shell.windowdecor.WindowDecorViewModel;
|
||||||
|
|
||||||
@@ -105,6 +106,7 @@ public class SplitTransitionTests extends ShellTestCase {
|
|||||||
@Mock private WindowDecorViewModel mWindowDecorViewModel;
|
@Mock private WindowDecorViewModel mWindowDecorViewModel;
|
||||||
@Mock private ShellExecutor mMainExecutor;
|
@Mock private ShellExecutor mMainExecutor;
|
||||||
@Mock private LaunchAdjacentController mLaunchAdjacentController;
|
@Mock private LaunchAdjacentController mLaunchAdjacentController;
|
||||||
|
@Mock private DefaultMixedHandler mMixedHandler;
|
||||||
private SplitLayout mSplitLayout;
|
private SplitLayout mSplitLayout;
|
||||||
private MainStage mMainStage;
|
private MainStage mMainStage;
|
||||||
private SideStage mSideStage;
|
private SideStage mSideStage;
|
||||||
@@ -136,6 +138,7 @@ public class SplitTransitionTests extends ShellTestCase {
|
|||||||
mDisplayImeController, mDisplayInsetsController, mSplitLayout, mTransitions,
|
mDisplayImeController, mDisplayInsetsController, mSplitLayout, mTransitions,
|
||||||
mTransactionPool, mMainExecutor, Optional.empty(),
|
mTransactionPool, mMainExecutor, Optional.empty(),
|
||||||
mLaunchAdjacentController, Optional.empty());
|
mLaunchAdjacentController, Optional.empty());
|
||||||
|
mStageCoordinator.setMixedHandler(mMixedHandler);
|
||||||
mSplitScreenTransitions = mStageCoordinator.getSplitTransitions();
|
mSplitScreenTransitions = mStageCoordinator.getSplitTransitions();
|
||||||
doAnswer((Answer<IBinder>) invocation -> mock(IBinder.class))
|
doAnswer((Answer<IBinder>) invocation -> mock(IBinder.class))
|
||||||
.when(mTransitions).startTransition(anyInt(), any(), any());
|
.when(mTransitions).startTransition(anyInt(), any(), any());
|
||||||
|
|||||||
Reference in New Issue
Block a user