summaryrefslogtreecommitdiff
path: root/quickstep
diff options
context:
space:
mode:
authorWinson Chung <winsonc@google.com>2022-02-17 23:26:12 +0000
committerWinson Chung <winsonc@google.com>2022-02-18 17:49:59 +0000
commit3516ecc5340c495cf0582ab685fecbdede20a286 (patch)
tree962028bdbadb3844967284880f371d145302e3ce /quickstep
parentda7a268e7f4350a72f5fdfc054c0bd05d96c7e56 (diff)
downloadLauncher3-3516ecc5340c495cf0582ab685fecbdede20a286.tar.gz
Allow split with an existing split task
- Determine the task in the group being clicked in split-select mode and launch split using that selected task - Also make sure we don't handle drag cancel twice when we are animating the return of the drag surface Bug: 219060441 Test: Split from home/overview with fullscreen+fullscreen task, and with fullscreen+split task Change-Id: I48ec0a82812197803ff4b3698830a9cb705719e3
Diffstat (limited to 'quickstep')
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java6
-rw-r--r--quickstep/src/com/android/quickstep/views/FloatingTaskView.java19
-rw-r--r--quickstep/src/com/android/quickstep/views/GroupedTaskView.java18
-rw-r--r--quickstep/src/com/android/quickstep/views/RecentsView.java44
-rw-r--r--quickstep/src/com/android/quickstep/views/TaskView.java24
5 files changed, 73 insertions, 38 deletions
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
index 435eae47ee..6a2f62256b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
@@ -469,13 +469,19 @@ public class TaskbarDragController extends DragController<TaskbarActivityContext
}
});
mReturnAnimator.addListener(new AnimatorListenerAdapter() {
+ private boolean mCanceled = false;
+
@Override
public void onAnimationCancel(Animator animation) {
cleanUpSurface();
+ mCanceled = true;
}
@Override
public void onAnimationEnd(Animator animation) {
+ if (mCanceled) {
+ return;
+ }
cleanUpSurface();
}
diff --git a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
index 307c51f6fd..f2f1c3f5f6 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
@@ -48,8 +48,6 @@ public class FloatingTaskView extends FrameLayout {
private SplitPlaceholderView mSplitPlaceholderView;
private RectF mStartingPosition;
- @Nullable
- private Consumer<RectF> mAdditionalOffsetter;
private final StatefulActivity mActivity;
private final boolean mIsRtl;
private final Rect mOutline = new Rect();
@@ -81,9 +79,8 @@ public class FloatingTaskView extends FrameLayout {
}
private void init(StatefulActivity launcher, View originalView, @Nullable Bitmap thumbnail,
- Drawable icon, RectF positionOut, Consumer<RectF> additionalOffsetter) {
+ Drawable icon, RectF positionOut) {
mStartingPosition = positionOut;
- mAdditionalOffsetter = additionalOffsetter;
updateInitialPositionForView(originalView);
final InsettableFrameLayout.LayoutParams lp =
(InsettableFrameLayout.LayoutParams) getLayoutParams();
@@ -113,15 +110,13 @@ public class FloatingTaskView extends FrameLayout {
* translation values from originalView will be used
*/
public static FloatingTaskView getFloatingTaskView(StatefulActivity launcher,
- View originalView, @Nullable Bitmap thumbnail, Drawable icon, RectF positionOut,
- @Nullable Consumer<RectF> additionalOffsetter) {
+ View originalView, @Nullable Bitmap thumbnail, Drawable icon, RectF positionOut) {
final BaseDragLayer dragLayer = launcher.getDragLayer();
ViewGroup parent = (ViewGroup) dragLayer.getParent();
final FloatingTaskView floatingView = (FloatingTaskView) launcher.getLayoutInflater()
.inflate(R.layout.floating_split_select_view, parent, false);
- floatingView.init(launcher, originalView, thumbnail, icon, positionOut,
- additionalOffsetter);
+ floatingView.init(launcher, originalView, thumbnail, icon, positionOut);
parent.addView(floatingView);
return floatingView;
}
@@ -129,14 +124,8 @@ public class FloatingTaskView extends FrameLayout {
public void updateInitialPositionForView(View originalView) {
Rect viewBounds = new Rect(0, 0, originalView.getWidth(), originalView.getHeight());
Utilities.getBoundsForViewInDragLayer(mActivity.getDragLayer(), originalView, viewBounds,
- true /* ignoreTransform */, null /* recycle */,
+ false /* ignoreTransform */, null /* recycle */,
mStartingPosition);
- if (mAdditionalOffsetter != null) {
- mAdditionalOffsetter.accept(mStartingPosition);
- } else {
- mStartingPosition.offset(originalView.getTranslationX(),
- originalView.getTranslationY());
- }
final InsettableFrameLayout.LayoutParams lp = new InsettableFrameLayout.LayoutParams(
Math.round(mStartingPosition.width()),
Math.round(mStartingPosition.height()));
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
index af9f818e4e..04af3c11ab 100644
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
@@ -5,14 +5,17 @@ import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITIO
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
import android.content.Context;
+import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.MotionEvent;
+import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.SplitConfigurationOptions.StagedSplitBounds;
import com.android.launcher3.util.TransformingTouchDelegate;
@@ -52,7 +55,6 @@ public class GroupedTaskView extends TaskView {
@Nullable private StagedSplitBounds mSplitBoundsConfig;
private final DigitalWellBeingToast mDigitalWellBeingToast2;
-
public GroupedTaskView(Context context) {
this(context, null);
}
@@ -205,6 +207,20 @@ public class GroupedTaskView extends TaskView {
}
@Override
+ protected int getChildTaskIndexAtPosition(PointF position) {
+ if (isCoordInView(mIconView2, position) || isCoordInView(mSnapshotView2, position)) {
+ return 1;
+ }
+ return super.getChildTaskIndexAtPosition(position);
+ }
+
+ private boolean isCoordInView(View v, PointF position) {
+ float[] localPos = new float[]{position.x, position.y};
+ Utilities.mapCoordInSelfToDescendant(v, this, localPos);
+ return Utilities.pointInView(v, localPos[0], localPos[1], 0f /* slop */);
+ }
+
+ @Override
public void onRecycle() {
super.onRecycle();
mSnapshotView2.setThumbnail(mSecondaryTask, null);
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index a042bff67f..cb7e08a255 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -619,7 +619,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
@Nullable
private TaskView mSplitHiddenTaskView;
@Nullable
- private TaskView mSecondSplitHiddenTaskView;
+ private View mSecondSplitHiddenView;
@Nullable
private StagedSplitBounds mSplitBoundsConfig;
private final Toast mSplitToast = Toast.makeText(getContext(),
@@ -2729,11 +2729,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
mFirstFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
mSplitHiddenTaskView.getThumbnail(),
mSplitHiddenTaskView.getThumbnail().getThumbnail(),
- mSplitHiddenTaskView.getIconView().getDrawable(), startingTaskRect,
- floatingTaskViewStartingPosition -> floatingTaskViewStartingPosition.offset(
- mSplitHiddenTaskView.getTranslationX(),
- mSplitHiddenTaskView.getTranslationY()
- ));
+ mSplitHiddenTaskView.getIconView().getDrawable(), startingTaskRect);
mFirstFloatingTaskView.setAlpha(1);
mFirstFloatingTaskView.addAnimation(anim, startingTaskRect,
mTempRect, true /*fadeWithThumbnail*/);
@@ -2741,7 +2737,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
mSplitSelectSource.view.setVisibility(INVISIBLE);
mFirstFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
mSplitSelectSource.view, null,
- mSplitSelectSource.drawable, startingTaskRect, null /*additionalOffsetter*/);
+ mSplitSelectSource.drawable, startingTaskRect);
mFirstFloatingTaskView.setAlpha(1);
mFirstFloatingTaskView.addAnimation(anim, startingTaskRect,
mTempRect, true /*fadeWithThumbnail*/);
@@ -4004,9 +4000,14 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
}
- public void confirmSplitSelect(TaskView taskView) {
+ /**
+ * 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.
+ */
+ public void confirmSplitSelect(TaskView containerTaskView, Task task, IconView iconView,
+ TaskThumbnailView thumbnailView) {
mSplitToast.cancel();
- if (!taskView.getTask().isDockable) {
+ if (!task.isDockable) {
// Task not split screen supported
mSplitUnsupportedToast.show();
return;
@@ -4032,20 +4033,21 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
false /*fadeWithThumbnail*/);
mSecondFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
- taskView.getThumbnail(), taskView.getThumbnail().getThumbnail(),
- taskView.getIconView().getDrawable(), secondTaskStartingBounds,
- floatingTaskViewStartingPosition -> floatingTaskViewStartingPosition.offset(
- taskView.getTranslationX(),
- taskView.getTranslationY()
- ));
+ thumbnailView, thumbnailView.getThumbnail(),
+ iconView.getDrawable(), secondTaskStartingBounds);
mSecondFloatingTaskView.setAlpha(1);
mSecondFloatingTaskView.addAnimation(pendingAnimation, secondTaskStartingBounds,
- secondTaskEndingBounds, true /*fadeWithThumbnail*/);
+ secondTaskEndingBounds, true /* fadeWithThumbnail */);
pendingAnimation.addEndListener(aBoolean ->
- mSplitSelectStateController.setSecondTaskId(taskView.getTask().key.id,
+ mSplitSelectStateController.setSecondTaskId(task.key.id,
aBoolean1 -> RecentsView.this.resetFromSplitSelectionState()));
- mSecondSplitHiddenTaskView = taskView;
- taskView.setVisibility(INVISIBLE);
+ if (containerTaskView.containsMultipleTasks()) {
+ // If we are launching from a child task, then only hide the thumbnail itself
+ mSecondSplitHiddenView = thumbnailView;
+ } else {
+ mSecondSplitHiddenView = containerTaskView;
+ }
+ mSecondSplitHiddenView.setVisibility(INVISIBLE);
pendingAnimation.buildAnim().start();
}
@@ -4059,8 +4061,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
if (mSecondFloatingTaskView != null) {
mActivity.getRootView().removeView(mSecondFloatingTaskView);
mSecondFloatingTaskView = null;
- mSecondSplitHiddenTaskView.setVisibility(VISIBLE);
- mSecondSplitHiddenTaskView = null;
+ mSecondSplitHiddenView.setVisibility(VISIBLE);
+ mSecondSplitHiddenView = null;
}
mSplitSelectSource = null;
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 488789b465..f716965fa1 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -45,6 +45,7 @@ import android.app.ActivityOptions;
import android.content.Context;
import android.content.Intent;
import android.graphics.Outline;
+import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
@@ -426,8 +427,11 @@ public class TaskView extends FrameLayout implements Reusable {
private final float[] mIconCenterCoords = new float[2];
+ private final PointF mLastTouchDownPosition = new PointF();
+
private boolean mIsClickableAsLiveTile = true;
+
public TaskView(Context context) {
this(context, null);
}
@@ -600,6 +604,14 @@ public class TaskView extends FrameLayout implements Reusable {
return mIconView;
}
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent ev) {
+ if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+ mLastTouchDownPosition.set(ev.getX(), ev.getY());
+ }
+ return super.dispatchTouchEvent(ev);
+ }
+
private void onClick(View view) {
if (getTask() == null) {
return;
@@ -688,12 +700,22 @@ public class TaskView extends FrameLayout implements Reusable {
private boolean confirmSecondSplitSelectApp() {
boolean isSelectingSecondSplitApp = getRecentsView().isSplitSelectionActive();
if (isSelectingSecondSplitApp) {
- getRecentsView().confirmSplitSelect(this);
+ int index = getChildTaskIndexAtPosition(mLastTouchDownPosition);
+ TaskIdAttributeContainer container = mTaskIdAttributeContainer[index];
+ getRecentsView().confirmSplitSelect(this, container.getTask(), container.getIconView(),
+ container.getThumbnailView());
}
return isSelectingSecondSplitApp;
}
/**
+ * Returns the task under the given position in the local coordinates of this task view.
+ */
+ protected int getChildTaskIndexAtPosition(PointF position) {
+ return 0;
+ }
+
+ /**
* Starts the task associated with this view and animates the startup.
* @return CompletionStage to indicate the animation completion or null if the launch failed.
*/