Merge "Fix drop to enter split not working" into sc-v2-dev

This commit is contained in:
Jerry Chang
2021-10-22 04:50:25 +00:00
committed by Android (Google) Code Review
4 changed files with 53 additions and 20 deletions

View File

@@ -215,10 +215,12 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
options = mStageCoordinator.resolveStartStage(stage, position, options, null /* wct */); options = mStageCoordinator.resolveStartStage(stage, position, options, null /* wct */);
try { try {
final WindowContainerTransaction evictWct = new WindowContainerTransaction();
mStageCoordinator.prepareEvictChildTasks(position, evictWct);
final int result = final int result =
ActivityTaskManager.getService().startActivityFromRecents(taskId, options); ActivityTaskManager.getService().startActivityFromRecents(taskId, options);
if (result == START_SUCCESS || result == START_TASK_TO_FRONT) { if (result == START_SUCCESS || result == START_TASK_TO_FRONT) {
mStageCoordinator.evictOccludedChildren(position); mSyncQueue.queue(evictWct);
} }
} catch (RemoteException e) { } catch (RemoteException e) {
Slog.e(TAG, "Failed to launch task", e); Slog.e(TAG, "Failed to launch task", e);
@@ -229,13 +231,15 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
@SplitScreen.StageType int stage, @SplitPosition int position, @SplitScreen.StageType int stage, @SplitPosition int position,
@Nullable Bundle options, UserHandle user) { @Nullable Bundle options, UserHandle user) {
options = mStageCoordinator.resolveStartStage(stage, position, options, null /* wct */); options = mStageCoordinator.resolveStartStage(stage, position, options, null /* wct */);
final WindowContainerTransaction evictWct = new WindowContainerTransaction();
mStageCoordinator.prepareEvictChildTasks(position, evictWct);
try { try {
LauncherApps launcherApps = LauncherApps launcherApps =
mContext.getSystemService(LauncherApps.class); mContext.getSystemService(LauncherApps.class);
launcherApps.startShortcut(packageName, shortcutId, null /* sourceBounds */, launcherApps.startShortcut(packageName, shortcutId, null /* sourceBounds */,
options, user); options, user);
mStageCoordinator.evictOccludedChildren(position); mSyncQueue.queue(evictWct);
} catch (ActivityNotFoundException e) { } catch (ActivityNotFoundException e) {
Slog.e(TAG, "Failed to launch shortcut", e); Slog.e(TAG, "Failed to launch shortcut", e);
} }
@@ -255,6 +259,9 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
private void startIntentLegacy(PendingIntent intent, Intent fillInIntent, private void startIntentLegacy(PendingIntent intent, Intent fillInIntent,
@SplitScreen.StageType int stage, @SplitPosition int position, @SplitScreen.StageType int stage, @SplitPosition int position,
@Nullable Bundle options) { @Nullable Bundle options) {
final WindowContainerTransaction evictWct = new WindowContainerTransaction();
mStageCoordinator.prepareEvictChildTasks(position, evictWct);
LegacyTransitions.ILegacyTransition transition = new LegacyTransitions.ILegacyTransition() { LegacyTransitions.ILegacyTransition transition = new LegacyTransitions.ILegacyTransition() {
@Override @Override
public void onAnimationStart(int transit, RemoteAnimationTarget[] apps, public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
@@ -280,12 +287,11 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
} }
} }
// Launching a new app into a specific split evicts tasks previously in the same mSyncQueue.queue(evictWct);
// split.
mStageCoordinator.evictOccludedChildren(position);
} }
}; };
WindowContainerTransaction wct = new WindowContainerTransaction();
final WindowContainerTransaction wct = new WindowContainerTransaction();
options = mStageCoordinator.resolveStartStage(stage, position, options, wct); options = mStageCoordinator.resolveStartStage(stage, position, options, wct);
wct.sendPendingIntent(intent, fillInIntent, options); wct.sendPendingIntent(intent, fillInIntent, options);
mSyncQueue.queue(transition, WindowManager.TRANSIT_OPEN, wct); mSyncQueue.queue(transition, WindowManager.TRANSIT_OPEN, wct);

View File

