From da230cf526bd48b8114b45e8d39dce5df2d7b4ee Mon Sep 17 00:00:00 2001 From: Jeremy Sim Date: Mon, 11 Sep 2023 21:59:56 -0700 Subject: [PATCH] Request split launches using a new enum, snapPosition, rather than a float splitRatio Split ratios are now stored as an int enum rather than float values. Previously, split ratios were stored as floats, which needed to be recalculated frequently and differed depending on device screen size. Now Shell to store and launch split screen setups using an enum rather than floats. Bug: 274835596 Bug: 182839788 Test: Existing tests still pass Change-Id: Iebb8d3c7e8f9d597a59b677e48072300ddea458f --- .../uioverrides/QuickstepLauncher.java | 8 +- .../android/quickstep/RecentTasksList.java | 13 +-- .../quickstep/RecentsAnimationCallbacks.java | 3 +- .../quickstep/RecentsAnimationTargets.java | 5 +- .../quickstep/RemoteAnimationTargets.java | 11 ++- .../android/quickstep/RemoteTargetGluer.java | 70 +++++++--------- .../com/android/quickstep/SystemUiProxy.java | 52 ++++++------ .../com/android/quickstep/TaskViewUtils.java | 3 +- .../quickstep/util/SplitScreenUtils.kt | 59 ++++++++++++++ .../util/SplitSelectStateController.java | 81 ++++++++++--------- .../quickstep/util/TaskViewSimulator.java | 16 +--- .../quickstep/views/GroupedTaskView.java | 32 +++++--- .../util/SplitSelectStateControllerTest.kt | 8 +- .../util/SplitConfigurationOptions.java | 10 +-- 14 files changed, 213 insertions(+), 158 deletions(-) create mode 100644 quickstep/src/com/android/quickstep/util/SplitScreenUtils.kt diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index 175611747b..40909d5b12 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -50,9 +50,9 @@ import static com.android.launcher3.testing.shared.TestProtocol.QUICK_SWITCH_STA import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN; import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; -import static com.android.launcher3.util.SplitConfigurationOptions.DEFAULT_SPLIT_RATIO; import static com.android.quickstep.util.SplitAnimationTimings.TABLET_HOME_TO_SPLIT; import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY; +import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_50_50; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -1260,10 +1260,8 @@ public class QuickstepLauncher extends Launcher { /* callback= */ success -> mSplitSelectStateController.resetState(), /* freezeTaskList= */ true, groupTask.mSplitBounds == null - ? DEFAULT_SPLIT_RATIO - : groupTask.mSplitBounds.appsStackedVertically - ? groupTask.mSplitBounds.topTaskPercent - : groupTask.mSplitBounds.leftTaskPercent); + ? SNAP_TO_50_50 + : groupTask.mSplitBounds.snapPosition); } /** diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java index 1c74fbedc7..0a7344a3c0 100644 --- a/quickstep/src/com/android/quickstep/RecentTasksList.java +++ b/quickstep/src/com/android/quickstep/RecentTasksList.java @@ -17,6 +17,7 @@ package com.android.quickstep; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; +import static com.android.quickstep.util.SplitScreenUtils.convertShellSplitBoundsToLauncher; import static com.android.quickstep.views.DesktopTaskView.DESKTOP_MODE_SUPPORTED; import static com.android.wm.shell.util.GroupedRecentTaskInfo.TYPE_FREEFORM; @@ -39,7 +40,6 @@ import com.android.quickstep.util.GroupTask; import com.android.systemui.shared.recents.model.Task; import com.android.wm.shell.recents.IRecentTasksListener; import com.android.wm.shell.util.GroupedRecentTaskInfo; -import com.android.wm.shell.util.SplitBounds; import java.io.PrintWriter; import java.util.ArrayList; @@ -293,7 +293,7 @@ public class RecentTasksList { task2.setLastSnapshotData(taskInfo2); } final SplitConfigurationOptions.SplitBounds launcherSplitBounds = - convertSplitBounds(rawTask.getSplitBounds()); + convertShellSplitBoundsToLauncher(rawTask.getSplitBounds()); allTasks.add(new GroupTask(task1, task2, launcherSplitBounds)); } @@ -313,15 +313,6 @@ public class RecentTasksList { return new DesktopTask(tasks); } - private SplitConfigurationOptions.SplitBounds convertSplitBounds( - SplitBounds shellSplitBounds) { - return shellSplitBounds == null ? - null : - new SplitConfigurationOptions.SplitBounds( - shellSplitBounds.leftTopBounds, shellSplitBounds.rightBottomBounds, - shellSplitBounds.leftTopTaskId, shellSplitBounds.rightBottomTaskId); - } - private ArrayList copyOf(ArrayList tasks) { ArrayList newTasks = new ArrayList<>(); for (int i = 0; i < tasks.size(); i++) { diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java index d300cc57c2..bbcea6c4cb 100644 --- a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java +++ b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java @@ -138,7 +138,8 @@ public class RecentsAnimationCallbacks implements nonAppTargets = new RemoteAnimationTarget[0]; } final RecentsAnimationTargets targets = new RecentsAnimationTargets(appTargets, - wallpaperTargets, nonAppTargets, homeContentInsets, minimizedHomeBounds); + wallpaperTargets, nonAppTargets, homeContentInsets, minimizedHomeBounds, + extras); Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> { ActiveGestureLog.INSTANCE.addLog( diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java b/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java index 15e1365998..67c56e39eb 100644 --- a/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java +++ b/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java @@ -20,6 +20,7 @@ import static android.view.RemoteAnimationTarget.MODE_CLOSING; import android.app.WindowConfiguration; import android.graphics.Rect; +import android.os.Bundle; import android.view.RemoteAnimationTarget; import com.android.quickstep.views.DesktopTaskView; @@ -35,8 +36,8 @@ public class RecentsAnimationTargets extends RemoteAnimationTargets { public RecentsAnimationTargets(RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps, - Rect homeContentInsets, Rect minimizedHomeBounds) { - super(apps, wallpapers, nonApps, MODE_CLOSING); + Rect homeContentInsets, Rect minimizedHomeBounds, Bundle extras) { + super(apps, wallpapers, nonApps, MODE_CLOSING, extras); this.homeContentInsets = homeContentInsets; this.minimizedHomeBounds = minimizedHomeBounds; } diff --git a/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java b/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java index 80aaad0dd9..e0c7403181 100644 --- a/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java +++ b/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java @@ -19,6 +19,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; +import android.os.Bundle; import android.view.RemoteAnimationTarget; import java.util.ArrayList; @@ -35,6 +36,7 @@ public class RemoteAnimationTargets { public final RemoteAnimationTarget[] apps; public final RemoteAnimationTarget[] wallpapers; public final RemoteAnimationTarget[] nonApps; + public final Bundle extras; public final int targetMode; public final boolean hasRecents; @@ -42,7 +44,7 @@ public class RemoteAnimationTargets { public RemoteAnimationTargets(RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps, - int targetMode) { + int targetMode, Bundle extras) { ArrayList filteredApps = new ArrayList<>(); boolean hasRecents = false; if (apps != null) { @@ -61,6 +63,13 @@ public class RemoteAnimationTargets { this.targetMode = targetMode; this.hasRecents = hasRecents; this.nonApps = nonApps; + this.extras = extras; + } + + public RemoteAnimationTargets(RemoteAnimationTarget[] apps, + RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps, + int targetMode) { + this(apps, wallpapers, nonApps, targetMode, new Bundle()); } public RemoteAnimationTarget findTask(int taskId) { diff --git a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java index 84246e93c0..3af5ab7583 100644 --- a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java +++ b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java @@ -16,7 +16,9 @@ package com.android.quickstep; -import android.app.WindowConfiguration; +import static com.android.quickstep.util.SplitScreenUtils.convertShellSplitBoundsToLauncher; +import static com.android.wm.shell.util.SplitBounds.KEY_EXTRA_SPLIT_BOUNDS; + import android.content.Context; import android.graphics.Rect; import android.util.Log; @@ -24,11 +26,12 @@ import android.view.RemoteAnimationTarget; import androidx.annotation.Nullable; -import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds; +import com.android.launcher3.util.SplitConfigurationOptions; import com.android.quickstep.util.AnimatorControllerWithResistance; import com.android.quickstep.util.TaskViewSimulator; import com.android.quickstep.util.TransformParams; import com.android.quickstep.views.DesktopTaskView; +import com.android.wm.shell.util.SplitBounds; import java.util.ArrayList; import java.util.Arrays; @@ -43,7 +46,7 @@ public class RemoteTargetGluer { private static final int DEFAULT_NUM_HANDLES = 2; private RemoteTargetHandle[] mRemoteTargetHandles; - private SplitBounds mSplitBounds; + private SplitConfigurationOptions.SplitBounds mSplitBounds; /** * Use this constructor if remote targets are split-screen independent @@ -110,6 +113,16 @@ public class RemoteTargetGluer { return mRemoteTargetHandles; } + /** + * Calls {@link #assignTargetsForSplitScreen(RemoteAnimationTargets)} with SplitBounds + * information specified. + */ + public RemoteTargetHandle[] assignTargetsForSplitScreen(RemoteAnimationTargets targets, + SplitConfigurationOptions.SplitBounds splitBounds) { + mSplitBounds = splitBounds; + return assignTargetsForSplitScreen(targets); + } + /** * Similar to {@link #assignTargets(RemoteAnimationTargets)}, except this assigns the * apps in {@code targets.apps} to the {@link #mRemoteTargetHandles} with index 0 will being @@ -129,10 +142,17 @@ public class RemoteTargetGluer { mRemoteTargetHandles = newHandles; } - boolean containsSplitTargets = Arrays.stream(targets.apps) - .anyMatch(remoteAnimationTarget -> - remoteAnimationTarget.windowConfiguration.getWindowingMode() - == WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW); + // If we are in a true split screen case (2 apps running on screen), either: + // a) mSplitBounds was already set (from the clicked GroupedTaskView) + // b) A SplitBounds was passed up from shell (via AbsSwipeUpHandler) + // If both of these are null, we are in a 1-app or 1-app-plus-assistant case. + if (mSplitBounds == null) { + SplitBounds shellSplitBounds = targets.extras.getParcelable(KEY_EXTRA_SPLIT_BOUNDS, + SplitBounds.class); + mSplitBounds = convertShellSplitBoundsToLauncher(shellSplitBounds); + } + + boolean containsSplitTargets = mSplitBounds != null; Log.d(TAG, "containsSplitTargets? " + containsSplitTargets + " handleLength: " + mRemoteTargetHandles.length + " appsLength: " + targets.apps.length); @@ -154,40 +174,12 @@ public class RemoteTargetGluer { } } else { // Split apps (+ maybe assistant) - RemoteAnimationTarget topLeftTarget = Arrays.stream(targets.apps) - .filter(remoteAnimationTarget -> - remoteAnimationTarget.windowConfiguration.getWindowingMode() - == WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW) - .findFirst().get(); - - // Fetch the adjacent target for split screen. - RemoteAnimationTarget bottomRightTarget = null; - for (int i = 0; i < targets.apps.length; i++) { - final RemoteAnimationTarget target = targets.apps[i]; - if (target.windowConfiguration.getWindowingMode() != - WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW || - target == topLeftTarget) { - continue; - } - Rect topLeftBounds = getStartBounds(topLeftTarget); - Rect bounds = getStartBounds(target); - if (topLeftBounds.left > bounds.right || topLeftBounds.top > bounds.bottom) { - bottomRightTarget = topLeftTarget; - topLeftTarget = target; - break; - } else if (topLeftBounds.right < bounds.left || topLeftBounds.bottom < bounds.top) { - bottomRightTarget = target; - break; - } - } + RemoteAnimationTarget topLeftTarget = targets.findTask(mSplitBounds.leftTopTaskId); + RemoteAnimationTarget bottomRightTarget = targets.findTask( + mSplitBounds.rightBottomTaskId); // remoteTargetHandle[0] denotes topLeft task, so we pass in the bottomRight to exclude, // vice versa - mSplitBounds = new SplitBounds( - getStartBounds(topLeftTarget), - getStartBounds(bottomRightTarget), - topLeftTarget.taskId, - bottomRightTarget.taskId); mRemoteTargetHandles[0].mTransformParams.setTargetSet( createRemoteAnimationTargetsForTarget(targets, bottomRightTarget)); mRemoteTargetHandles[0].mTaskViewSimulator.setPreview(topLeftTarget, @@ -291,7 +283,7 @@ public class RemoteTargetGluer { return mRemoteTargetHandles; } - public SplitBounds getSplitBounds() { + public SplitConfigurationOptions.SplitBounds getSplitBounds() { return mSplitBounds; } diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java index 1dc777d8cd..170847d6a3 100644 --- a/quickstep/src/com/android/quickstep/SystemUiProxy.java +++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java @@ -19,6 +19,7 @@ import static android.app.ActivityManager.RECENT_IGNORE_UNAVAILABLE; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; +import static com.android.launcher3.util.SplitConfigurationOptions.StagePosition; import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.RECENT_TASKS_MISSING; import static com.android.quickstep.util.LogUtils.splitFailureMessage; @@ -63,7 +64,6 @@ import com.android.internal.util.ScreenshotRequest; import com.android.internal.view.AppearanceRegion; import com.android.launcher3.util.MainThreadInitializedObject; import com.android.launcher3.util.Preconditions; -import com.android.launcher3.util.SplitConfigurationOptions; import com.android.quickstep.util.ActiveGestureLog; import com.android.quickstep.util.AssistUtils; import com.android.systemui.shared.recents.ISystemUiProxy; @@ -78,6 +78,7 @@ import com.android.systemui.unfold.progress.IUnfoldTransitionListener; import com.android.wm.shell.back.IBackAnimation; import com.android.wm.shell.bubbles.IBubbles; import com.android.wm.shell.bubbles.IBubblesListener; +import com.android.wm.shell.common.split.SplitScreenConstants.SnapPosition; import com.android.wm.shell.desktopmode.IDesktopMode; import com.android.wm.shell.desktopmode.IDesktopTaskListener; import com.android.wm.shell.draganddrop.IDragAndDrop; @@ -796,12 +797,12 @@ public class SystemUiProxy implements ISystemUiProxy { /** Start multiple tasks in split-screen simultaneously. */ public void startTasks(int taskId1, Bundle options1, int taskId2, Bundle options2, - @SplitConfigurationOptions.StagePosition int splitPosition, float splitRatio, + @StagePosition int splitPosition, @SnapPosition int snapPosition, RemoteTransition remoteTransition, InstanceId instanceId) { if (mSystemUiProxy != null) { try { mSplitScreen.startTasks(taskId1, options1, taskId2, options2, splitPosition, - splitRatio, remoteTransition, instanceId); + snapPosition, remoteTransition, instanceId); } catch (RemoteException e) { Log.w(TAG, splitFailureMessage("startTasks", "RemoteException"), e); } @@ -809,12 +810,13 @@ public class SystemUiProxy implements ISystemUiProxy { } public void startIntentAndTask(PendingIntent pendingIntent, int userId1, Bundle options1, - int taskId, Bundle options2, @SplitConfigurationOptions.StagePosition int splitPosition, - float splitRatio, RemoteTransition remoteTransition, InstanceId instanceId) { + int taskId, Bundle options2, @StagePosition int splitPosition, + @SnapPosition int snapPosition, RemoteTransition remoteTransition, + InstanceId instanceId) { if (mSystemUiProxy != null) { try { mSplitScreen.startIntentAndTask(pendingIntent, userId1, options1, taskId, options2, - splitPosition, splitRatio, remoteTransition, instanceId); + splitPosition, snapPosition, remoteTransition, instanceId); } catch (RemoteException e) { Log.w(TAG, splitFailureMessage("startIntentAndTask", "RemoteException"), e); } @@ -824,13 +826,13 @@ public class SystemUiProxy implements ISystemUiProxy { public void startIntents(PendingIntent pendingIntent1, int userId1, @Nullable ShortcutInfo shortcutInfo1, Bundle options1, PendingIntent pendingIntent2, int userId2, @Nullable ShortcutInfo shortcutInfo2, Bundle options2, - @SplitConfigurationOptions.StagePosition int splitPosition, float splitRatio, + @StagePosition int splitPosition, @SnapPosition int snapPosition, RemoteTransition remoteTransition, InstanceId instanceId) { if (mSystemUiProxy != null) { try { mSplitScreen.startIntents(pendingIntent1, userId1, shortcutInfo1, options1, - pendingIntent2, userId2, shortcutInfo2, options2, splitPosition, splitRatio, - remoteTransition, instanceId); + pendingIntent2, userId2, shortcutInfo2, options2, splitPosition, + snapPosition, remoteTransition, instanceId); } catch (RemoteException e) { Log.w(TAG, splitFailureMessage("startIntents", "RemoteException"), e); } @@ -838,12 +840,12 @@ public class SystemUiProxy implements ISystemUiProxy { } public void startShortcutAndTask(ShortcutInfo shortcutInfo, Bundle options1, int taskId, - Bundle options2, @SplitConfigurationOptions.StagePosition int splitPosition, - float splitRatio, RemoteTransition remoteTransition, InstanceId instanceId) { + Bundle options2, @StagePosition int splitPosition, @SnapPosition int snapPosition, + RemoteTransition remoteTransition, InstanceId instanceId) { if (mSystemUiProxy != null) { try { mSplitScreen.startShortcutAndTask(shortcutInfo, options1, taskId, options2, - splitPosition, splitRatio, remoteTransition, instanceId); + splitPosition, snapPosition, remoteTransition, instanceId); } catch (RemoteException e) { Log.w(TAG, splitFailureMessage("startShortcutAndTask", "RemoteException"), e); } @@ -854,12 +856,12 @@ public class SystemUiProxy implements ISystemUiProxy { * Start multiple tasks in split-screen simultaneously. */ public void startTasksWithLegacyTransition(int taskId1, Bundle options1, int taskId2, - Bundle options2, @SplitConfigurationOptions.StagePosition int splitPosition, - float splitRatio, RemoteAnimationAdapter adapter, InstanceId instanceId) { + Bundle options2, @StagePosition int splitPosition, @SnapPosition int snapPosition, + RemoteAnimationAdapter adapter, InstanceId instanceId) { if (mSystemUiProxy != null) { try { mSplitScreen.startTasksWithLegacyTransition(taskId1, options1, taskId2, options2, - splitPosition, splitRatio, adapter, instanceId); + splitPosition, snapPosition, adapter, instanceId); } catch (RemoteException e) { Log.w(TAG, splitFailureMessage( "startTasksWithLegacyTransition", "RemoteException"), e); @@ -868,13 +870,13 @@ public class SystemUiProxy implements ISystemUiProxy { } public void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent, int userId1, - Bundle options1, int taskId, Bundle options2, - @SplitConfigurationOptions.StagePosition int splitPosition, float splitRatio, - RemoteAnimationAdapter adapter, InstanceId instanceId) { + Bundle options1, int taskId, Bundle options2, @StagePosition int splitPosition, + @SnapPosition int snapPosition, RemoteAnimationAdapter adapter, InstanceId instanceId) { if (mSystemUiProxy != null) { try { mSplitScreen.startIntentAndTaskWithLegacyTransition(pendingIntent, userId1, - options1, taskId, options2, splitPosition, splitRatio, adapter, instanceId); + options1, taskId, options2, splitPosition, snapPosition, adapter, + instanceId); } catch (RemoteException e) { Log.w(TAG, splitFailureMessage( "startIntentAndTaskWithLegacyTransition", "RemoteException"), e); @@ -883,12 +885,12 @@ public class SystemUiProxy implements ISystemUiProxy { } public void startShortcutAndTaskWithLegacyTransition(ShortcutInfo shortcutInfo, Bundle options1, - int taskId, Bundle options2, @SplitConfigurationOptions.StagePosition int splitPosition, - float splitRatio, RemoteAnimationAdapter adapter, InstanceId instanceId) { + int taskId, Bundle options2, @StagePosition int splitPosition, + @SnapPosition int snapPosition, RemoteAnimationAdapter adapter, InstanceId instanceId) { if (mSystemUiProxy != null) { try { mSplitScreen.startShortcutAndTaskWithLegacyTransition(shortcutInfo, options1, - taskId, options2, splitPosition, splitRatio, adapter, instanceId); + taskId, options2, splitPosition, snapPosition, adapter, instanceId); } catch (RemoteException e) { Log.w(TAG, splitFailureMessage( "startShortcutAndTaskWithLegacyTransition", "RemoteException"), e); @@ -903,13 +905,13 @@ public class SystemUiProxy implements ISystemUiProxy { public void startIntentsWithLegacyTransition(PendingIntent pendingIntent1, int userId1, @Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1, PendingIntent pendingIntent2, int userId2, @Nullable ShortcutInfo shortcutInfo2, - @Nullable Bundle options2, @SplitConfigurationOptions.StagePosition int sidePosition, - float splitRatio, RemoteAnimationAdapter adapter, InstanceId instanceId) { + @Nullable Bundle options2, @StagePosition int sidePosition, + @SnapPosition int snapPosition, RemoteAnimationAdapter adapter, InstanceId instanceId) { if (mSystemUiProxy != null) { try { mSplitScreen.startIntentsWithLegacyTransition(pendingIntent1, userId1, shortcutInfo1, options1, pendingIntent2, userId2, shortcutInfo2, options2, - sidePosition, splitRatio, adapter, instanceId); + sidePosition, snapPosition, adapter, instanceId); } catch (RemoteException e) { Log.w(TAG, splitFailureMessage( "startIntentsWithLegacyTransition", "RemoteException"), e); diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java index 97e484a71a..34965df28b 100644 --- a/quickstep/src/com/android/quickstep/TaskViewUtils.java +++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java @@ -191,7 +191,8 @@ public final class TaskViewUtils { if (forDesktop) { remoteTargetHandles = gluer.assignTargetsForDesktop(targets); } else if (v.containsMultipleTasks()) { - remoteTargetHandles = gluer.assignTargetsForSplitScreen(targets); + remoteTargetHandles = gluer.assignTargetsForSplitScreen(targets, + ((GroupedTaskView) v).getSplitBoundsConfig()); } else { remoteTargetHandles = gluer.assignTargets(targets); } diff --git a/quickstep/src/com/android/quickstep/util/SplitScreenUtils.kt b/quickstep/src/com/android/quickstep/util/SplitScreenUtils.kt new file mode 100644 index 0000000000..596bb47861 --- /dev/null +++ b/quickstep/src/com/android/quickstep/util/SplitScreenUtils.kt @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.quickstep.util + +import com.android.launcher3.util.SplitConfigurationOptions +import com.android.wm.shell.util.SplitBounds + +class SplitScreenUtils { + companion object { + // TODO(b/254378592): Remove these methods when the two classes are reunited + /** Converts the shell version of SplitBounds to the launcher version */ + @JvmStatic + fun convertShellSplitBoundsToLauncher( + shellSplitBounds: SplitBounds? + ): SplitConfigurationOptions.SplitBounds? { + return if (shellSplitBounds == null) { + null + } else { + SplitConfigurationOptions.SplitBounds( + shellSplitBounds.leftTopBounds, shellSplitBounds.rightBottomBounds, + shellSplitBounds.leftTopTaskId, shellSplitBounds.rightBottomTaskId, + shellSplitBounds.snapPosition + ) + } + } + + /** Converts the launcher version of SplitBounds to the shell version */ + @JvmStatic + fun convertLauncherSplitBoundsToShell( + launcherSplitBounds: SplitConfigurationOptions.SplitBounds? + ): SplitBounds? { + return if (launcherSplitBounds == null) { + null + } else { + SplitBounds( + launcherSplitBounds.leftTopBounds, + launcherSplitBounds.rightBottomBounds, + launcherSplitBounds.leftTopTaskId, + launcherSplitBounds.rightBottomTaskId, + launcherSplitBounds.snapPosition + ) + } + } + } +} \ No newline at end of file diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java index 16fe07dfea..c8831c7db9 100644 --- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java +++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java @@ -22,7 +22,6 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_DESKTOP_MODE_SPLIT_RIGHT_BOTTOM; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; -import static com.android.launcher3.util.SplitConfigurationOptions.DEFAULT_SPLIT_RATIO; import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT; import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_PENDINGINTENT_PENDINGINTENT; import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_PENDINGINTENT_TASK; @@ -33,6 +32,7 @@ import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_SINGLE_TASK import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_TASK_PENDINGINTENT; import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_TASK_SHORTCUT; import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_TASK_TASK; +import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_50_50; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -98,6 +98,7 @@ import com.android.quickstep.views.SplitInstructionsView; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.RemoteAnimationRunnerCompat; +import com.android.wm.shell.common.split.SplitScreenConstants.SnapPosition; import com.android.wm.shell.splitscreen.ISplitSelectListener; import java.io.PrintWriter; @@ -288,11 +289,11 @@ public class SplitSelectStateController { * To be called when the both split tasks are ready to be launched. Call after launcher side * animations are complete. */ - public void launchSplitTasks(@Nullable Consumer callback) { + public void launchSplitTasks(@SnapPosition int snapPosition, + @Nullable Consumer callback) { Pair instanceIds = LogUtils.getShellShareableInstanceId(); - launchTasks(callback, false /* freezeTaskList */, DEFAULT_SPLIT_RATIO, - instanceIds.first); + launchTasks(callback, false /* freezeTaskList */, snapPosition, instanceIds.first); mStatsLogManager.logger() .withItemInfo(mSplitSelectDataHolder.getItemInfo()) @@ -301,11 +302,18 @@ public class SplitSelectStateController { } /** - * A version of {@link #launchTasks(Consumer, boolean, float, InstanceId)} with no success - * callback. + * A version of {@link #launchSplitTasks(int, Consumer)} that launches with default split ratio. + */ + public void launchSplitTasks(@Nullable Consumer callback) { + launchSplitTasks(SNAP_TO_50_50, callback); + } + + /** + * A version of {@link #launchSplitTasks(int, Consumer)} that launches with a default split + * ratio and no callback. */ public void launchSplitTasks() { - launchSplitTasks(null); + launchSplitTasks(SNAP_TO_50_50, null); } /** @@ -342,7 +350,7 @@ public class SplitSelectStateController { * foreground (quickswitch, launching previous pairs from overview) */ public void launchTasks(@Nullable Consumer callback, boolean freezeTaskList, - float splitRatio, @Nullable InstanceId shellInstanceId) { + @SnapPosition int snapPosition, @Nullable InstanceId shellInstanceId) { TestLogging.recordEvent( TestProtocol.SEQUENCE_MAIN, "launchSplitTasks"); final ActivityOptions options1 = ActivityOptions.makeBasic(); @@ -369,33 +377,33 @@ public class SplitSelectStateController { switch (launchData.getSplitLaunchType()) { case SPLIT_TASK_TASK -> mSystemUiProxy.startTasks(firstTaskId, optionsBundle, secondTaskId, - null /* options2 */, initialStagePosition, splitRatio, + null /* options2 */, initialStagePosition, snapPosition, remoteTransition, shellInstanceId); case SPLIT_TASK_PENDINGINTENT -> mSystemUiProxy.startIntentAndTask(secondPI, secondUserId, optionsBundle, - firstTaskId, null /*options2*/, initialStagePosition, splitRatio, + firstTaskId, null /*options2*/, initialStagePosition, snapPosition, remoteTransition, shellInstanceId); case SPLIT_TASK_SHORTCUT -> mSystemUiProxy.startShortcutAndTask(secondShortcut, optionsBundle, - firstTaskId, null /*options2*/, initialStagePosition, splitRatio, + firstTaskId, null /*options2*/, initialStagePosition, snapPosition, remoteTransition, shellInstanceId); case SPLIT_PENDINGINTENT_TASK -> mSystemUiProxy.startIntentAndTask(firstPI, firstUserId, optionsBundle, - secondTaskId, null /*options2*/, initialStagePosition, splitRatio, + secondTaskId, null /*options2*/, initialStagePosition, snapPosition, remoteTransition, shellInstanceId); case SPLIT_PENDINGINTENT_PENDINGINTENT -> mSystemUiProxy.startIntents(firstPI, firstUserId, firstShortcut, optionsBundle, secondPI, secondUserId, secondShortcut, - null /*options2*/, initialStagePosition, splitRatio, + null /*options2*/, initialStagePosition, snapPosition, remoteTransition, shellInstanceId); case SPLIT_SHORTCUT_TASK -> mSystemUiProxy.startShortcutAndTask(firstShortcut, optionsBundle, - secondTaskId, null /*options2*/, initialStagePosition, splitRatio, + secondTaskId, null /*options2*/, initialStagePosition, snapPosition, remoteTransition, shellInstanceId); } } else { @@ -405,40 +413,40 @@ public class SplitSelectStateController { case SPLIT_TASK_TASK -> mSystemUiProxy.startTasksWithLegacyTransition(firstTaskId, optionsBundle, secondTaskId, null /* options2 */, initialStagePosition, - splitRatio, adapter, shellInstanceId); + snapPosition, adapter, shellInstanceId); case SPLIT_TASK_PENDINGINTENT -> mSystemUiProxy.startIntentAndTaskWithLegacyTransition(secondPI, secondUserId, optionsBundle, firstTaskId, null /*options2*/, - initialStagePosition, splitRatio, adapter, shellInstanceId); + initialStagePosition, snapPosition, adapter, shellInstanceId); case SPLIT_TASK_SHORTCUT -> mSystemUiProxy.startShortcutAndTaskWithLegacyTransition(secondShortcut, optionsBundle, firstTaskId, null /*options2*/, initialStagePosition, - splitRatio, adapter, shellInstanceId); + snapPosition, adapter, shellInstanceId); case SPLIT_PENDINGINTENT_TASK -> mSystemUiProxy.startIntentAndTaskWithLegacyTransition(firstPI, firstUserId, optionsBundle, secondTaskId, null /*options2*/, - initialStagePosition, splitRatio, adapter, shellInstanceId); + initialStagePosition, snapPosition, adapter, shellInstanceId); case SPLIT_PENDINGINTENT_PENDINGINTENT -> mSystemUiProxy.startIntentsWithLegacyTransition(firstPI, firstUserId, firstShortcut, optionsBundle, secondPI, secondUserId, - secondShortcut, null /*options2*/, initialStagePosition, splitRatio, - adapter, shellInstanceId); + secondShortcut, null /*options2*/, initialStagePosition, + snapPosition, adapter, shellInstanceId); case SPLIT_SHORTCUT_TASK -> mSystemUiProxy.startShortcutAndTaskWithLegacyTransition(firstShortcut, optionsBundle, secondTaskId, null /*options2*/, - initialStagePosition, splitRatio, adapter, shellInstanceId); + initialStagePosition, snapPosition, adapter, shellInstanceId); } } } /** * Used to launch split screen from a split pair that already exists (usually accessible through - * Overview). This is different than {@link #launchTasks(Consumer, boolean, float, InstanceId)} + * Overview). This is different than {@link #launchTasks(Consumer, boolean, int, InstanceId)} * in that this only launches split screen that are existing tasks. This doesn't determine which * API should be used (i.e. launching split with existing tasks vs intents vs shortcuts, etc). * @@ -447,7 +455,7 @@ public class SplitSelectStateController { */ public void launchExistingSplitPair(@Nullable GroupedTaskView groupedTaskView, int firstTaskId, int secondTaskId, @StagePosition int stagePosition, - Consumer callback, boolean freezeTaskList, float splitRatio) { + Consumer callback, boolean freezeTaskList, @SnapPosition int snapPosition) { mLaunchingTaskView = groupedTaskView; final ActivityOptions options1 = ActivityOptions.makeBasic(); if (freezeTaskList) { @@ -458,21 +466,20 @@ public class SplitSelectStateController { if (TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) { final RemoteTransition remoteTransition = getShellRemoteTransition(firstTaskId, secondTaskId, callback, "LaunchExistingPair"); - mSystemUiProxy.startTasks(firstTaskId, optionsBundle, secondTaskId, - null /* options2 */, stagePosition, splitRatio, - remoteTransition, null /*shellInstanceId*/); + mSystemUiProxy.startTasks(firstTaskId, optionsBundle, secondTaskId, null /* options2 */, + stagePosition, snapPosition, remoteTransition, null /*shellInstanceId*/); } else { final RemoteAnimationAdapter adapter = getLegacyRemoteAdapter(firstTaskId, secondTaskId, callback); - mSystemUiProxy.startTasksWithLegacyTransition(firstTaskId, optionsBundle, - secondTaskId, null /* options2 */, stagePosition, - splitRatio, adapter, null /*shellInstanceId*/); + mSystemUiProxy.startTasksWithLegacyTransition(firstTaskId, optionsBundle, secondTaskId, + null /* options2 */, stagePosition, snapPosition, adapter, + null /*shellInstanceId*/); } } /** * Launches the initially selected task/intent in fullscreen (note the same SystemUi APIs are - * used as {@link #launchSplitTasks(Consumer)} because they are overloaded to launch both + * used as {@link #launchSplitTasks(int, Consumer)} because they are overloaded to launch both * split and fullscreen tasks) */ public void launchInitialAppFullscreen(Consumer callback) { @@ -497,14 +504,13 @@ public class SplitSelectStateController { switch (launchData.getSplitLaunchType()) { case SPLIT_SINGLE_TASK_FULLSCREEN -> mSystemUiProxy.startTasks(firstTaskId, optionsBundle, secondTaskId, null /* options2 */, initialStagePosition, - DEFAULT_SPLIT_RATIO, remoteTransition, instanceId); + SNAP_TO_50_50, remoteTransition, instanceId); case SPLIT_SINGLE_INTENT_FULLSCREEN -> mSystemUiProxy.startIntentAndTask(firstPI, firstUserId, optionsBundle, secondTaskId, null /*options2*/, - initialStagePosition, DEFAULT_SPLIT_RATIO, remoteTransition, - instanceId); + initialStagePosition, SNAP_TO_50_50, remoteTransition, instanceId); case SPLIT_SINGLE_SHORTCUT_FULLSCREEN -> mSystemUiProxy.startShortcutAndTask( initialShortcut, optionsBundle, firstTaskId, null /* options2 */, - initialStagePosition, DEFAULT_SPLIT_RATIO, remoteTransition, instanceId); + initialStagePosition, SNAP_TO_50_50, remoteTransition, instanceId); } } else { final RemoteAnimationAdapter adapter = getLegacyRemoteAdapter(firstTaskId, @@ -512,16 +518,15 @@ public class SplitSelectStateController { switch (launchData.getSplitLaunchType()) { case SPLIT_SINGLE_TASK_FULLSCREEN -> mSystemUiProxy.startTasksWithLegacyTransition( firstTaskId, optionsBundle, secondTaskId, null /* options2 */, - initialStagePosition, DEFAULT_SPLIT_RATIO, adapter, instanceId); + initialStagePosition, SNAP_TO_50_50, adapter, instanceId); case SPLIT_SINGLE_INTENT_FULLSCREEN -> mSystemUiProxy.startIntentAndTaskWithLegacyTransition(firstPI, firstUserId, optionsBundle, secondTaskId, null /*options2*/, - initialStagePosition, DEFAULT_SPLIT_RATIO, adapter, - instanceId); + initialStagePosition, SNAP_TO_50_50, adapter, instanceId); case SPLIT_SINGLE_SHORTCUT_FULLSCREEN -> mSystemUiProxy.startShortcutAndTaskWithLegacyTransition( initialShortcut, optionsBundle, firstTaskId, null /* options2 */, - initialStagePosition, DEFAULT_SPLIT_RATIO, adapter, instanceId); + initialStagePosition, SNAP_TO_50_50, adapter, instanceId); } } } diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java index b9ff272b04..510044d338 100644 --- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java +++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java @@ -26,6 +26,7 @@ import static com.android.launcher3.util.SplitConfigurationOptions.StagePosition import static com.android.quickstep.TaskAnimationManager.ENABLE_SHELL_TRANSITIONS; import static com.android.quickstep.util.RecentsOrientedState.postDisplayRotation; import static com.android.quickstep.util.RecentsOrientedState.preDisplayRotation; +import static com.android.quickstep.util.SplitScreenUtils.convertLauncherSplitBoundsToShell; import android.animation.TimeInterpolator; import android.content.Context; @@ -210,7 +211,8 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy { mStagePosition = mThumbnailPosition.equals(splitInfo.leftTopBounds) ? STAGE_POSITION_TOP_OR_LEFT : STAGE_POSITION_BOTTOM_OR_RIGHT; - mPositionHelper.setSplitBounds(convertSplitBounds(mSplitBounds), mStagePosition); + mPositionHelper.setSplitBounds(convertLauncherSplitBoundsToShell(mSplitBounds), + mStagePosition); } /** @@ -435,16 +437,4 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy { // Ideally we should use square-root. This is an optimization as one of the dimension is 0. return Math.max(Math.abs(mTempPoint[0]), Math.abs(mTempPoint[1])); } - - /** - * TODO(b/254378592): Remove this after consolidation of classes - */ - public static com.android.wm.shell.util.SplitBounds convertSplitBounds(SplitBounds bounds) { - return new com.android.wm.shell.util.SplitBounds( - bounds.leftTopBounds, - bounds.rightBottomBounds, - bounds.leftTopTaskId, - bounds.rightBottomTaskId - ); - } } diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java index 01f6ae8d5c..7e58763b15 100644 --- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java +++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java @@ -2,8 +2,8 @@ package com.android.quickstep.views; import static android.app.ActivityTaskManager.INVALID_TASK_ID; -import static com.android.launcher3.util.SplitConfigurationOptions.DEFAULT_SPLIT_RATIO; import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT; +import static com.android.quickstep.util.SplitScreenUtils.convertLauncherSplitBoundsToShell; import android.content.Context; import android.graphics.PointF; @@ -28,11 +28,11 @@ import com.android.quickstep.TaskThumbnailCache; import com.android.quickstep.util.CancellableTask; import com.android.quickstep.util.RecentsOrientedState; import com.android.quickstep.util.SplitSelectStateController; -import com.android.quickstep.util.TaskViewSimulator; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.recents.utilities.PreviewPositionHelper; import com.android.systemui.shared.system.InteractionJankMonitorWrapper; +import com.android.wm.shell.common.split.SplitScreenConstants.SnapPosition; import java.util.HashMap; import java.util.function.Consumer; @@ -114,11 +114,11 @@ public class GroupedTaskView extends TaskView { if (mSplitBoundsConfig == null) { return; } - mSnapshotView.getPreviewPositionHelper().setSplitBounds(TaskViewSimulator - .convertSplitBounds(splitBoundsConfig), + mSnapshotView.getPreviewPositionHelper().setSplitBounds( + convertLauncherSplitBoundsToShell(splitBoundsConfig), PreviewPositionHelper.STAGE_POSITION_TOP_OR_LEFT); - mSnapshotView2.getPreviewPositionHelper().setSplitBounds(TaskViewSimulator - .convertSplitBounds(splitBoundsConfig), + mSnapshotView2.getPreviewPositionHelper().setSplitBounds( + convertLauncherSplitBoundsToShell(splitBoundsConfig), PreviewPositionHelper.STAGE_POSITION_BOTTOM_OR_RIGHT); } @@ -180,12 +180,20 @@ public class GroupedTaskView extends TaskView { invalidate(); } - public float getSplitRatio() { - if (mSplitBoundsConfig != null) { - return mSplitBoundsConfig.appsStackedVertically - ? mSplitBoundsConfig.topTaskPercent : mSplitBoundsConfig.leftTaskPercent; + @Nullable + public SplitBounds getSplitBoundsConfig() { + return mSplitBoundsConfig; + } + + /** + * Returns the {@link SnapPosition} of this pair of tasks. + */ + public int getSnapPosition() { + if (mSplitBoundsConfig == null) { + throw new IllegalStateException("mSplitBoundsConfig is null"); } - return DEFAULT_SPLIT_RATIO; + + return mSplitBoundsConfig.snapPosition; } @Override @@ -251,7 +259,7 @@ public class GroupedTaskView extends TaskView { getRecentsView().getSplitSelectController().launchExistingSplitPair( launchingExistingTaskView ? this : null, mTask.key.id, mSecondaryTask.key.id, SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT, - callback, isQuickswitch, getSplitRatio()); + callback, isQuickswitch, getSnapPosition()); } @Override diff --git a/quickstep/tests/src/com/android/quickstep/util/SplitSelectStateControllerTest.kt b/quickstep/tests/src/com/android/quickstep/util/SplitSelectStateControllerTest.kt index 4e7fcf07d9..f19874169b 100644 --- a/quickstep/tests/src/com/android/quickstep/util/SplitSelectStateControllerTest.kt +++ b/quickstep/tests/src/com/android/quickstep/util/SplitSelectStateControllerTest.kt @@ -20,7 +20,6 @@ package com.android.quickstep.util import android.app.ActivityManager import android.app.PendingIntent import android.content.ComponentName -import android.content.Context import android.content.Intent import android.graphics.Rect import android.os.Handler @@ -38,7 +37,7 @@ import com.android.launcher3.util.withArgCaptor import com.android.quickstep.RecentsModel import com.android.quickstep.SystemUiProxy import com.android.systemui.shared.recents.model.Task -import java.util.function.Consumer +import com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_50_50 import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertNull @@ -50,6 +49,7 @@ import org.mockito.Mock import org.mockito.Mockito.verify import org.mockito.Mockito.`when` import org.mockito.MockitoAnnotations +import java.util.function.Consumer @RunWith(AndroidJUnit4::class) class SplitSelectStateControllerTest { @@ -560,7 +560,7 @@ class SplitSelectStateControllerTest { return GroupTask( task1, task2, - SplitConfigurationOptions.SplitBounds(Rect(), Rect(), -1, -1) + SplitConfigurationOptions.SplitBounds(Rect(), Rect(), -1, -1, SNAP_TO_50_50) ) } @@ -592,7 +592,7 @@ class SplitSelectStateControllerTest { return GroupTask( task1, task2, - SplitConfigurationOptions.SplitBounds(Rect(), Rect(), -1, -1) + SplitConfigurationOptions.SplitBounds(Rect(), Rect(), -1, -1, SNAP_TO_50_50) ) } } diff --git a/src/com/android/launcher3/util/SplitConfigurationOptions.java b/src/com/android/launcher3/util/SplitConfigurationOptions.java index 1ae43d000b..f4a022544c 100644 --- a/src/com/android/launcher3/util/SplitConfigurationOptions.java +++ b/src/com/android/launcher3/util/SplitConfigurationOptions.java @@ -77,11 +77,6 @@ public final class SplitConfigurationOptions { public @interface StageType {} /////////////////////////////////// - /** - * Default split ratio for launching app pair from overview. - */ - public static final float DEFAULT_SPLIT_RATIO = 0.5f; - public static class SplitPositionOption { public final int iconResId; public final int textResId; @@ -116,6 +111,8 @@ public final class SplitConfigurationOptions { public final float leftTaskPercent; public final float dividerWidthPercent; public final float dividerHeightPercent; + public final int snapPosition; + /** * If {@code true}, that means at the time of creation of this object, the * split-screened apps were vertically stacked. This is useful in scenarios like @@ -135,11 +132,12 @@ public final class SplitConfigurationOptions { public final int rightBottomTaskId; public SplitBounds(Rect leftTopBounds, Rect rightBottomBounds, int leftTopTaskId, - int rightBottomTaskId) { + int rightBottomTaskId, int snapPosition) { this.leftTopBounds = leftTopBounds; this.rightBottomBounds = rightBottomBounds; this.leftTopTaskId = leftTopTaskId; this.rightBottomTaskId = rightBottomTaskId; + this.snapPosition = snapPosition; if (rightBottomBounds.top > leftTopBounds.top) { // vertical apps, horizontal divider