Merge "Enhance error handling logic to restore split-screen" into tm-qpr-dev

This commit is contained in:
TreeHugger Robot
2022-07-18 05:56:23 +00:00
committed by Android (Google) Code Review
4 changed files with 56 additions and 30 deletions

View File

@@ -500,7 +500,9 @@ public class ShellTaskOrganizer extends TaskOrganizer implements
|| (taskInfo.topActivityType == WindowConfiguration.ACTIVITY_TYPE_HOME
&& taskInfo.isVisible);
final boolean focusTaskChanged = (mLastFocusedTaskInfo == null
|| mLastFocusedTaskInfo.taskId != taskInfo.taskId) && isFocusedOrHome;
|| mLastFocusedTaskInfo.taskId != taskInfo.taskId
|| mLastFocusedTaskInfo.getWindowingMode() != taskInfo.getWindowingMode())
&& isFocusedOrHome;
if (focusTaskChanged) {
for (int i = 0; i < mFocusListeners.size(); i++) {
mFocusListeners.valueAt(i).onFocusTaskChanged(taskInfo);

View File

@@ -24,8 +24,6 @@ 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.CONTROLLED_ACTIVITY_TYPES;
import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
@@ -64,7 +62,6 @@ import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.InstanceId;
import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.ArrayUtils;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.ShellTaskOrganizer;
@@ -102,7 +99,7 @@ import java.util.concurrent.Executor;
*/
// TODO(b/198577848): Implement split screen flicker test to consolidate CUJ of split screen.
public class SplitScreenController implements DragAndDropPolicy.Starter,
RemoteCallable<SplitScreenController>, ShellTaskOrganizer.FocusListener {
RemoteCallable<SplitScreenController> {
private static final String TAG = SplitScreenController.class.getSimpleName();
public static final int EXIT_REASON_UNKNOWN = 0;
@@ -150,8 +147,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
// outside the bounds of the roots by being reparented into a higher level fullscreen container
private SurfaceControl mSplitTasksContainerLayer;
private ActivityManager.RunningTaskInfo mFocusingTaskInfo;
public SplitScreenController(ShellTaskOrganizer shellTaskOrganizer,
SyncTransactionQueue syncQueue, Context context,
RootTaskDisplayAreaOrganizer rootTDAOrganizer,
@@ -173,7 +168,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
mLogger = new SplitscreenEventLogger();
mIconProvider = iconProvider;
mRecentTasksOptional = recentTasks;
mTaskOrganizer.addFocusListener(this);
}
public SplitScreen asSplitScreen() {
@@ -190,11 +184,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
return mMainExecutor;
}
@Override
public void onFocusTaskChanged(ActivityManager.RunningTaskInfo taskInfo) {
mFocusingTaskInfo = taskInfo;
}
public void onOrganizerRegistered() {
if (mStageCoordinator == null) {
// TODO: Multi-display
@@ -213,6 +202,14 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
return mStageCoordinator;
}
public ActivityManager.RunningTaskInfo getFocusingTaskInfo() {
return mStageCoordinator.getFocusingTaskInfo();
}
public boolean isValidToEnterSplitScreen(@NonNull ActivityManager.RunningTaskInfo taskInfo) {
return mStageCoordinator.isValidToEnterSplitScreen(taskInfo);
}
@Nullable
public ActivityManager.RunningTaskInfo getTaskInfo(@SplitPosition int splitPosition) {
if (!isSplitScreenVisible() || splitPosition == SPLIT_POSITION_UNDEFINED) {
@@ -228,12 +225,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
&& mStageCoordinator.getStageOfTask(taskId) != STAGE_TYPE_UNDEFINED;
}
public boolean isValidToEnterSplitScreen(@NonNull ActivityManager.RunningTaskInfo taskInfo) {
return taskInfo.supportsMultiWindow
&& ArrayUtils.contains(CONTROLLED_ACTIVITY_TYPES, taskInfo.getActivityType())
&& ArrayUtils.contains(CONTROLLED_WINDOWING_MODES, taskInfo.getWindowingMode());
}
public @SplitPosition int getSplitPosition(int taskId) {
return mStageCoordinator.getSplitPosition(taskId);
}
@@ -470,8 +461,9 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
return Objects.equals(launchingActivity, pairedActivity);
}
if (mFocusingTaskInfo != null && isValidToEnterSplitScreen(mFocusingTaskInfo)) {
return Objects.equals(mFocusingTaskInfo.baseIntent.getComponent(), launchingActivity);
final ActivityManager.RunningTaskInfo taskInfo = getFocusingTaskInfo();
if (taskInfo != null && isValidToEnterSplitScreen(taskInfo)) {
return Objects.equals(taskInfo.baseIntent.getComponent(), launchingActivity);
}
return false;

View File

@@ -35,6 +35,8 @@ import static android.window.TransitionInfo.FLAG_IS_DISPLAY;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER;
import static com.android.wm.shell.common.split.SplitLayout.PARALLAX_ALIGN_CENTER;
import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES;
import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
@@ -98,6 +100,7 @@ import android.window.WindowContainerTransaction;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.InstanceId;
import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.ArrayUtils;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
@@ -138,7 +141,7 @@ import java.util.Optional;
*/
public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
DisplayController.OnDisplaysChangedListener, Transitions.TransitionHandler,
ShellTaskOrganizer.TaskListener {
ShellTaskOrganizer.TaskListener, ShellTaskOrganizer.FocusListener {
private static final String TAG = StageCoordinator.class.getSimpleName();
@@ -176,6 +179,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
private final Rect mTempRect1 = new Rect();
private final Rect mTempRect2 = new Rect();
private ActivityManager.RunningTaskInfo mFocusingTaskInfo;
/**
* A single-top root task which the split divider attached to.
*/
@@ -255,6 +260,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mDisplayController.addDisplayWindowListener(this);
mDisplayLayout = new DisplayLayout(displayController.getDisplayLayout(displayId));
transitions.addHandler(this);
mTaskOrganizer.addFocusListener(this);
}
@VisibleForTesting
@@ -1226,12 +1232,21 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
}
} else if (isSideStage && !mMainStage.isActive()) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
mSplitLayout.init();
prepareEnterSplitScreen(wct);
mSyncQueue.queue(wct);
mSyncQueue.runInSync(t ->
updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */));
if (mFocusingTaskInfo != null && !isValidToEnterSplitScreen(mFocusingTaskInfo)) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
mSideStage.removeAllTasks(wct, true);
wct.reorder(mRootTaskInfo.token, false /* onTop */);
mTaskOrganizer.applyTransaction(wct);
Slog.i(TAG, "cancel entering split screen, reason = "
+ exitReasonToString(EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW));
} else {
final WindowContainerTransaction wct = new WindowContainerTransaction();
mSplitLayout.init();
prepareEnterSplitScreen(wct);
mSyncQueue.queue(wct);
mSyncQueue.runInSync(t ->
updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */));
}
}
if (mMainStageListener.mHasChildren && mSideStageListener.mHasChildren) {
mShouldUpdateRecents = true;
@@ -1246,6 +1261,21 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
}
boolean isValidToEnterSplitScreen(@NonNull ActivityManager.RunningTaskInfo taskInfo) {
return taskInfo.supportsMultiWindow
&& ArrayUtils.contains(CONTROLLED_ACTIVITY_TYPES, taskInfo.getActivityType())
&& ArrayUtils.contains(CONTROLLED_WINDOWING_MODES, taskInfo.getWindowingMode());
}
ActivityManager.RunningTaskInfo getFocusingTaskInfo() {
return mFocusingTaskInfo;
}
@Override
public void onFocusTaskChanged(ActivityManager.RunningTaskInfo taskInfo) {
mFocusingTaskInfo = taskInfo;
}
@Override
public void onSnappedToDismiss(boolean bottomOrRight, int reason) {
final boolean mainStageToTop =

View File

@@ -24,6 +24,7 @@ import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSIT
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
@@ -90,12 +91,13 @@ public class SplitScreenControllerTests extends ShellTestCase {
@Test
public void testIsLaunchingAdjacently_notInSplitScreen() {
doReturn(false).when(mSplitScreenController).isSplitScreenVisible();
doReturn(true).when(mSplitScreenController).isValidToEnterSplitScreen(any());
// Verify launching the same activity returns true.
Intent startIntent = createStartIntent("startActivity");
ActivityManager.RunningTaskInfo focusTaskInfo =
createTaskInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, startIntent);
mSplitScreenController.onFocusTaskChanged(focusTaskInfo);
doReturn(focusTaskInfo).when(mSplitScreenController).getFocusingTaskInfo();
assertTrue(mSplitScreenController.isLaunchingAdjacently(
startIntent, SPLIT_POSITION_TOP_OR_LEFT));
@@ -103,7 +105,7 @@ public class SplitScreenControllerTests extends ShellTestCase {
Intent diffIntent = createStartIntent("diffActivity");
focusTaskInfo =
createTaskInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, diffIntent);
mSplitScreenController.onFocusTaskChanged(focusTaskInfo);
doReturn(focusTaskInfo).when(mSplitScreenController).getFocusingTaskInfo();
assertFalse(mSplitScreenController.isLaunchingAdjacently(
startIntent, SPLIT_POSITION_TOP_OR_LEFT));
}