Merge "Initial Taskbar drag-n-drop support for search results." into udc-qpr-dev am: 3f0e7e7c5d

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/24011563

Change-Id: I6838291da55f690898946094c5a6e8ece27a4d3b
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Brian Isganitis
2023-07-17 17:38:02 +00:00
committed by Automerger Merge Worker
5 changed files with 99 additions and 23 deletions
@@ -20,11 +20,13 @@ import static com.android.launcher3.AbstractFloatingView.TYPE_TASKBAR_ALL_APPS;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_ALL_APPS;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_PREDICTION;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_SEARCH_ACTION;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.app.PendingIntent;
import android.content.ClipData;
import android.content.ClipDescription;
import android.content.Intent;
@@ -73,6 +75,7 @@ import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.views.BubbleTextHolder;
import com.android.quickstep.util.LogUtils;
import com.android.quickstep.util.MultiValueUpdateListener;
import com.android.systemui.shared.recents.model.Task;
@@ -149,6 +152,9 @@ public class TaskbarDragController extends DragController<BaseTaskbarContext> im
View view,
@Nullable DragPreviewProvider dragPreviewProvider,
@Nullable Point iconShift) {
if (view instanceof BubbleTextHolder) {
view = ((BubbleTextHolder) view).getBubbleText();
}
if (!(view instanceof BubbleTextView) || mDisallowLongClick) {
return false;
}
@@ -193,13 +199,21 @@ public class TaskbarDragController extends DragController<BaseTaskbarContext> im
dragLayerY += dragRect.top;
DragOptions dragOptions = new DragOptions();
dragOptions.preDragCondition = null;
PopupContainerWithArrow<BaseTaskbarContext> popupContainer =
mControllers.taskbarPopupController.showForIcon(btv);
if (popupContainer != null) {
dragOptions.preDragCondition = popupContainer.createPreDragCondition(false);
}
// First, see if view is a search result that needs custom pre-drag conditions.
dragOptions.preDragCondition =
mControllers.taskbarAllAppsController.createPreDragConditionForSearch(btv);
if (dragOptions.preDragCondition == null) {
// See if view supports a popup container.
PopupContainerWithArrow<BaseTaskbarContext> popupContainer =
mControllers.taskbarPopupController.showForIcon(btv);
if (popupContainer != null) {
dragOptions.preDragCondition = popupContainer.createPreDragCondition(false);
}
}
if (dragOptions.preDragCondition == null) {
// Fallback pre-drag condition.
dragOptions.preDragCondition = new DragOptions.PreDragCondition() {
private DragView mDragView;
@@ -213,13 +227,8 @@ public class TaskbarDragController extends DragController<BaseTaskbarContext> im
mDragView = dragObject.dragView;
if (!shouldStartDrag(0)) {
mDragView.setOnAnimationEndCallback(() -> {
// Drag might be cancelled during the DragView animation, so check
// mIsPreDrag again.
if (mIsInPreDrag) {
callOnDragStart();
}
});
mDragView.setOnScaleAnimEndCallback(
TaskbarDragController.this::onPreDragAnimationEnd);
}
}
@@ -230,12 +239,13 @@ public class TaskbarDragController extends DragController<BaseTaskbarContext> im
};
}
Point dragOffset = dragOptions.preDragCondition.getDragOffset();
return startDrag(
drawable,
/* view = */ null,
/* originalView = */ btv,
dragLayerX,
dragLayerY,
dragLayerX + dragOffset.x,
dragLayerY + dragOffset.y,
(View target, DropTarget.DragObject d, boolean success) -> {} /* DragSource */,
(ItemInfo) btv.getTag(),
dragRect,
@@ -290,6 +300,11 @@ public class TaskbarDragController extends DragController<BaseTaskbarContext> im
mDragObject.dragInfo = dragInfo;
mDragObject.originalDragInfo = mDragObject.dragInfo.makeShallowCopy();
if (mOptions.preDragCondition != null) {
dragView.setHasDragOffset(mOptions.preDragCondition.getDragOffset().x != 0
|| mOptions.preDragCondition.getDragOffset().y != 0);
}
if (dragRegion != null) {
dragView.setDragRegion(new Rect(dragRegion));
}
@@ -308,6 +323,14 @@ public class TaskbarDragController extends DragController<BaseTaskbarContext> im
return dragView;
}
/** Invoked when an animation running as part of pre-drag finishes. */
public void onPreDragAnimationEnd() {
// Drag might be cancelled during the DragView animation, so check mIsPreDrag again.
if (mIsInPreDrag) {
callOnDragStart();
}
}
@Override
protected void callOnDragStart() {
super.callOnDragStart();
@@ -383,6 +406,17 @@ public class TaskbarDragController extends DragController<BaseTaskbarContext> im
item.user));
intent.putExtra(Intent.EXTRA_PACKAGE_NAME, item.getIntent().getPackage());
intent.putExtra(Intent.EXTRA_SHORTCUT_ID, deepShortcutId);
} else if (item.itemType == ITEM_TYPE_SEARCH_ACTION) {
// TODO(b/289261756): Buggy behavior when split opposite to an existing search pane.
intent.putExtra(
ClipDescription.EXTRA_PENDING_INTENT,
PendingIntent.getActivityAsUser(
mActivity,
/* requestCode= */ 0,
item.getIntent(),
PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT,
/* options= */ null,
item.user));
} else {
intent.putExtra(ClipDescription.EXTRA_PENDING_INTENT,
launcherApps.getMainActivityLaunchIntent(item.getIntent().getComponent(),
@@ -15,11 +15,14 @@
*/
package com.android.launcher3.taskbar.allapps;
import android.view.View;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.R;
import com.android.launcher3.appprediction.PredictionRowView;
import com.android.launcher3.dragndrop.DragOptions.PreDragCondition;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.taskbar.TaskbarControllers;
@@ -208,4 +211,12 @@ public final class TaskbarAllAppsController {
// Allow null-pointer since this should only be null if the apps view is not showing.
return mAppsView.getActiveRecyclerView().computeVerticalScrollOffset();
}
/** @see TaskbarSearchSessionController#createPreDragConditionForSearch(View) */
@Nullable
public PreDragCondition createPreDragConditionForSearch(View view) {
return mSearchSessionController != null
? mSearchSessionController.createPreDragConditionForSearch(view)
: null;
}
}
@@ -17,8 +17,10 @@
package com.android.launcher3.taskbar.allapps
import android.content.Context
import android.view.View
import com.android.launcher3.R
import com.android.launcher3.config.FeatureFlags
import com.android.launcher3.dragndrop.DragOptions.PreDragCondition
import com.android.launcher3.model.data.ItemInfo
import com.android.launcher3.util.ResourceBasedOverride
import com.android.launcher3.util.ResourceBasedOverride.Overrides
@@ -38,6 +40,9 @@ open class TaskbarSearchSessionController : ResourceBasedOverride {
/** Updates the search suggestions shown in the zero-state. */
open fun setZeroStateSearchSuggestions(items: List<ItemInfo>) {}
/** Creates a [PreDragCondition] for [view], if it is a search result that requires one. */
open fun createPreDragConditionForSearch(view: View): PreDragCondition? = null
companion object {
@JvmStatic
fun newInstance(context: Context): TaskbarSearchSessionController {
@@ -99,7 +99,9 @@ public abstract class DragView<T extends Context & ActivityContext> extends Fram
// Whether mAnim has started. Unlike mAnim.isStarted(), this is true even after mAnim ends.
private boolean mScaleAnimStarted;
private Runnable mOnAnimEndCallback = null;
private boolean mShiftAnimStarted;
private Runnable mOnScaleAnimEndCallback;
private Runnable mOnShiftAnimEndCallback;
private int mLastTouchX;
private int mLastTouchY;
@@ -186,13 +188,26 @@ public abstract class DragView<T extends Context & ActivityContext> extends Fram
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
if (mOnAnimEndCallback != null) {
mOnAnimEndCallback.run();
if (mOnScaleAnimEndCallback != null) {
mOnScaleAnimEndCallback.run();
}
}
});
// Set up the shift animator.
mShiftAnim = ValueAnimator.ofFloat(0f, 1f);
mShiftAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
mShiftAnimStarted = true;
}
@Override
public void onAnimationEnd(Animator animation) {
if (mOnShiftAnimEndCallback != null) {
mOnShiftAnimEndCallback.run();
}
}
});
setDragRegion(new Rect(0, 0, width, height));
@@ -211,8 +226,14 @@ public abstract class DragView<T extends Context & ActivityContext> extends Fram
setWillNotDraw(false);
}
public void setOnAnimationEndCallback(Runnable callback) {
mOnAnimEndCallback = callback;
/** Callback invoked when the scale animation ends. */
public void setOnScaleAnimEndCallback(Runnable callback) {
mOnScaleAnimEndCallback = callback;
}
/** Callback invoked when the shift animation ends. */
public void setOnShiftAnimEndCallback(Runnable callback) {
mOnShiftAnimEndCallback = callback;
}
/**
@@ -416,10 +437,16 @@ public abstract class DragView<T extends Context & ActivityContext> extends Fram
}
}
/** {@code true} if the scale animation has finished. */
public boolean isScaleAnimationFinished() {
return mScaleAnimStarted && !mScaleAnim.isRunning();
}
/** {@code true} if the shift animation has finished. */
public boolean isShiftAnimationFinished() {
return mShiftAnimStarted && !mShiftAnim.isRunning();
}
/**
* Move the window containing this view.
*
@@ -240,9 +240,8 @@ public class SecondaryDragLayer extends BaseDragLayer<SecondaryDisplayLauncher>
public void onPreDragStart(DropTarget.DragObject dragObject) {
mDragView = dragObject.dragView;
if (!shouldStartDrag(0)) {
mDragView.setOnAnimationEndCallback(() -> {
mActivity.beginDragShared(v, mActivity.getAppsView(), options);
});
mDragView.setOnScaleAnimEndCallback(() ->
mActivity.beginDragShared(v, mActivity.getAppsView(), options));
}
}