Merge "Fixing app-to-overview animation in 3 button mode" into ub-launcher3-master
diff --git a/res/layout/search_result_settings_row.xml b/res/layout/search_result_settings_row.xml
index 05f7561..22c08bf 100644
--- a/res/layout/search_result_settings_row.xml
+++ b/res/layout/search_result_settings_row.xml
@@ -44,6 +44,7 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginBottom="@dimen/search_line_spacing"
+            android:maxLines="1"
             android:textColor="?android:attr/textColorPrimary"
             android:textSize="@dimen/search_hero_title_size" />
 
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 38ebe14..aa123f6 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -2497,6 +2497,7 @@
     @Override
     public void bindAllApplications(AppInfo[] apps, int flags) {
         mAppsView.getAppsStore().setApps(apps, flags);
+        PopupContainerWithArrow.dismissInvalidPopup(this);
     }
 
     /**
@@ -2528,6 +2529,7 @@
     public void bindWorkspaceItemsChanged(List<WorkspaceItemInfo> updated) {
         if (!updated.isEmpty()) {
             mWorkspace.updateShortcuts(updated);
+            PopupContainerWithArrow.dismissInvalidPopup(this);
         }
     }
 
@@ -2552,6 +2554,7 @@
     public void bindWorkspaceComponentsRemoved(final ItemInfoMatcher matcher) {
         mWorkspace.removeItemsByMatcher(matcher);
         mDragController.onAppsRemoved(matcher);
+        PopupContainerWithArrow.dismissInvalidPopup(this);
     }
 
     @Override
diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
index 5b42681..d049352 100644
--- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
+++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
@@ -184,8 +184,7 @@
                     || viewType == VIEW_TYPE_SEARCH_THUMBNAIL
                     || viewType == VIEW_TYPE_SEARCH_ICON_ROW
                     || viewType == VIEW_TYPE_SEARCH_ICON
-                    || viewType == VIEW_TYPE_SEARCH_SUGGEST
-                    || viewType == VIEW_TYPE_SEARCH_WIDGET_LIVE;
+                    || viewType == VIEW_TYPE_SEARCH_SUGGEST;
         }
     }
 
diff --git a/src/com/android/launcher3/allapps/AllAppsSectionDecorator.java b/src/com/android/launcher3/allapps/AllAppsSectionDecorator.java
index 3c81811..1d31975 100644
--- a/src/com/android/launcher3/allapps/AllAppsSectionDecorator.java
+++ b/src/com/android/launcher3/allapps/AllAppsSectionDecorator.java
@@ -98,7 +98,8 @@
                     mAppsView.getActiveRecyclerView().getLayoutManager();
             if (layoutManager.findFirstVisibleItemPosition() <= index
                     && index < parent.getChildCount()) {
-                decorationHandler.onFocusDraw(c, parent.getChildAt(index));
+                RecyclerView.ViewHolder vh = parent.findViewHolderForAdapterPosition(index);
+                if (vh != null) decorationHandler.onFocusDraw(c, vh.itemView);
             }
         }
         decorationHandler.reset();
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 6d92b8b..59930ff 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -600,6 +600,17 @@
     }
 
     /**
+     * Dismisses the popup if it is no longer valid
+     */
+    public static void dismissInvalidPopup(BaseDraggingActivity activity) {
+        PopupContainerWithArrow popup = getOpen(activity);
+        if (popup != null && (!popup.mOriginalIcon.isAttachedToWindow()
+                || !canShow(popup.mOriginalIcon, (ItemInfo) popup.mOriginalIcon.getTag()))) {
+            popup.animateClose();
+        }
+    }
+
+    /**
      * Handler to control drag-and-drop for popup items
      */
     public interface PopupItemDragHandler extends OnLongClickListener, OnTouchListener { }
diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
index 2b04365..2adf8ce 100644
--- a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
+++ b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
@@ -39,6 +39,7 @@
 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
 import com.android.launcher3.model.data.PromiseAppInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.popup.PopupContainerWithArrow;
 import com.android.launcher3.popup.PopupDataProvider;
 import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.IntArray;
