diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java index 1ba1d22e78311..122fc9f5f780c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java @@ -19,7 +19,6 @@ package com.android.wm.shell.splitscreen; import android.annotation.Nullable; import android.app.ActivityManager; import android.content.Context; -import android.graphics.Rect; import android.view.SurfaceSession; import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; @@ -45,11 +44,6 @@ class SideStage extends StageTaskListener { stageTaskUnfoldController); } - void moveToTop(Rect rootBounds, WindowContainerTransaction wct) { - final WindowContainerToken rootToken = mRootTaskInfo.token; - wct.setBounds(rootToken, rootBounds).reorder(rootToken, true /* onTop */); - } - boolean removeAllTasks(WindowContainerTransaction wct, boolean toTop) { // No matter if the root task is empty or not, moving the root to bottom because it no // longer preserves visible child task. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index dde470df13c98..e2bba76aa5604 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -375,6 +375,9 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, // Init divider first to make divider leash for remote animation target. mSplitLayout.init(); final WindowContainerTransaction wct = new WindowContainerTransaction(); + final WindowContainerTransaction evictWct = new WindowContainerTransaction(); + prepareEvictChildTasks(SPLIT_POSITION_TOP_OR_LEFT, evictWct); + prepareEvictChildTasks(SPLIT_POSITION_BOTTOM_OR_RIGHT, evictWct); // Need to add another wrapper here in shell so that we can inject the divider bar // and also manage the process elevation via setRunningRemote IRemoteAnimationRunner wrapper = new IRemoteAnimationRunner.Stub() { @@ -395,6 +398,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, new IRemoteAnimationFinishedCallback.Stub() { @Override public void onAnimationFinished() throws RemoteException { + mSyncQueue.queue(evictWct); mSyncQueue.runInSync(t -> setDividerVisibility(true, t)); finishedCallback.onAnimationFinished(); } @@ -416,6 +420,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, @Override public void onAnimationCancelled() { + mSyncQueue.queue(evictWct); mSyncQueue.runInSync(t -> setDividerVisibility(true, t)); try { adapter.getRunner().onAnimationCancelled(); @@ -439,10 +444,14 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, setSideStagePosition(sidePosition, wct); mSplitLayout.setDivideRatio(splitRatio); - // Build a request WCT that will launch both apps such that task 0 is on the main stage - // while task 1 is on the side stage. - mMainStage.activate(getMainStageBounds(), wct, false /* reparent */); - mSideStage.setBounds(getSideStageBounds(), wct); + if (mMainStage.isActive()) { + mMainStage.moveToTop(getMainStageBounds(), wct); + } else { + // Build a request WCT that will launch both apps such that task 0 is on the main stage + // while task 1 is on the side stage. + mMainStage.activate(getMainStageBounds(), wct, false /* reparent */); + } + mSideStage.moveToTop(getSideStageBounds(), wct); // Make sure the launch options will put tasks in the corresponding split roots addActivityOptions(mainOptions, mMainStage); @@ -899,6 +908,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, if (mDividerVisible) { t.show(dividerLeash); + t.setAlpha(dividerLeash, 1); t.setLayer(dividerLeash, SPLIT_DIVIDER_LAYER); t.setPosition(dividerLeash, mSplitLayout.getDividerBounds().left, mSplitLayout.getDividerBounds().top); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java index 2c853c1c474c6..04e20db369eff 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java @@ -34,6 +34,7 @@ import android.graphics.Rect; import android.util.SparseArray; import android.view.SurfaceControl; import android.view.SurfaceSession; +import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; import androidx.annotation.NonNull; @@ -304,6 +305,11 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { wct.reparent(task.token, mRootTaskInfo.token, true /* onTop*/); } + void moveToTop(Rect rootBounds, WindowContainerTransaction wct) { + final WindowContainerToken rootToken = mRootTaskInfo.token; + wct.setBounds(rootToken, rootBounds).reorder(rootToken, true /* onTop */); + } + void setBounds(Rect bounds, WindowContainerTransaction wct) { wct.setBounds(mRootTaskInfo.token, bounds); } diff --git a/services/core/java/com/android/server/wm/RunningTasks.java b/services/core/java/com/android/server/wm/RunningTasks.java index 1533245a75cab..d31b007c56afd 100644 --- a/services/core/java/com/android/server/wm/RunningTasks.java +++ b/services/core/java/com/android/server/wm/RunningTasks.java @@ -58,6 +58,7 @@ class RunningTasks { private boolean mAllowed; private boolean mFilterOnlyVisibleRecents; private Task mTopDisplayFocusRootTask; + private Task mTopDisplayAdjacentTask; private RecentTasks mRecentTasks; private boolean mKeepIntentExtra; @@ -81,6 +82,12 @@ class RunningTasks { mRecentTasks = root.mService.getRecentTasks(); mKeepIntentExtra = (flags & FLAG_KEEP_INTENT_EXTRA) == FLAG_KEEP_INTENT_EXTRA; + if (mTopDisplayFocusRootTask.getAdjacentTaskFragment() != null) { + mTopDisplayAdjacentTask = mTopDisplayFocusRootTask.getAdjacentTaskFragment().asTask(); + } else { + mTopDisplayAdjacentTask = null; + } + final PooledConsumer c = PooledLambda.obtainConsumer(RunningTasks::processTask, this, PooledLambda.__(Task.class)); root.forAllLeafTasks(c, false); @@ -130,6 +137,12 @@ class RunningTasks { // can be used to determine the order of the tasks (it may not be set for newly // created tasks) task.touchActiveTime(); + } else if (rootTask == mTopDisplayAdjacentTask && rootTask.getTopMostTask() == task) { + // The short-term workaround for launcher could get suitable running task info in + // split screen. + task.touchActiveTime(); + // TreeSet doesn't allow same value and make sure this task is lower than focus one. + task.lastActiveTime--; } mTmpSortedSet.add(task);