From 1c81f07eb597c41091e8cb7d58b218cb47f1e3b1 Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Tue, 13 Jun 2023 14:29:24 -0700 Subject: [PATCH] Allow starting split from home, selecting second app from overview * KI: After entering overview, swiping to exit doesn't clear split state. That's because LauncherRecentsView#reset() gets called both when entering and exiting overview. We'd need to check or pass through what state we're moving to to determine whether or not actually to reset state in SplitSelectStateController, or handle that at the gesture level Flag: ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE Test: Manual, split paths work w/ and w/o flag enabled Bug: 276361926 Change-Id: I39391ac5f92b774d8198930829caabe84d950598 --- .../BaseRecentsViewStateController.java | 5 +- .../uioverrides/QuickstepLauncher.java | 9 +-- .../quickstep/SplitSelectionListener.kt | 17 +++++ .../fallback/FallbackRecentsView.java | 7 ++- .../util/SplitSelectStateController.java | 33 +++++++++- .../quickstep/views/LauncherRecentsView.java | 7 ++- .../android/quickstep/views/RecentsView.java | 63 ++++++++++++++++--- 7 files changed, 122 insertions(+), 19 deletions(-) create mode 100644 quickstep/src/com/android/quickstep/SplitSelectionListener.kt diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java index 8c8e267e34..d241260082 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java @@ -46,6 +46,7 @@ import androidx.annotation.NonNull; import com.android.launcher3.LauncherState; import com.android.launcher3.Utilities; import com.android.launcher3.anim.PendingAnimation; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.statemanager.StateManager.StateHandler; import com.android.launcher3.states.StateAnimationConfig; @@ -113,7 +114,9 @@ public abstract class BaseRecentsViewStateController setter.setFloat(mRecentsView, TASK_SECONDARY_TRANSLATION, 0f, config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, LINEAR)); - if (mRecentsView.isSplitSelectionActive()) { + boolean exitingOverview = !FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get() + || !toState.overviewUi; + if (mRecentsView.isSplitSelectionActive() && exitingOverview) { // TODO (b/238651489): Refactor state management to avoid need for double check FloatingTaskView floatingTask = mRecentsView.getFirstFloatingTaskView(); if (floatingTask != null) { diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index ecc8e196fd..6507dfe929 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -615,9 +615,10 @@ public class QuickstepLauncher extends Launcher { mSplitSelectStateController.findLastActiveTaskAndRunCallback( splitSelectSource.itemInfo.getComponentKey(), foundTask -> { - splitSelectSource.alreadyRunningTaskId = foundTask == null - ? INVALID_TASK_ID - : foundTask.key.id; + boolean taskWasFound = foundTask != null; + splitSelectSource.alreadyRunningTaskId = taskWasFound + ? foundTask.key.id + : INVALID_TASK_ID; if (ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()) { startSplitToHome(splitSelectSource); } else { @@ -1295,7 +1296,7 @@ public class QuickstepLauncher extends Launcher { groupTask.task1.key.id, groupTask.task2.key.id, SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT, - /* callback= */ success -> {}, + /* callback= */ success -> mSplitSelectStateController.resetState(), /* freezeTaskList= */ true, groupTask.mSplitBounds == null ? DEFAULT_SPLIT_RATIO diff --git a/quickstep/src/com/android/quickstep/SplitSelectionListener.kt b/quickstep/src/com/android/quickstep/SplitSelectionListener.kt new file mode 100644 index 0000000000..5025c1c181 --- /dev/null +++ b/quickstep/src/com/android/quickstep/SplitSelectionListener.kt @@ -0,0 +1,17 @@ +package com.android.quickstep + +interface SplitSelectionListener { + /** Called when the first app has been selected with the intention to launch split screen */ + fun onSplitSelectionActive() + + /** Called when the second app has been selected with the intention to launch split screen */ + fun onSplitSelectionConfirmed() + + /** + * Called when the user no longer is in the process of selecting apps for split screen. + * [launchedSplit] will be true if selected apps have launched successfully (either in + * split screen or fullscreen), false if the user canceled/exited the selection process + */ + fun onSplitSelectionExit(launchedSplit: Boolean) { + } +} \ No newline at end of file diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java index 074aedd3c7..45930446b1 100644 --- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java +++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java @@ -35,6 +35,7 @@ import androidx.annotation.Nullable; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.PendingAnimation; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.statemanager.StateManager.StateListener; import com.android.launcher3.util.SplitConfigurationOptions; @@ -246,7 +247,11 @@ public class FallbackRecentsView extends RecentsView mSplitSelectionListeners = new ArrayList<>(); + public SplitSelectStateController(Context context, Handler handler, StateManager stateManager, DepthController depthController, StatsLogManager statsLogManager, SystemUiProxy systemUiProxy, RecentsModel recentsModel) { @@ -247,6 +251,27 @@ public class SplitSelectStateController { && task.key.userId == componentKey.user.getIdentifier(); } + /** + * Listener will only get callbacks going forward from the point of registration. No + * methods will be fired upon registering. + */ + public void registerSplitListener(@NonNull SplitSelectionListener listener) { + if (mSplitSelectionListeners.contains(listener)) { + return; + } + mSplitSelectionListeners.add(listener); + } + + public void unregisterSplitListener(@NonNull SplitSelectionListener listener) { + mSplitSelectionListeners.remove(listener); + } + + private void dispatchOnSplitSelectionExit() { + for (SplitSelectionListener listener : mSplitSelectionListeners) { + listener.onSplitSelectionExit(false); + } + } + /** * To be called when the actual tasks ({@link #mInitialTaskId}, {@link #mSecondTaskId}) are * to be launched. Call after launcher side animations are complete. @@ -790,12 +815,16 @@ public class SplitSelectStateController { } /** - * To be called if split select was cancelled + * To be called whenever we exit split selection state. If + * {@link FeatureFlags#ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE} is set, this should be the + * central way split is getting reset, which should then go through the callbacks to reset + * other state. */ public void resetState() { if (FeatureFlags.ENABLE_SPLIT_LAUNCH_DATA_REFACTOR.get()) { mSplitSelectDataHolder.resetState(); } + dispatchOnSplitSelectionExit(); mInitialTaskId = INVALID_TASK_ID; mInitialTaskIntent = null; mSecondTaskId = INVALID_TASK_ID; diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java index 4dbf4e3655..2ac73c83c2 100644 --- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java +++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java @@ -37,6 +37,7 @@ import androidx.annotation.Nullable; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.LauncherState; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.statehandlers.DepthController; import com.android.launcher3.statehandlers.DesktopVisibilityController; @@ -218,7 +219,11 @@ public class LauncherRecentsView extends RecentsView - mSplitSelectStateController.launchInitialAppFullscreen(launchSuccess -> - resetFromSplitSelectionState())); + mSplitSelectStateController.launchInitialAppFullscreen(launchSuccess -> { + if (FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()) { + mSplitSelectStateController.resetState(); + } else { + resetFromSplitSelectionState(); + } + })); pendingAnimation.buildAnim().start(); } @@ -4704,7 +4736,13 @@ public abstract class RecentsView { mSplitSelectStateController.launchSplitTasks( - aBoolean1 -> RecentsView.this.resetFromSplitSelectionState()); + aBoolean1 -> { + if (FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()) { + mSplitSelectStateController.resetState(); + } else { + resetFromSplitSelectionState(); + } + }); InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER); }); @@ -4726,7 +4764,8 @@ public abstract class RecentsView