Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3346e19b authored by Brian Isganitis's avatar Brian Isganitis
Browse files

Initial Taskbar drag-n-drop support for search results.

- Includes initial support for obtaining PendingIntent for ITEM_TYPE_SEARCH_ACTION.
- Custom pre-drag conditions for search results can be provided through TaskbarSearchSessionController.
- Added detection for telling when DragView shift animation ends for
  pre-drag condition usage.

Test: Manual
Bug: 289261756
Flag: ENABLE_ALL_APPS_SEARCH_IN_TASKBAR
Change-Id: I52510a6f3ee49968134ecb591ef7c4df711b9d3d
parent 19c22c20
Loading
Loading
Loading
Loading
+48 −14
Original line number Diff line number Diff line
@@ -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;
        // 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(),
+11 −0
Original line number Diff line number Diff line
@@ -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;
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -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 {
+32 −5
Original line number Diff line number Diff line
@@ -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.
     *
+2 −3
Original line number Diff line number Diff line
@@ -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));
                    }
                }