Merge changes from topic "wdecor-split-changes" into udc-qpr-dev
* changes: Allow dragging through the status bar on split-screen tasks Calculate desktop mode launch bounds for tasks launched into split Propagate split's task info changes to window decorations
This commit is contained in:
@@ -205,8 +205,7 @@ public abstract class WMShellModule {
|
||||
SyncTransactionQueue syncQueue,
|
||||
Transitions transitions,
|
||||
Optional<DesktopModeController> desktopModeController,
|
||||
Optional<DesktopTasksController> desktopTasksController,
|
||||
Optional<SplitScreenController> splitScreenController) {
|
||||
Optional<DesktopTasksController> desktopTasksController) {
|
||||
if (DesktopModeStatus.isAnyEnabled()) {
|
||||
return new DesktopModeWindowDecorViewModel(
|
||||
context,
|
||||
@@ -217,8 +216,7 @@ public abstract class WMShellModule {
|
||||
syncQueue,
|
||||
transitions,
|
||||
desktopModeController,
|
||||
desktopTasksController,
|
||||
splitScreenController);
|
||||
desktopTasksController);
|
||||
}
|
||||
return new CaptionWindowDecorViewModel(
|
||||
context,
|
||||
@@ -336,11 +334,13 @@ public abstract class WMShellModule {
|
||||
IconProvider iconProvider,
|
||||
Optional<RecentTasksController> recentTasks,
|
||||
LaunchAdjacentController launchAdjacentController,
|
||||
Optional<WindowDecorViewModel> windowDecorViewModel,
|
||||
@ShellMainThread ShellExecutor mainExecutor) {
|
||||
return new SplitScreenController(context, shellInit, shellCommandHandler, shellController,
|
||||
shellTaskOrganizer, syncQueue, rootTaskDisplayAreaOrganizer, displayController,
|
||||
displayImeController, displayInsetsController, dragAndDropController, transitions,
|
||||
transactionPool, iconProvider, recentTasks, launchAdjacentController, mainExecutor);
|
||||
transactionPool, iconProvider, recentTasks, launchAdjacentController,
|
||||
windowDecorViewModel, mainExecutor);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -24,6 +24,9 @@ import android.window.WindowContainerTransaction;
|
||||
import com.android.launcher3.icons.IconProvider;
|
||||
import com.android.wm.shell.ShellTaskOrganizer;
|
||||
import com.android.wm.shell.common.SyncTransactionQueue;
|
||||
import com.android.wm.shell.windowdecor.WindowDecorViewModel;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Main stage for split-screen mode. When split-screen is active all standard activity types launch
|
||||
@@ -35,9 +38,10 @@ class MainStage extends StageTaskListener {
|
||||
|
||||
MainStage(Context context, ShellTaskOrganizer taskOrganizer, int displayId,
|
||||
StageListenerCallbacks callbacks, SyncTransactionQueue syncQueue,
|
||||
SurfaceSession surfaceSession, IconProvider iconProvider) {
|
||||
SurfaceSession surfaceSession, IconProvider iconProvider,
|
||||
Optional<WindowDecorViewModel> windowDecorViewModel) {
|
||||
super(context, taskOrganizer, displayId, callbacks, syncQueue, surfaceSession,
|
||||
iconProvider);
|
||||
iconProvider, windowDecorViewModel);
|
||||
}
|
||||
|
||||
boolean isActive() {
|
||||
|
||||
@@ -25,6 +25,9 @@ import android.window.WindowContainerTransaction;
|
||||
import com.android.launcher3.icons.IconProvider;
|
||||
import com.android.wm.shell.ShellTaskOrganizer;
|
||||
import com.android.wm.shell.common.SyncTransactionQueue;
|
||||
import com.android.wm.shell.windowdecor.WindowDecorViewModel;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Side stage for split-screen mode. Only tasks that are explicitly pinned to this stage show up
|
||||
@@ -37,9 +40,10 @@ class SideStage extends StageTaskListener {
|
||||
|
||||
SideStage(Context context, ShellTaskOrganizer taskOrganizer, int displayId,
|
||||
StageListenerCallbacks callbacks, SyncTransactionQueue syncQueue,
|
||||
SurfaceSession surfaceSession, IconProvider iconProvider) {
|
||||
SurfaceSession surfaceSession, IconProvider iconProvider,
|
||||
Optional<WindowDecorViewModel> windowDecorViewModel) {
|
||||
super(context, taskOrganizer, displayId, callbacks, syncQueue, surfaceSession,
|
||||
iconProvider);
|
||||
iconProvider, windowDecorViewModel);
|
||||
}
|
||||
|
||||
boolean removeAllTasks(WindowContainerTransaction wct, boolean toTop) {
|
||||
|
||||
@@ -94,6 +94,7 @@ import com.android.wm.shell.sysui.ShellCommandHandler;
|
||||
import com.android.wm.shell.sysui.ShellController;
|
||||
import com.android.wm.shell.sysui.ShellInit;
|
||||
import com.android.wm.shell.transition.Transitions;
|
||||
import com.android.wm.shell.windowdecor.WindowDecorViewModel;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -172,6 +173,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
||||
private final IconProvider mIconProvider;
|
||||
private final Optional<RecentTasksController> mRecentTasksOptional;
|
||||
private final LaunchAdjacentController mLaunchAdjacentController;
|
||||
private final Optional<WindowDecorViewModel> mWindowDecorViewModel;
|
||||
private final SplitScreenShellCommandHandler mSplitScreenShellCommandHandler;
|
||||
private final String[] mAppsSupportMultiInstances;
|
||||
|
||||
@@ -199,6 +201,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
||||
IconProvider iconProvider,
|
||||
Optional<RecentTasksController> recentTasks,
|
||||
LaunchAdjacentController launchAdjacentController,
|
||||
Optional<WindowDecorViewModel> windowDecorViewModel,
|
||||
ShellExecutor mainExecutor) {
|
||||
mShellCommandHandler = shellCommandHandler;
|
||||
mShellController = shellController;
|
||||
@@ -216,6 +219,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
||||
mIconProvider = iconProvider;
|
||||
mRecentTasksOptional = recentTasks;
|
||||
mLaunchAdjacentController = launchAdjacentController;
|
||||
mWindowDecorViewModel = windowDecorViewModel;
|
||||
mSplitScreenShellCommandHandler = new SplitScreenShellCommandHandler(this);
|
||||
// TODO(b/238217847): Temporarily add this check here until we can remove the dynamic
|
||||
// override for this controller from the base module
|
||||
@@ -246,6 +250,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
||||
IconProvider iconProvider,
|
||||
RecentTasksController recentTasks,
|
||||
LaunchAdjacentController launchAdjacentController,
|
||||
WindowDecorViewModel windowDecorViewModel,
|
||||
ShellExecutor mainExecutor,
|
||||
StageCoordinator stageCoordinator) {
|
||||
mShellCommandHandler = shellCommandHandler;
|
||||
@@ -264,6 +269,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
||||
mIconProvider = iconProvider;
|
||||
mRecentTasksOptional = Optional.of(recentTasks);
|
||||
mLaunchAdjacentController = launchAdjacentController;
|
||||
mWindowDecorViewModel = Optional.of(windowDecorViewModel);
|
||||
mStageCoordinator = stageCoordinator;
|
||||
mSplitScreenShellCommandHandler = new SplitScreenShellCommandHandler(this);
|
||||
shellInit.addInitCallback(this::onInit, this);
|
||||
@@ -296,13 +302,15 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
||||
mStageCoordinator = createStageCoordinator();
|
||||
}
|
||||
mDragAndDropController.ifPresent(controller -> controller.setSplitScreenController(this));
|
||||
mWindowDecorViewModel.ifPresent(viewModel -> viewModel.setSplitScreenController(this));
|
||||
}
|
||||
|
||||
protected StageCoordinator createStageCoordinator() {
|
||||
return new StageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue,
|
||||
mTaskOrganizer, mDisplayController, mDisplayImeController,
|
||||
mDisplayInsetsController, mTransitions, mTransactionPool,
|
||||
mIconProvider, mMainExecutor, mRecentTasksOptional, mLaunchAdjacentController);
|
||||
mDisplayInsetsController, mTransitions, mTransactionPool, mIconProvider,
|
||||
mMainExecutor, mRecentTasksOptional, mLaunchAdjacentController,
|
||||
mWindowDecorViewModel);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -141,6 +141,7 @@ import com.android.wm.shell.transition.LegacyTransitions;
|
||||
import com.android.wm.shell.transition.Transitions;
|
||||
import com.android.wm.shell.util.SplitBounds;
|
||||
import com.android.wm.shell.util.TransitionUtil;
|
||||
import com.android.wm.shell.windowdecor.WindowDecorViewModel;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
@@ -198,6 +199,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
private final ArrayList<Integer> mPausingTasks = new ArrayList<>();
|
||||
private final Optional<RecentTasksController> mRecentTasks;
|
||||
private final LaunchAdjacentController mLaunchAdjacentController;
|
||||
private final Optional<WindowDecorViewModel> mWindowDecorViewModel;
|
||||
|
||||
private final Rect mTempRect1 = new Rect();
|
||||
private final Rect mTempRect2 = new Rect();
|
||||
@@ -276,7 +278,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
TransactionPool transactionPool,
|
||||
IconProvider iconProvider, ShellExecutor mainExecutor,
|
||||
Optional<RecentTasksController> recentTasks,
|
||||
LaunchAdjacentController launchAdjacentController) {
|
||||
LaunchAdjacentController launchAdjacentController,
|
||||
Optional<WindowDecorViewModel> windowDecorViewModel) {
|
||||
mContext = context;
|
||||
mDisplayId = displayId;
|
||||
mSyncQueue = syncQueue;
|
||||
@@ -285,6 +288,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
mMainExecutor = mainExecutor;
|
||||
mRecentTasks = recentTasks;
|
||||
mLaunchAdjacentController = launchAdjacentController;
|
||||
mWindowDecorViewModel = windowDecorViewModel;
|
||||
|
||||
taskOrganizer.createRootTask(displayId, WINDOWING_MODE_FULLSCREEN, this /* listener */);
|
||||
|
||||
@@ -295,7 +299,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
mMainStageListener,
|
||||
mSyncQueue,
|
||||
mSurfaceSession,
|
||||
iconProvider);
|
||||
iconProvider,
|
||||
mWindowDecorViewModel);
|
||||
mSideStage = new SideStage(
|
||||
mContext,
|
||||
mTaskOrganizer,
|
||||
@@ -303,7 +308,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
mSideStageListener,
|
||||
mSyncQueue,
|
||||
mSurfaceSession,
|
||||
iconProvider);
|
||||
iconProvider,
|
||||
mWindowDecorViewModel);
|
||||
mDisplayController = displayController;
|
||||
mDisplayImeController = displayImeController;
|
||||
mDisplayInsetsController = displayInsetsController;
|
||||
@@ -332,7 +338,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
Transitions transitions, TransactionPool transactionPool,
|
||||
ShellExecutor mainExecutor,
|
||||
Optional<RecentTasksController> recentTasks,
|
||||
LaunchAdjacentController launchAdjacentController) {
|
||||
LaunchAdjacentController launchAdjacentController,
|
||||
Optional<WindowDecorViewModel> windowDecorViewModel) {
|
||||
mContext = context;
|
||||
mDisplayId = displayId;
|
||||
mSyncQueue = syncQueue;
|
||||
@@ -350,6 +357,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
mMainExecutor = mainExecutor;
|
||||
mRecentTasks = recentTasks;
|
||||
mLaunchAdjacentController = launchAdjacentController;
|
||||
mWindowDecorViewModel = windowDecorViewModel;
|
||||
mDisplayController.addDisplayWindowListener(this);
|
||||
mDisplayLayout = new DisplayLayout();
|
||||
transitions.addHandler(this);
|
||||
@@ -1705,7 +1713,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
if (mRootTaskInfo == null || mRootTaskInfo.taskId != taskInfo.taskId) {
|
||||
throw new IllegalArgumentException(this + "\n Unknown task info changed: " + taskInfo);
|
||||
}
|
||||
|
||||
mWindowDecorViewModel.ifPresent(viewModel -> viewModel.onTaskInfoChanged(taskInfo));
|
||||
mRootTaskInfo = taskInfo;
|
||||
if (mSplitLayout != null
|
||||
&& mSplitLayout.updateConfiguration(mRootTaskInfo.configuration)
|
||||
|
||||
@@ -51,8 +51,10 @@ import com.android.wm.shell.common.SurfaceUtils;
|
||||
import com.android.wm.shell.common.SyncTransactionQueue;
|
||||
import com.android.wm.shell.common.split.SplitDecorManager;
|
||||
import com.android.wm.shell.splitscreen.SplitScreen.StageType;
|
||||
import com.android.wm.shell.windowdecor.WindowDecorViewModel;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
@@ -87,6 +89,7 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
|
||||
private final SurfaceSession mSurfaceSession;
|
||||
private final SyncTransactionQueue mSyncQueue;
|
||||
private final IconProvider mIconProvider;
|
||||
private final Optional<WindowDecorViewModel> mWindowDecorViewModel;
|
||||
|
||||
protected ActivityManager.RunningTaskInfo mRootTaskInfo;
|
||||
protected SurfaceControl mRootLeash;
|
||||
@@ -98,12 +101,14 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
|
||||
|
||||
StageTaskListener(Context context, ShellTaskOrganizer taskOrganizer, int displayId,
|
||||
StageListenerCallbacks callbacks, SyncTransactionQueue syncQueue,
|
||||
SurfaceSession surfaceSession, IconProvider iconProvider) {
|
||||
SurfaceSession surfaceSession, IconProvider iconProvider,
|
||||
Optional<WindowDecorViewModel> windowDecorViewModel) {
|
||||
mContext = context;
|
||||
mCallbacks = callbacks;
|
||||
mSyncQueue = syncQueue;
|
||||
mSurfaceSession = surfaceSession;
|
||||
mIconProvider = iconProvider;
|
||||
mWindowDecorViewModel = windowDecorViewModel;
|
||||
taskOrganizer.createRootTask(displayId, WINDOWING_MODE_MULTI_WINDOW, this);
|
||||
}
|
||||
|
||||
@@ -200,6 +205,7 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
|
||||
@Override
|
||||
@CallSuper
|
||||
public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
|
||||
mWindowDecorViewModel.ifPresent(viewModel -> viewModel.onTaskInfoChanged(taskInfo));
|
||||
if (mRootTaskInfo.taskId == taskInfo.taskId) {
|
||||
// Inflates split decor view only when the root task is visible.
|
||||
if (!ENABLE_SHELL_TRANSITIONS && mRootTaskInfo.isVisible != taskInfo.isVisible) {
|
||||
|
||||
@@ -86,7 +86,8 @@ public class TvSplitScreenController extends SplitScreenController {
|
||||
super(context, shellInit, shellCommandHandler, shellController, shellTaskOrganizer,
|
||||
syncQueue, rootTDAOrganizer, displayController, displayImeController,
|
||||
displayInsetsController, dragAndDropController, transitions, transactionPool,
|
||||
iconProvider, recentTasks, launchAdjacentController, mainExecutor);
|
||||
iconProvider, recentTasks, launchAdjacentController, Optional.empty(),
|
||||
mainExecutor);
|
||||
|
||||
mTaskOrganizer = shellTaskOrganizer;
|
||||
mSyncQueue = syncQueue;
|
||||
|
||||
@@ -56,7 +56,7 @@ public class TvStageCoordinator extends StageCoordinator
|
||||
SystemWindows systemWindows) {
|
||||
super(context, displayId, syncQueue, taskOrganizer, displayController, displayImeController,
|
||||
displayInsetsController, transitions, transactionPool, iconProvider,
|
||||
mainExecutor, recentTasks, launchAdjacentController);
|
||||
mainExecutor, recentTasks, launchAdjacentController, Optional.empty());
|
||||
|
||||
mTvSplitMenuController = new TvSplitMenuController(context, this,
|
||||
systemWindows, mainHandler);
|
||||
|
||||
@@ -38,6 +38,7 @@ import com.android.wm.shell.ShellTaskOrganizer;
|
||||
import com.android.wm.shell.common.DisplayController;
|
||||
import com.android.wm.shell.common.SyncTransactionQueue;
|
||||
import com.android.wm.shell.freeform.FreeformTaskTransitionStarter;
|
||||
import com.android.wm.shell.splitscreen.SplitScreenController;
|
||||
import com.android.wm.shell.transition.Transitions;
|
||||
|
||||
/**
|
||||
@@ -88,6 +89,9 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
|
||||
mTaskOperations = new TaskOperations(transitionStarter, mContext, mSyncQueue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSplitScreenController(SplitScreenController splitScreenController) {}
|
||||
|
||||
@Override
|
||||
public boolean onTaskOpening(
|
||||
RunningTaskInfo taskInfo,
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.wm.shell.windowdecor;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
|
||||
|
||||
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;
|
||||
@@ -107,7 +108,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
|
||||
private final Supplier<SurfaceControl.Transaction> mTransactionFactory;
|
||||
private final Transitions mTransitions;
|
||||
|
||||
private Optional<SplitScreenController> mSplitScreenController;
|
||||
private SplitScreenController mSplitScreenController;
|
||||
|
||||
private ValueAnimator mDragToDesktopValueAnimator;
|
||||
private final Rect mDragToDesktopAnimationStartBounds = new Rect();
|
||||
@@ -122,8 +123,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
|
||||
SyncTransactionQueue syncQueue,
|
||||
Transitions transitions,
|
||||
Optional<DesktopModeController> desktopModeController,
|
||||
Optional<DesktopTasksController> desktopTasksController,
|
||||
Optional<SplitScreenController> splitScreenController) {
|
||||
Optional<DesktopTasksController> desktopTasksController) {
|
||||
this(
|
||||
context,
|
||||
mainHandler,
|
||||
@@ -134,7 +134,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
|
||||
transitions,
|
||||
desktopModeController,
|
||||
desktopTasksController,
|
||||
splitScreenController,
|
||||
new DesktopModeWindowDecoration.Factory(),
|
||||
new InputMonitorFactory(),
|
||||
SurfaceControl.Transaction::new);
|
||||
@@ -151,7 +150,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
|
||||
Transitions transitions,
|
||||
Optional<DesktopModeController> desktopModeController,
|
||||
Optional<DesktopTasksController> desktopTasksController,
|
||||
Optional<SplitScreenController> splitScreenController,
|
||||
DesktopModeWindowDecoration.Factory desktopModeWindowDecorFactory,
|
||||
InputMonitorFactory inputMonitorFactory,
|
||||
Supplier<SurfaceControl.Transaction> transactionFactory) {
|
||||
@@ -161,7 +159,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
|
||||
mActivityTaskManager = mContext.getSystemService(ActivityTaskManager.class);
|
||||
mTaskOrganizer = taskOrganizer;
|
||||
mDisplayController = displayController;
|
||||
mSplitScreenController = splitScreenController;
|
||||
mSyncQueue = syncQueue;
|
||||
mTransitions = transitions;
|
||||
mDesktopModeController = desktopModeController;
|
||||
@@ -177,6 +174,11 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
|
||||
mTaskOperations = new TaskOperations(transitionStarter, mContext, mSyncQueue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSplitScreenController(SplitScreenController splitScreenController) {
|
||||
mSplitScreenController = splitScreenController;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTaskOpening(
|
||||
ActivityManager.RunningTaskInfo taskInfo,
|
||||
@@ -239,7 +241,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
|
||||
SurfaceControl.Transaction startT,
|
||||
SurfaceControl.Transaction finishT) {
|
||||
final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId);
|
||||
|
||||
if (!shouldShowWindowDecor(taskInfo)) {
|
||||
if (decoration != null) {
|
||||
destroyWindowDecoration(taskInfo);
|
||||
@@ -304,14 +305,14 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
|
||||
final int id = v.getId();
|
||||
if (id == R.id.close_window || id == R.id.close_button) {
|
||||
mTaskOperations.closeTask(mTaskToken);
|
||||
if (mSplitScreenController.isPresent()
|
||||
&& mSplitScreenController.get().isSplitScreenVisible()) {
|
||||
int remainingTaskPosition = mTaskId == mSplitScreenController.get()
|
||||
if (mSplitScreenController != null
|
||||
&& mSplitScreenController.isSplitScreenVisible()) {
|
||||
int remainingTaskPosition = mTaskId == mSplitScreenController
|
||||
.getTaskInfo(SPLIT_POSITION_TOP_OR_LEFT).taskId
|
||||
? SPLIT_POSITION_BOTTOM_OR_RIGHT : SPLIT_POSITION_TOP_OR_LEFT;
|
||||
ActivityManager.RunningTaskInfo remainingTask = mSplitScreenController.get()
|
||||
ActivityManager.RunningTaskInfo remainingTask = mSplitScreenController
|
||||
.getTaskInfo(remainingTaskPosition);
|
||||
mSplitScreenController.get().moveTaskToFullscreen(remainingTask.taskId);
|
||||
mSplitScreenController.moveTaskToFullscreen(remainingTask.taskId);
|
||||
}
|
||||
} else if (id == R.id.back_button) {
|
||||
mTaskOperations.injectBackKey();
|
||||
@@ -555,9 +556,11 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
|
||||
relevantDecor.mTaskInfo.configuration.windowConfiguration.getBounds());
|
||||
boolean dragFromStatusBarAllowed = false;
|
||||
if (DesktopModeStatus.isProto2Enabled()) {
|
||||
// In proto2 any full screen task can be dragged to freeform
|
||||
dragFromStatusBarAllowed = relevantDecor.mTaskInfo.getWindowingMode()
|
||||
== WINDOWING_MODE_FULLSCREEN;
|
||||
// In proto2 any full screen or multi-window task can be dragged to
|
||||
// freeform.
|
||||
final int windowingMode = relevantDecor.mTaskInfo.getWindowingMode();
|
||||
dragFromStatusBarAllowed = windowingMode == WINDOWING_MODE_FULLSCREEN
|
||||
|| windowingMode == WINDOWING_MODE_MULTI_WINDOW;
|
||||
}
|
||||
|
||||
if (dragFromStatusBarAllowed && relevantDecor.checkTouchEventInHandle(ev)) {
|
||||
@@ -714,8 +717,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
|
||||
|
||||
@Nullable
|
||||
private DesktopModeWindowDecoration getRelevantWindowDecor(MotionEvent ev) {
|
||||
if (mSplitScreenController.isPresent()
|
||||
&& mSplitScreenController.get().isSplitScreenVisible()) {
|
||||
if (mSplitScreenController != null && mSplitScreenController.isSplitScreenVisible()) {
|
||||
// We can't look at focused task here as only one task will have focus.
|
||||
return getSplitScreenDecor(ev);
|
||||
} else {
|
||||
@@ -726,9 +728,9 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
|
||||
@Nullable
|
||||
private DesktopModeWindowDecoration getSplitScreenDecor(MotionEvent ev) {
|
||||
ActivityManager.RunningTaskInfo topOrLeftTask =
|
||||
mSplitScreenController.get().getTaskInfo(SPLIT_POSITION_TOP_OR_LEFT);
|
||||
mSplitScreenController.getTaskInfo(SPLIT_POSITION_TOP_OR_LEFT);
|
||||
ActivityManager.RunningTaskInfo bottomOrRightTask =
|
||||
mSplitScreenController.get().getTaskInfo(SPLIT_POSITION_BOTTOM_OR_RIGHT);
|
||||
mSplitScreenController.getTaskInfo(SPLIT_POSITION_BOTTOM_OR_RIGHT);
|
||||
if (topOrLeftTask != null && topOrLeftTask.getConfiguration()
|
||||
.windowConfiguration.getBounds().contains((int) ev.getX(), (int) ev.getY())) {
|
||||
return mWindowDecorByTaskId.get(topOrLeftTask.taskId);
|
||||
@@ -780,8 +782,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
|
||||
|
||||
private boolean shouldShowWindowDecor(RunningTaskInfo taskInfo) {
|
||||
if (taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) return true;
|
||||
if (mSplitScreenController.isPresent()
|
||||
&& mSplitScreenController.get().isTaskRootOrStageRoot(taskInfo.taskId)) {
|
||||
if (mSplitScreenController != null
|
||||
&& mSplitScreenController.isTaskRootOrStageRoot(taskInfo.taskId)) {
|
||||
return false;
|
||||
}
|
||||
return DesktopModeStatus.isProto2Enabled()
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.view.SurfaceControl;
|
||||
import android.window.TransitionInfo;
|
||||
|
||||
import com.android.wm.shell.freeform.FreeformTaskTransitionStarter;
|
||||
import com.android.wm.shell.splitscreen.SplitScreenController;
|
||||
|
||||
/**
|
||||
* The interface used by some {@link com.android.wm.shell.ShellTaskOrganizer.TaskListener} to help
|
||||
@@ -38,6 +39,11 @@ public interface WindowDecorViewModel {
|
||||
*/
|
||||
void setFreeformTaskTransitionStarter(FreeformTaskTransitionStarter transitionStarter);
|
||||
|
||||
/**
|
||||
* Sets the {@link SplitScreenController} if available.
|
||||
*/
|
||||
void setSplitScreenController(SplitScreenController splitScreenController);
|
||||
|
||||
/**
|
||||
* Creates a window decoration for the given task. Can be {@code null} for Fullscreen tasks but
|
||||
* not Freeform ones.
|
||||
|
||||
@@ -41,6 +41,8 @@ import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/** Tests for {@link MainStage} */
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@@ -61,7 +63,7 @@ public class MainStageTests extends ShellTestCase {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mRootTaskInfo = new TestRunningTaskInfoBuilder().build();
|
||||
mMainStage = new MainStage(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mCallbacks,
|
||||
mSyncQueue, mSurfaceSession, mIconProvider);
|
||||
mSyncQueue, mSurfaceSession, mIconProvider, Optional.empty());
|
||||
mMainStage.onTaskAppeared(mRootTaskInfo, mRootLeash);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,8 @@ import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.Spy;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/** Tests for {@link SideStage} */
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@@ -66,7 +68,7 @@ public class SideStageTests extends ShellTestCase {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mRootTask = new TestRunningTaskInfoBuilder().build();
|
||||
mSideStage = new SideStage(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mCallbacks,
|
||||
mSyncQueue, mSurfaceSession, mIconProvider);
|
||||
mSyncQueue, mSurfaceSession, mIconProvider, Optional.empty());
|
||||
mSideStage.onTaskAppeared(mRootTask, mRootLeash);
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ import com.android.wm.shell.sysui.ShellController;
|
||||
import com.android.wm.shell.sysui.ShellInit;
|
||||
import com.android.wm.shell.sysui.ShellSharedConstants;
|
||||
import com.android.wm.shell.transition.Transitions;
|
||||
import com.android.wm.shell.windowdecor.WindowDecorViewModel;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -104,6 +105,7 @@ public class SplitScreenControllerTests extends ShellTestCase {
|
||||
@Mock StageCoordinator mStageCoordinator;
|
||||
@Mock RecentTasksController mRecentTasks;
|
||||
@Mock LaunchAdjacentController mLaunchAdjacentController;
|
||||
@Mock WindowDecorViewModel mWindowDecorViewModel;
|
||||
@Captor ArgumentCaptor<Intent> mIntentCaptor;
|
||||
|
||||
private ShellController mShellController;
|
||||
@@ -119,8 +121,8 @@ public class SplitScreenControllerTests extends ShellTestCase {
|
||||
mShellCommandHandler, mShellController, mTaskOrganizer, mSyncQueue,
|
||||
mRootTDAOrganizer, mDisplayController, mDisplayImeController,
|
||||
mDisplayInsetsController, mDragAndDropController, mTransitions, mTransactionPool,
|
||||
mIconProvider, mRecentTasks, mLaunchAdjacentController, mMainExecutor,
|
||||
mStageCoordinator));
|
||||
mIconProvider, mRecentTasks, mLaunchAdjacentController, mWindowDecorViewModel,
|
||||
mMainExecutor, mStageCoordinator));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -38,6 +38,7 @@ import com.android.wm.shell.common.TransactionPool;
|
||||
import com.android.wm.shell.common.split.SplitLayout;
|
||||
import com.android.wm.shell.recents.RecentTasksController;
|
||||
import com.android.wm.shell.transition.Transitions;
|
||||
import com.android.wm.shell.windowdecor.WindowDecorViewModel;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -76,12 +77,14 @@ public class SplitTestUtils {
|
||||
DisplayController displayController, DisplayImeController imeController,
|
||||
DisplayInsetsController insetsController, SplitLayout splitLayout,
|
||||
Transitions transitions, TransactionPool transactionPool,
|
||||
ShellExecutor mainExecutor, Optional<RecentTasksController> recentTasks,
|
||||
LaunchAdjacentController launchAdjacentController) {
|
||||
ShellExecutor mainExecutor,
|
||||
Optional<RecentTasksController> recentTasks,
|
||||
LaunchAdjacentController launchAdjacentController,
|
||||
Optional<WindowDecorViewModel> windowDecorViewModel) {
|
||||
super(context, displayId, syncQueue, taskOrganizer, mainStage,
|
||||
sideStage, displayController, imeController, insetsController, splitLayout,
|
||||
transitions, transactionPool, mainExecutor, recentTasks,
|
||||
launchAdjacentController);
|
||||
launchAdjacentController, windowDecorViewModel);
|
||||
|
||||
// Prepare root task for testing.
|
||||
mRootTask = new TestRunningTaskInfoBuilder().build();
|
||||
|
||||
@@ -77,6 +77,7 @@ import com.android.wm.shell.common.TransactionPool;
|
||||
import com.android.wm.shell.common.split.SplitDecorManager;
|
||||
import com.android.wm.shell.common.split.SplitLayout;
|
||||
import com.android.wm.shell.transition.Transitions;
|
||||
import com.android.wm.shell.windowdecor.WindowDecorViewModel;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -101,6 +102,7 @@ public class SplitTransitionTests extends ShellTestCase {
|
||||
@Mock private Transitions mTransitions;
|
||||
@Mock private SurfaceSession mSurfaceSession;
|
||||
@Mock private IconProvider mIconProvider;
|
||||
@Mock private WindowDecorViewModel mWindowDecorViewModel;
|
||||
@Mock private ShellExecutor mMainExecutor;
|
||||
@Mock private LaunchAdjacentController mLaunchAdjacentController;
|
||||
private SplitLayout mSplitLayout;
|
||||
@@ -123,17 +125,17 @@ public class SplitTransitionTests extends ShellTestCase {
|
||||
mSplitLayout = SplitTestUtils.createMockSplitLayout();
|
||||
mMainStage = spy(new MainStage(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock(
|
||||
StageTaskListener.StageListenerCallbacks.class), mSyncQueue, mSurfaceSession,
|
||||
mIconProvider));
|
||||
mIconProvider, Optional.of(mWindowDecorViewModel)));
|
||||
mMainStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface());
|
||||
mSideStage = spy(new SideStage(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock(
|
||||
StageTaskListener.StageListenerCallbacks.class), mSyncQueue, mSurfaceSession,
|
||||
mIconProvider));
|
||||
mIconProvider, Optional.of(mWindowDecorViewModel)));
|
||||
mSideStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface());
|
||||
mStageCoordinator = new SplitTestUtils.TestStageCoordinator(mContext, DEFAULT_DISPLAY,
|
||||
mSyncQueue, mTaskOrganizer, mMainStage, mSideStage, mDisplayController,
|
||||
mDisplayImeController, mDisplayInsetsController, mSplitLayout, mTransitions,
|
||||
mTransactionPool, mMainExecutor, Optional.empty(),
|
||||
mLaunchAdjacentController);
|
||||
mLaunchAdjacentController, Optional.empty());
|
||||
mSplitScreenTransitions = mStageCoordinator.getSplitTransitions();
|
||||
doAnswer((Answer<IBinder>) invocation -> mock(IBinder.class))
|
||||
.when(mTransitions).startTransition(anyInt(), any(), any());
|
||||
|
||||
@@ -133,7 +133,7 @@ public class StageCoordinatorTests extends ShellTestCase {
|
||||
mStageCoordinator = spy(new StageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue,
|
||||
mTaskOrganizer, mMainStage, mSideStage, mDisplayController, mDisplayImeController,
|
||||
mDisplayInsetsController, mSplitLayout, mTransitions, mTransactionPool,
|
||||
mMainExecutor, Optional.empty(), mLaunchAdjacentController));
|
||||
mMainExecutor, Optional.empty(), mLaunchAdjacentController, Optional.empty()));
|
||||
mDividerLeash = new SurfaceControl.Builder(mSurfaceSession).setName("fakeDivider").build();
|
||||
|
||||
when(mSplitLayout.getBounds1()).thenReturn(mBounds1);
|
||||
|
||||
@@ -43,6 +43,7 @@ import com.android.wm.shell.ShellTaskOrganizer;
|
||||
import com.android.wm.shell.ShellTestCase;
|
||||
import com.android.wm.shell.TestRunningTaskInfoBuilder;
|
||||
import com.android.wm.shell.common.SyncTransactionQueue;
|
||||
import com.android.wm.shell.windowdecor.WindowDecorViewModel;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -52,6 +53,8 @@ import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Tests for {@link StageTaskListener}
|
||||
* Build/Install/Run:
|
||||
@@ -71,6 +74,8 @@ public final class StageTaskListenerTests extends ShellTestCase {
|
||||
private SyncTransactionQueue mSyncQueue;
|
||||
@Mock
|
||||
private IconProvider mIconProvider;
|
||||
@Mock
|
||||
private WindowDecorViewModel mWindowDecorViewModel;
|
||||
@Captor
|
||||
private ArgumentCaptor<SyncTransactionQueue.TransactionRunnable> mRunnableCaptor;
|
||||
private SurfaceSession mSurfaceSession = new SurfaceSession();
|
||||
@@ -89,7 +94,8 @@ public final class StageTaskListenerTests extends ShellTestCase {
|
||||
mCallbacks,
|
||||
mSyncQueue,
|
||||
mSurfaceSession,
|
||||
mIconProvider);
|
||||
mIconProvider,
|
||||
Optional.of(mWindowDecorViewModel));
|
||||
mRootTask = new TestRunningTaskInfoBuilder().build();
|
||||
mRootTask.parentTaskId = INVALID_TASK_ID;
|
||||
mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession).setName("test").build();
|
||||
|
||||
@@ -53,7 +53,6 @@ import com.android.wm.shell.common.DisplayLayout;
|
||||
import com.android.wm.shell.common.SyncTransactionQueue;
|
||||
import com.android.wm.shell.desktopmode.DesktopModeController;
|
||||
import com.android.wm.shell.desktopmode.DesktopTasksController;
|
||||
import com.android.wm.shell.splitscreen.SplitScreenController;
|
||||
import com.android.wm.shell.transition.Transitions;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -82,7 +81,6 @@ public class DesktopModeWindowDecorViewModelTests extends ShellTestCase {
|
||||
@Mock private ShellTaskOrganizer mTaskOrganizer;
|
||||
@Mock private DisplayController mDisplayController;
|
||||
@Mock private DisplayLayout mDisplayLayout;
|
||||
@Mock private SplitScreenController mSplitScreenController;
|
||||
@Mock private SyncTransactionQueue mSyncQueue;
|
||||
@Mock private DesktopModeController mDesktopModeController;
|
||||
@Mock private DesktopTasksController mDesktopTasksController;
|
||||
@@ -111,7 +109,6 @@ public class DesktopModeWindowDecorViewModelTests extends ShellTestCase {
|
||||
mTransitions,
|
||||
Optional.of(mDesktopModeController),
|
||||
Optional.of(mDesktopTasksController),
|
||||
Optional.of(mSplitScreenController),
|
||||
mDesktopModeWindowDecorFactory,
|
||||
mMockInputMonitorFactory,
|
||||
mTransactionFactory
|
||||
|
||||
@@ -80,8 +80,8 @@ public class DesktopModeLaunchParamsModifier implements LaunchParamsModifier {
|
||||
appendLog("not in bounds phase, skipping");
|
||||
return RESULT_SKIP;
|
||||
}
|
||||
if (!task.isActivityTypeStandard()) {
|
||||
appendLog("not standard activity type, skipping");
|
||||
if (!task.isActivityTypeStandardOrUndefined()) {
|
||||
appendLog("not standard or undefined activity type, skipping");
|
||||
return RESULT_SKIP;
|
||||
}
|
||||
if (!currentParams.mBounds.isEmpty()) {
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.server.wm;
|
||||
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
|
||||
import static android.util.DisplayMetrics.DENSITY_DEFAULT;
|
||||
|
||||
@@ -80,12 +81,26 @@ public class DesktopModeLaunchParamsModifierTests extends WindowTestsBase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnsSkipIfTaskNotUsingActivityTypeStandard() {
|
||||
public void testReturnsSkipIfTaskNotUsingActivityTypeStandardOrUndefined() {
|
||||
final Task task = new TaskBuilder(mSupervisor).setActivityType(
|
||||
ACTIVITY_TYPE_ASSISTANT).build();
|
||||
assertEquals(RESULT_SKIP, new CalculateRequestBuilder().setTask(task).calculate());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnsDoneIfTaskUsingActivityTypeStandard() {
|
||||
final Task task = new TaskBuilder(mSupervisor).setActivityType(
|
||||
ACTIVITY_TYPE_STANDARD).build();
|
||||
assertEquals(RESULT_DONE, new CalculateRequestBuilder().setTask(task).calculate());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnsDoneIfTaskUsingActivityTypeUndefined() {
|
||||
final Task task = new TaskBuilder(mSupervisor).setActivityType(
|
||||
ACTIVITY_TYPE_UNDEFINED).build();
|
||||
assertEquals(RESULT_DONE, new CalculateRequestBuilder().setTask(task).calculate());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnsSkipIfCurrentParamsHasBounds() {
|
||||
final Task task = new TaskBuilder(mSupervisor).setActivityType(
|
||||
|
||||
Reference in New Issue
Block a user