Fix split overlay by drag drop launch
When drag drop launch, wms will use animation leash to do launch transition, and reparent surface back and reset its position by windows its configuration. However, on split side we also set windows bounds in same time, so in some race condition, wms side reset its position later and use old configuration because we update it in same time then cause task surface position wrong. To fix this issue, we should apply windows bounds before we launch the intent. This CL also fix divider invisible issue when drag drop some specfic app to active split screen caused by surface tanscation race too. Fix: 227142506 Fix: 240638389 Test: manual Test: pass existing tests. Change-Id: Ia195f39fbf8879cbee9608f0c27f98df7e9e289f
This commit is contained in:
@@ -21,7 +21,6 @@ import static android.app.ActivityManager.START_TASK_TO_FRONT;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.view.RemoteAnimationTarget.MODE_OPENING;
|
||||
|
||||
import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
|
||||
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
|
||||
@@ -86,7 +85,6 @@ import com.android.wm.shell.splitscreen.SplitScreen.StageType;
|
||||
import com.android.wm.shell.sysui.KeyguardChangeListener;
|
||||
import com.android.wm.shell.sysui.ShellController;
|
||||
import com.android.wm.shell.sysui.ShellInit;
|
||||
import com.android.wm.shell.transition.LegacyTransitions;
|
||||
import com.android.wm.shell.transition.Transitions;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
@@ -411,62 +409,13 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
||||
}
|
||||
|
||||
if (!ENABLE_SHELL_TRANSITIONS) {
|
||||
startIntentLegacy(intent, fillInIntent, position, options);
|
||||
mStageCoordinator.startIntentLegacy(intent, fillInIntent, position, options);
|
||||
return;
|
||||
}
|
||||
|
||||
mStageCoordinator.startIntent(intent, fillInIntent, position, options);
|
||||
}
|
||||
|
||||
private void startIntentLegacy(PendingIntent intent, Intent fillInIntent,
|
||||
@SplitPosition int position, @Nullable Bundle options) {
|
||||
final WindowContainerTransaction evictWct = new WindowContainerTransaction();
|
||||
mStageCoordinator.prepareEvictChildTasks(position, evictWct);
|
||||
|
||||
LegacyTransitions.ILegacyTransition transition = new LegacyTransitions.ILegacyTransition() {
|
||||
@Override
|
||||
public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
|
||||
RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
|
||||
IRemoteAnimationFinishedCallback finishedCallback,
|
||||
SurfaceControl.Transaction t) {
|
||||
if (apps == null || apps.length == 0) {
|
||||
// Switch the split position if launching as MULTIPLE_TASK failed.
|
||||
if ((fillInIntent.getFlags() & FLAG_ACTIVITY_MULTIPLE_TASK) != 0) {
|
||||
setSideStagePosition(SplitLayout.reversePosition(
|
||||
mStageCoordinator.getSideStagePosition()));
|
||||
}
|
||||
|
||||
// Do nothing when the animation was cancelled.
|
||||
t.apply();
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < apps.length; ++i) {
|
||||
if (apps[i].mode == MODE_OPENING) {
|
||||
t.show(apps[i].leash);
|
||||
}
|
||||
}
|
||||
t.apply();
|
||||
|
||||
if (finishedCallback != null) {
|
||||
try {
|
||||
finishedCallback.onAnimationFinished();
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Error finishing legacy transition: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
mSyncQueue.queue(evictWct);
|
||||
}
|
||||
};
|
||||
|
||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
options = mStageCoordinator.resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, wct);
|
||||
|
||||
wct.sendPendingIntent(intent, fillInIntent, options);
|
||||
mSyncQueue.queue(transition, WindowManager.TRANSIT_OPEN, wct);
|
||||
}
|
||||
|
||||
/** Returns {@code true} if it's launching the same component on both sides of the split. */
|
||||
@VisibleForTesting
|
||||
boolean isLaunchingAdjacently(@Nullable Intent startIntent,
|
||||
|
||||
@@ -26,6 +26,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.view.RemoteAnimationTarget.MODE_OPENING;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
|
||||
import static android.view.WindowManager.TRANSIT_CHANGE;
|
||||
import static android.view.WindowManager.TRANSIT_TO_BACK;
|
||||
@@ -118,6 +119,7 @@ import com.android.wm.shell.protolog.ShellProtoLogGroup;
|
||||
import com.android.wm.shell.recents.RecentTasksController;
|
||||
import com.android.wm.shell.splitscreen.SplitScreen.StageType;
|
||||
import com.android.wm.shell.splitscreen.SplitScreenController.ExitReason;
|
||||
import com.android.wm.shell.transition.LegacyTransitions;
|
||||
import com.android.wm.shell.transition.Transitions;
|
||||
import com.android.wm.shell.util.SplitBounds;
|
||||
|
||||
@@ -195,7 +197,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
private boolean mExitSplitScreenOnHide;
|
||||
private boolean mIsDividerRemoteAnimating;
|
||||
private boolean mIsExiting;
|
||||
private boolean mResizingSplits;
|
||||
|
||||
/** The target stage to dismiss to when unlock after folded. */
|
||||
@StageType
|
||||
@@ -210,7 +211,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
|
||||
@Override
|
||||
public void onLeashReady(SurfaceControl leash) {
|
||||
mSyncQueue.runInSync(t -> applyDividerVisibility(t));
|
||||
// This is for avoiding divider invisible due to delay of creating so only need
|
||||
// to do when divider should visible case.
|
||||
if (mDividerVisible) {
|
||||
mSyncQueue.runInSync(t -> applyDividerVisibility(t));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -433,6 +438,63 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
});
|
||||
}
|
||||
|
||||
/** Launches an activity into split by legacy transition. */
|
||||
void startIntentLegacy(PendingIntent intent, Intent fillInIntent,
|
||||
@SplitPosition int position, @androidx.annotation.Nullable Bundle options) {
|
||||
final WindowContainerTransaction evictWct = new WindowContainerTransaction();
|
||||
prepareEvictChildTasks(position, evictWct);
|
||||
|
||||
LegacyTransitions.ILegacyTransition transition = new LegacyTransitions.ILegacyTransition() {
|
||||
@Override
|
||||
public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
|
||||
RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
|
||||
IRemoteAnimationFinishedCallback finishedCallback,
|
||||
SurfaceControl.Transaction t) {
|
||||
if (apps == null || apps.length == 0) {
|
||||
// Switch the split position if launching as MULTIPLE_TASK failed.
|
||||
if ((fillInIntent.getFlags() & FLAG_ACTIVITY_MULTIPLE_TASK) != 0) {
|
||||
setSideStagePosition(SplitLayout.reversePosition(
|
||||
getSideStagePosition()), null);
|
||||
}
|
||||
|
||||
// Do nothing when the animation was cancelled.
|
||||
t.apply();
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < apps.length; ++i) {
|
||||
if (apps[i].mode == MODE_OPENING) {
|
||||
t.show(apps[i].leash);
|
||||
}
|
||||
}
|
||||
t.apply();
|
||||
|
||||
if (finishedCallback != null) {
|
||||
try {
|
||||
finishedCallback.onAnimationFinished();
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Error finishing legacy transition: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
mSyncQueue.queue(evictWct);
|
||||
}
|
||||
};
|
||||
|
||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
options = resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, wct);
|
||||
|
||||
// If split still not active, apply windows bounds first to avoid surface reset to
|
||||
// wrong pos by SurfaceAnimator from wms.
|
||||
// TODO(b/223325631): check is it still necessary after improve enter transition done.
|
||||
if (!mMainStage.isActive()) {
|
||||
updateWindowBounds(mSplitLayout, wct);
|
||||
}
|
||||
|
||||
wct.sendPendingIntent(intent, fillInIntent, options);
|
||||
mSyncQueue.queue(transition, WindowManager.TRANSIT_OPEN, wct);
|
||||
}
|
||||
|
||||
/** Starts 2 tasks in one transition. */
|
||||
void startTasks(int mainTaskId, @Nullable Bundle mainOptions, int sideTaskId,
|
||||
@Nullable Bundle sideOptions, @SplitPosition int sidePosition, float splitRatio,
|
||||
@@ -849,6 +911,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
.setWindowCrop(mSideStage.mRootLeash, null);
|
||||
t.setPosition(mMainStage.mRootLeash, 0, 0)
|
||||
.setPosition(mSideStage.mRootLeash, 0, 0);
|
||||
t.hide(mMainStage.mDimLayer).hide(mSideStage.mDimLayer);
|
||||
setDividerVisibility(false, t);
|
||||
|
||||
// In this case, exit still under progress, fade out the split decor after first WCT
|
||||
@@ -858,7 +921,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
WindowContainerTransaction finishedWCT = new WindowContainerTransaction();
|
||||
mIsExiting = false;
|
||||
childrenToTop.dismiss(finishedWCT, true /* toTop */);
|
||||
wct.reorder(mRootTaskInfo.token, false /* toTop */);
|
||||
finishedWCT.reorder(mRootTaskInfo.token, false /* toTop */);
|
||||
mTaskOrganizer.applyTransaction(finishedWCT);
|
||||
onTransitionAnimationComplete();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user