@@ -394,10 +394,16 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE, wct, remoteTransition, this); TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE, wct, remoteTransition, this);
} }
void evictOccludedChildren(@SplitPosition int position) { /**
final WindowContainerTransaction wct = new WindowContainerTransaction(); * Collects all the current child tasks of a specific split and prepares transaction to evict
(position == mSideStagePosition ? mSideStage : mMainStage).evictOccludedChildren(wct); * them to display.
mTaskOrganizer.applyTransaction(wct); */
void prepareEvictChildTasks(@SplitPosition int position, WindowContainerTransaction wct) {
if (position == mSideStagePosition) {
mSideStage.evictAllChildren(wct);
} else {
mMainStage.evictAllChildren(wct);
}
} }
Bundle resolveStartStage(@SplitScreen.StageType int stage, Bundle resolveStartStage(@SplitScreen.StageType int stage,

View File

@@ -248,12 +248,11 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
wct.reorder(mChildrenTaskInfo.get(taskId).token, onTop /* onTop */); wct.reorder(mChildrenTaskInfo.get(taskId).token, onTop /* onTop */);
} }
void evictOccludedChildren(WindowContainerTransaction wct) { /** Collects all the current child tasks and prepares transaction to evict them to display. */
void evictAllChildren(WindowContainerTransaction wct) {
for (int i = mChildrenTaskInfo.size() - 1; i >= 0; i--) { for (int i = mChildrenTaskInfo.size() - 1; i >= 0; i--) {
final ActivityManager.RunningTaskInfo taskInfo = mChildrenTaskInfo.valueAt(i); final ActivityManager.RunningTaskInfo taskInfo = mChildrenTaskInfo.valueAt(i);
if (!taskInfo.isVisible) { wct.reparent(taskInfo.token, null /* parent */, false /* onTop */);
wct.reparent(taskInfo.token, null /* parent */, false /* onTop */);
}
} }
} }

View File

@@ -21,6 +21,8 @@ import static android.view.Display.DEFAULT_DISPLAY;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeFalse; import static org.junit.Assume.assumeFalse;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.clearInvocations;
@@ -31,6 +33,7 @@ import android.app.ActivityManager;
import android.os.SystemProperties; import android.os.SystemProperties;
import android.view.SurfaceControl; import android.view.SurfaceControl;
import android.view.SurfaceSession; import android.view.SurfaceSession;
import android.window.WindowContainerTransaction;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
@@ -50,7 +53,7 @@ import org.mockito.MockitoAnnotations;
/** /**
* Tests for {@link StageTaskListener} * Tests for {@link StageTaskListener}
* Build/Install/Run: * Build/Install/Run:
* atest WMShellUnitTests:StageTaskListenerTests * atest WMShellUnitTests:StageTaskListenerTests
*/ */
@SmallTest @SmallTest
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
@@ -58,11 +61,16 @@ public final class StageTaskListenerTests {
private static final boolean ENABLE_SHELL_TRANSITIONS = private static final boolean ENABLE_SHELL_TRANSITIONS =
SystemProperties.getBoolean("persist.debug.shell_transit", false); SystemProperties.getBoolean("persist.debug.shell_transit", false);
@Mock private ShellTaskOrganizer mTaskOrganizer; @Mock
@Mock private StageTaskListener.StageListenerCallbacks mCallbacks; private ShellTaskOrganizer mTaskOrganizer;
@Mock private SyncTransactionQueue mSyncQueue; @Mock
@Mock private StageTaskUnfoldController mStageTaskUnfoldController; private StageTaskListener.StageListenerCallbacks mCallbacks;
@Captor private ArgumentCaptor<SyncTransactionQueue.TransactionRunnable> mRunnableCaptor; @Mock
private SyncTransactionQueue mSyncQueue;
@Mock
private StageTaskUnfoldController mStageTaskUnfoldController;
@Captor
private ArgumentCaptor<SyncTransactionQueue.TransactionRunnable> mRunnableCaptor;
private SurfaceSession mSurfaceSession = new SurfaceSession(); private SurfaceSession mSurfaceSession = new SurfaceSession();
private SurfaceControl mSurfaceControl; private SurfaceControl mSurfaceControl;
private ActivityManager.RunningTaskInfo mRootTask; private ActivityManager.RunningTaskInfo mRootTask;
@@ -167,4 +175,18 @@ public final class StageTaskListenerTests {
mStageTaskListener.onTaskInfoChanged(childTask); mStageTaskListener.onTaskInfoChanged(childTask);
verify(mCallbacks).onNoLongerSupportMultiWindow(); verify(mCallbacks).onNoLongerSupportMultiWindow();
} }
@Test
public void testEvictAllChildren() {
final WindowContainerTransaction wct = new WindowContainerTransaction();
mStageTaskListener.evictAllChildren(wct);
assertTrue(wct.isEmpty());
final ActivityManager.RunningTaskInfo childTask =
new TestRunningTaskInfoBuilder().setParentTaskId(mRootTask.taskId).build();
mStageTaskListener.onTaskAppeared(childTask, mSurfaceControl);
mStageTaskListener.evictAllChildren(wct);
assertFalse(wct.isEmpty());
}
} }