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