@@ -296,6 +297,7 @@
     @Override
     public void bindAllApplications(AppInfo[] apps, int flags) {
         mAppsView.getAppsStore().setApps(apps, flags);
+        PopupContainerWithArrow.dismissInvalidPopup(this);
     }
 
     public PopupDataProvider getPopupDataProvider() {
diff --git a/src/com/android/launcher3/views/SearchResultWidget.java b/src/com/android/launcher3/views/SearchResultWidget.java
index 65131be..7d53955 100644
--- a/src/com/android/launcher3/views/SearchResultWidget.java
+++ b/src/com/android/launcher3/views/SearchResultWidget.java
@@ -18,18 +18,25 @@
 import android.appwidget.AppWidgetHostView;
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.Context;
+import android.graphics.Rect;
 import android.util.AttributeSet;
+import android.view.GestureDetector;
 import android.view.MotionEvent;
+import android.view.View;
 import android.widget.RelativeLayout;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
 import com.android.launcher3.AppWidgetResizeFrame;
+import com.android.launcher3.CheckLongPressHelper;
+import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.allapps.search.AllAppsSearchBarController;
 import com.android.launcher3.allapps.search.SearchEventTracker;
 import com.android.launcher3.allapps.search.SearchWidgetInfoContainer;
+import com.android.launcher3.dragndrop.DraggableView;
+import com.android.launcher3.touch.ItemLongClickListener;
 import com.android.launcher3.widget.PendingAddWidgetInfo;
 import com.android.systemui.plugins.shared.SearchTarget;
 import com.android.systemui.plugins.shared.SearchTargetEvent;
@@ -39,14 +46,19 @@
  * provider
  */
 public class SearchResultWidget extends RelativeLayout implements
-        AllAppsSearchBarController.SearchTargetHandler {
+        AllAppsSearchBarController.SearchTargetHandler, DraggableView, View.OnLongClickListener {
 
     private static final String TAG = "SearchResultWidget";
 
     public static final String TARGET_TYPE_WIDGET_LIVE = "widget";
 
+    private final Rect mWidgetOffset = new Rect();
+
     private final Launcher mLauncher;
+    private final CheckLongPressHelper mLongPressHelper;
+    private final GestureDetector mClickDetector;
     private final AppWidgetHostView mHostView;
+    private final float mScaleToFit;
 
     private SearchTarget mSearchTarget;
     private AppWidgetProviderInfo mProviderInfo;
@@ -65,8 +77,18 @@
     public SearchResultWidget(@NonNull Context context, @Nullable AttributeSet attrs,
             int defStyleAttr) {
         super(context, attrs, defStyleAttr);
-        mHostView = new AppWidgetHostView(context);
         mLauncher = Launcher.getLauncher(context);
+        mHostView = new AppWidgetHostView(context);
+        DeviceProfile grid = mLauncher.getDeviceProfile();
+        mScaleToFit = Math.min(grid.appWidgetScale.x, grid.appWidgetScale.y);
+
+        // detect tap event on widget container for search target event reporting
+        mClickDetector = new GestureDetector(context,
+                new ClickListener(() -> handleSelection(SearchTargetEvent.CHILD_SELECT)));
+
+        mLongPressHelper = new CheckLongPressHelper(this);
+        mLongPressHelper.setLongPressTimeoutFactor(1);
+        setOnLongClickListener(this);
     }
 
     @Override
@@ -106,8 +128,7 @@
         AppWidgetResizeFrame.updateWidgetSizeRanges(mHostView, mLauncher, info.spanX,
                 info.spanY);
         mHostView.requestLayout();
-
-
+        setTag(info);
     }
 
     /**
@@ -127,9 +148,55 @@
 
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
-        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+        mLongPressHelper.onTouchEvent(ev);
+        mClickDetector.onTouchEvent(ev);
+        if (ev.getAction() == MotionEvent.ACTION_UP && !mLongPressHelper.hasPerformedLongPress()) {
             handleSelection(SearchTargetEvent.CHILD_SELECT);
         }
         return super.onInterceptTouchEvent(ev);
     }
+
+
+    @Override
+    public void cancelLongPress() {
+        super.cancelLongPress();
+        mLongPressHelper.cancelLongPress();
+    }
+
+    @Override
+    public int getViewType() {
+        return DraggableView.DRAGGABLE_WIDGET;
+    }
+
+    @Override
+    public void getSourceVisualDragBounds(Rect bounds) {
+        mHostView.getHitRect(mWidgetOffset);
+        int width = (int) (mHostView.getMeasuredWidth() * mScaleToFit);
+        int height = (int) (mHostView.getMeasuredHeight() * mScaleToFit);
+        bounds.set(mWidgetOffset.left,
+                mWidgetOffset.top,
+                width + mWidgetOffset.left,
+                height + mWidgetOffset.top);
+    }
+
+    @Override
+    public boolean onLongClick(View view) {
+        ItemLongClickListener.INSTANCE_ALL_APPS.onLongClick(view);
+        handleSelection(SearchTargetEvent.LONG_PRESS);
+        return false;
+    }
+
+    static class ClickListener extends GestureDetector.SimpleOnGestureListener {
+        private final Runnable mCb;
+
+        ClickListener(Runnable cb) {
+            mCb = cb;
+        }
+
+        @Override
+        public boolean onSingleTapConfirmed(MotionEvent e) {
+            mCb.run();
+            return super.onSingleTapConfirmed(e);
+        }
+    }
 }