Prevent double selection of second split app

* Also fix small other bug where we were
checking only for LauncherState
OVERVIEW_SPLIT_SELECT and not for equivalent
3P RecentsState

Fixes: 227419997
Test: Repro steps don't cause bug. Yay.
Change-Id: Ibb8238185b959d22d8455b6812d29b2e268d9739
This commit is contained in:
Vinit Nayak
2022-04-06 12:31:34 -07:00
parent fed1182660
commit a4e5a9eebe
5 changed files with 68 additions and 19 deletions
@@ -268,4 +268,9 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
super.initiateSplitSelect(splitSelectSource);
mActivity.getStateManager().goToState(OVERVIEW_SPLIT_SELECT);
}
@Override
protected boolean canLaunchFullscreenTask() {
return !mActivity.isInState(OVERVIEW_SPLIT_SELECT);
}
}
@@ -73,6 +73,7 @@ public class SplitSelectStateController {
private Intent mInitialTaskIntent;
private int mInitialTaskId = INVALID_TASK_ID;
private int mSecondTaskId = INVALID_TASK_ID;
private String mSecondTaskPackageName;
private boolean mRecentsAnimationRunning;
/** If not null, this is the TaskView we want to launch from */
@Nullable
@@ -103,15 +104,15 @@ public class SplitSelectStateController {
}
/**
* To be called after second task selected
* To be called when the actual tasks ({@link #mInitialTaskId}, {@link #mSecondTaskId}) are
* to be launched. Call after launcher side animations are complete.
*/
public void setSecondTask(Task task, Consumer<Boolean> callback) {
mSecondTaskId = task.key.id;
public void launchSplitTasks(Consumer<Boolean> callback) {
final Intent fillInIntent;
if (mInitialTaskIntent != null) {
fillInIntent = new Intent();
if (TextUtils.equals(mInitialTaskIntent.getComponent().getPackageName(),
task.getTopComponent().getPackageName())) {
mSecondTaskPackageName)) {
fillInIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
}
} else {
@@ -124,6 +125,18 @@ public class SplitSelectStateController {
callback, false /* freezeTaskList */, DEFAULT_SPLIT_RATIO);
}
/**
* To be called as soon as user selects the second task (even if animations aren't complete)
* @param task The second task that will be launched.
*/
public void setSecondTask(Task task) {
mSecondTaskId = task.key.id;
if (mInitialTaskIntent != null) {
mSecondTaskPackageName = task.getTopComponent().getPackageName();
}
}
/**
* To be called when we want to launch split pairs from an existing GroupedTaskView.
*/
@@ -303,7 +316,18 @@ public class SplitSelectStateController {
* chosen
*/
public boolean isSplitSelectActive() {
return (mInitialTaskId != INVALID_TASK_ID || mInitialTaskIntent != null)
&& mSecondTaskId == INVALID_TASK_ID;
return isInitialTaskIntentSet() && mSecondTaskId == INVALID_TASK_ID;
}
/**
* @return {@code true} if the first and second task have been chosen and split is waiting to
* be launched
*/
public boolean isBothSplitAppsConfirmed() {
return isInitialTaskIntentSet() && mSecondTaskId != INVALID_TASK_ID;
}
private boolean isInitialTaskIntentSet() {
return (mInitialTaskId != INVALID_TASK_ID || mInitialTaskIntent != null);
}
}
@@ -181,4 +181,9 @@ public class LauncherRecentsView extends RecentsView<BaseQuickstepLauncher, Laun
super.initiateSplitSelect(splitSelectSource);
mActivity.getStateManager().goToState(LauncherState.OVERVIEW_SPLIT_SELECT);
}
@Override
protected boolean canLaunchFullscreenTask() {
return !mActivity.isInState(OVERVIEW_SPLIT_SELECT);
}
}
@@ -878,6 +878,14 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
return mSplitSelectStateController.isSplitSelectActive();
}
/**
* See overridden implementations
* @return {@code true} if child TaskViews can be launched when user taps on them
*/
protected boolean canLaunchFullscreenTask() {
return true;
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
@@ -3991,15 +3999,25 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
/**
* Confirms the selection of the next split task. The extra data is passed through because the
* user may be selecting a subtask in a group.
*
* @return true if waiting for confirmation of second app or if split animations are running,
* false otherwise
*/
public void confirmSplitSelect(TaskView containerTaskView, Task task, IconView iconView,
public boolean confirmSplitSelect(TaskView containerTaskView, Task task, IconView iconView,
TaskThumbnailView thumbnailView) {
if (canLaunchFullscreenTask()) {
return false;
}
if (mSplitSelectStateController.isBothSplitAppsConfirmed()) {
return true;
}
mSplitToast.cancel();
if (!task.isDockable) {
// Task not split screen supported
mSplitUnsupportedToast.show();
return;
return true;
}
mSplitSelectStateController.setSecondTask(task);
RectF secondTaskStartingBounds = new RectF();
Rect secondTaskEndingBounds = new Rect();
// TODO(194414938) starting bounds seem slightly off, investigate
@@ -4027,8 +4045,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
mSecondFloatingTaskView.addAnimation(pendingAnimation, secondTaskStartingBounds,
secondTaskEndingBounds, true /* fadeWithThumbnail */, false /* isStagedTask */);
pendingAnimation.addEndListener(aBoolean ->
mSplitSelectStateController.setSecondTask(
task, aBoolean1 -> RecentsView.this.resetFromSplitSelectionState()));
mSplitSelectStateController.launchSplitTasks(
aBoolean1 -> RecentsView.this.resetFromSplitSelectionState()));
if (containerTaskView.containsMultipleTasks()) {
// If we are launching from a child task, then only hide the thumbnail itself
mSecondSplitHiddenView = thumbnailView;
@@ -4037,6 +4055,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
mSecondSplitHiddenView.setVisibility(INVISIBLE);
pendingAnimation.buildAnim().start();
return true;
}
/** TODO(b/181707736) More gracefully handle exiting split selection state */
@@ -698,14 +698,10 @@ public class TaskView extends FrameLayout implements Reusable {
* second app. {@code false} otherwise
*/
private boolean confirmSecondSplitSelectApp() {
boolean isSelectingSecondSplitApp = getRecentsView().isSplitSelectionActive();
if (isSelectingSecondSplitApp) {
int index = getChildTaskIndexAtPosition(mLastTouchDownPosition);
TaskIdAttributeContainer container = mTaskIdAttributeContainer[index];
getRecentsView().confirmSplitSelect(this, container.getTask(), container.getIconView(),
container.getThumbnailView());
}
return isSelectingSecondSplitApp;
int index = getChildTaskIndexAtPosition(mLastTouchDownPosition);
TaskIdAttributeContainer container = mTaskIdAttributeContainer[index];
return getRecentsView().confirmSplitSelect(this, container.getTask(),
container.getIconView(), container.getThumbnailView());
}
/**
@@ -855,7 +851,7 @@ public class TaskView extends FrameLayout implements Reusable {
}
private boolean showTaskMenu(IconView iconView) {
if (getRecentsView().mActivity.isInState(OVERVIEW_SPLIT_SELECT)) {
if (!getRecentsView().canLaunchFullscreenTask()) {
// Don't show menu when selecting second split screen app
return true;
}