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:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user