Introduce support for Hero app Section

[Video attached to bug report]

Bug: 162871508
Test: Manual
Change-Id: Ia6f5621d6220f55e6fd5e56530853c267838442c
diff --git a/res/layout/search_result_hero_app.xml b/res/layout/search_result_hero_app.xml
new file mode 100644
index 0000000..bd0e42b
--- /dev/null
+++ b/res/layout/search_result_hero_app.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<com.android.launcher3.views.HeroSearchResultView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal"
+    android:gravity="center_vertical"
+    android:padding="@dimen/dynamic_grid_edge_margin">
+
+    <FrameLayout
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_gravity="center_vertical"
+        android:layout_weight="1">
+        <com.android.launcher3.BubbleTextView
+            android:id="@+id/bubble_text"
+            style="@style/BaseIcon"
+            android:drawablePadding="@dimen/dynamic_grid_icon_drawable_padding"
+            android:gravity="start|center_vertical"
+            android:textAlignment="viewStart"
+            android:textColor="?android:attr/textColorPrimary"
+            android:textSize="16sp"
+            android:layout_height="wrap_content"
+            launcher:iconDisplay="hero_app"
+            launcher:layoutHorizontal="true"/>
+
+        <View
+            android:id="@+id/icon"
+            android:layout_width="@dimen/deep_shortcut_icon_size"
+            android:layout_height="@dimen/deep_shortcut_icon_size"
+            android:layout_gravity="start|center_vertical"
+            android:background="@drawable/ic_deepshortcut_placeholder"/>
+    </FrameLayout>
+
+    <com.android.launcher3.BubbleTextView
+        android:id="@+id/shortcut_0"
+        style="@style/BaseIcon"
+        android:layout_width="@dimen/deep_shortcut_icon_size"
+        android:layout_height="match_parent"
+        android:gravity="start|center_vertical"
+        android:textAlignment="center"
+        launcher:iconDisplay="shortcut_popup"
+        android:textSize="12sp"
+        launcher:iconSizeOverride="@dimen/deep_shortcut_icon_size"
+        launcher:layoutHorizontal="false"/>
+
+    <com.android.launcher3.BubbleTextView
+        android:id="@+id/shortcut_1"
+        style="@style/BaseIcon"
+        android:layout_width="@dimen/deep_shortcut_icon_size"
+        android:layout_height="match_parent"
+        android:gravity="start|center_vertical"
+        android:textAlignment="center"
+        launcher:iconDisplay="shortcut_popup"
+        android:textSize="12sp"
+        launcher:iconSizeOverride="@dimen/deep_shortcut_icon_size"
+        launcher:layoutHorizontal="false"/>
+
+</com.android.launcher3.views.HeroSearchResultView>
\ No newline at end of file
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 26e6cba..acb8221 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -57,6 +57,7 @@
             <enum name="folder" value="2" />
             <enum name="widget_section" value="3" />
             <enum name="shortcut_popup" value="4" />
+            <enum name="hero_app" value="5" />
         </attr>
         <attr name="centerVertically" format="boolean" />
     </declare-styleable>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index ad607a3..9a89dee 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -35,8 +35,6 @@
 
     <color name="icon_background">#E0E0E0</color> <!-- Gray 300 -->
 
-    <color name="all_apps_bg_hand_fill">#E5E5E5</color>
-    <color name="all_apps_bg_hand_fill_dark">#9AA0A6</color>
     <color name="all_apps_section_fill">#327d7d7d</color>
 
     <color name="gesture_tutorial_ripple_color">#A0C2F9</color> <!-- Light Blue -->
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 198f13d..55d5de7 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -77,6 +77,7 @@
     private static final int DISPLAY_WORKSPACE = 0;
     private static final int DISPLAY_ALL_APPS = 1;
     private static final int DISPLAY_FOLDER = 2;
+    private static final int DISPLAY_HERO_APP = 5;
 
     private static final int[] STATE_PRESSED = new int[] {android.R.attr.state_pressed};
 
@@ -178,6 +179,8 @@
             setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.folderChildTextSizePx);
             setCompoundDrawablePadding(grid.folderChildDrawablePaddingPx);
             defaultIconSize = grid.folderChildIconSizePx;
+        } else if (mDisplay == DISPLAY_HERO_APP) {
+            defaultIconSize = grid.allAppsIconSizePx;
         } else {
             // widget_selection or shortcut_popup
             defaultIconSize = grid.iconSizePx;
diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
index dec92df..2cec797 100644
--- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
+++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
@@ -43,6 +43,7 @@
 import com.android.launcher3.allapps.AlphabeticalAppsList.AdapterItem;
 import com.android.launcher3.model.data.AppInfo;
 import com.android.launcher3.util.PackageManagerHelper;
+import com.android.launcher3.views.HeroSearchResultView;
 
 import java.util.List;
 
@@ -66,7 +67,9 @@
     // A divider that separates the apps list and the search market button
     public static final int VIEW_TYPE_ALL_APPS_DIVIDER = 1 << 4;
 
-    public static final int VIEW_TYPE_SEARCH_CORPUS_TITLE =  1 << 5;
+    public static final int VIEW_TYPE_SEARCH_CORPUS_TITLE = 1 << 5;
+
+    public static final int VIEW_TYPE_SEARCH_HERO_APP = 1 << 6;
 
     // Common view type masks
     public static final int VIEW_TYPE_MASK_DIVIDER = VIEW_TYPE_ALL_APPS_DIVIDER;
@@ -279,6 +282,10 @@
             case VIEW_TYPE_SEARCH_CORPUS_TITLE:
                 return new ViewHolder(
                         mLayoutInflater.inflate(R.layout.search_section_title, parent, false));
+
+            case VIEW_TYPE_SEARCH_HERO_APP:
+                return new ViewHolder(mLayoutInflater.inflate(
+                        R.layout.search_result_hero_app, parent, false));
             default:
                 throw new RuntimeException("Unexpected view type");
         }
@@ -311,6 +318,13 @@
                 TextView titleView = (TextView) holder.itemView;
                 titleView.setText(mApps.getAdapterItems().get(position).searchSectionInfo.getTitle(
                         titleView.getContext()));
+                break;
+            case VIEW_TYPE_SEARCH_HERO_APP:
+                HeroSearchResultView heroView = (HeroSearchResultView) holder.itemView;
+                heroView.prepareUsingAdapterItem(
+                        (AlphabeticalAppsList.HeroAppAdapterItem) mApps.getAdapterItems().get(
+                                position));
+                break;
             case VIEW_TYPE_ALL_APPS_DIVIDER:
                 // nothing to do
                 break;
diff --git a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
index 0fc04a7..9076f2a 100644
--- a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
+++ b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
@@ -22,6 +22,7 @@
 import com.android.launcher3.allapps.search.SearchSectionInfo;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.model.data.AppInfo;
+import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.util.ItemInfoMatcher;
 import com.android.launcher3.util.LabelComparator;
 
@@ -130,10 +131,33 @@
         }
 
         boolean isCountedForAccessibility() {
-            return viewType == AllAppsGridAdapter.VIEW_TYPE_ICON;
+            return viewType == AllAppsGridAdapter.VIEW_TYPE_ICON
+                    || viewType == AllAppsGridAdapter.VIEW_TYPE_SEARCH_HERO_APP;
         }
     }
 
+    /**
+     * Extension of AdapterItem that contains shortcut workspace items
+     */
+    public static class HeroAppAdapterItem extends AdapterItem {
+        private ArrayList<WorkspaceItemInfo> mShortcutInfos;
+
+        public HeroAppAdapterItem(AppInfo info, ArrayList<WorkspaceItemInfo> shortcutInfos) {
+            viewType = AllAppsGridAdapter.VIEW_TYPE_SEARCH_HERO_APP;
+            mShortcutInfos = shortcutInfos;
+            appInfo = info;
+        }
+
+        /**
+         * Returns list of shortcuts for appInfo
+         */
+        public ArrayList<WorkspaceItemInfo> getShortcutInfos() {
+            return mShortcutInfos;
+        }
+
+    }
+
+
     private final BaseDraggingActivity mLauncher;
 
     // The set of apps from the system
diff --git a/src/com/android/launcher3/allapps/search/AppsSearchPipeline.java b/src/com/android/launcher3/allapps/search/AppsSearchPipeline.java
index fb78651..e67e897 100644
--- a/src/com/android/launcher3/allapps/search/AppsSearchPipeline.java
+++ b/src/com/android/launcher3/allapps/search/AppsSearchPipeline.java
@@ -15,16 +15,25 @@
  */
 package com.android.launcher3.allapps.search;
 
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_SHORTCUTS;
+
+import android.content.Context;
+import android.content.pm.ShortcutInfo;
+
 import androidx.annotation.WorkerThread;
 
 import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.R;
 import com.android.launcher3.allapps.AllAppsSectionDecorator.SectionDecorationHandler;
 import com.android.launcher3.allapps.AlphabeticalAppsList.AdapterItem;
+import com.android.launcher3.allapps.AlphabeticalAppsList.HeroAppAdapterItem;
+import com.android.launcher3.icons.IconCache;
 import com.android.launcher3.model.AllAppsList;
 import com.android.launcher3.model.BaseModelUpdateTask;
 import com.android.launcher3.model.BgDataModel;
 import com.android.launcher3.model.data.AppInfo;
+import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.popup.PopupPopulator;
+import com.android.launcher3.shortcuts.ShortcutRequest;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -36,22 +45,23 @@
 public class AppsSearchPipeline implements SearchPipeline {
 
     private static final int MAX_RESULTS_COUNT = 5;
+    private static final int MAX_HERO_SECTION_COUNT = 2;
+    private static final int MAX_SHORTCUTS_COUNT = 2;
 
-    private static final int SECTION_TYPE_HEADER = 0;
-    private static final int SECTION_TYPE_APPS = 1;
-
-    private final SearchSectionInfo[] mSearchSectionInfos;
+    private final SearchSectionInfo mSearchSectionInfo;
     private final LauncherAppState mLauncherAppState;
-
+    private final boolean mHeroSectionSupported;
 
     public AppsSearchPipeline(LauncherAppState launcherAppState) {
+        this(launcherAppState, true);
+    }
+
+    public AppsSearchPipeline(LauncherAppState launcherAppState, boolean supportsHeroView) {
         mLauncherAppState = launcherAppState;
-        mSearchSectionInfos = new SearchSectionInfo[]{
-                new SearchSectionInfo(R.string.search_corpus_apps),
-                new SearchSectionInfo()
-        };
-        mSearchSectionInfos[SECTION_TYPE_APPS].setDecorationHandler(
+        mSearchSectionInfo = new SearchSectionInfo();
+        mSearchSectionInfo.setDecorationHandler(
                 new SectionDecorationHandler(launcherAppState.getContext(), true));
+        mHeroSectionSupported = supportsHeroView;
     }
 
     @Override
@@ -60,12 +70,39 @@
         mLauncherAppState.getModel().enqueueModelUpdateTask(new BaseModelUpdateTask() {
             @Override
             public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
-                callback.accept(getAdapterItems(getTitleMatchResult(apps.data, query)));
+                List<AppInfo> matchingResults = getTitleMatchResult(apps.data, query);
+                if (mHeroSectionSupported && matchingResults.size() <= MAX_HERO_SECTION_COUNT) {
+                    callback.accept(getHeroAdapterItems(app.getContext(), matchingResults));
+                } else {
+                    callback.accept(getAdapterItems(matchingResults));
+                }
             }
         });
     }
 
     /**
+     * Returns MAX_SHORTCUTS_COUNT shortcuts from local cache
+     * TODO: Shortcuts should be ranked based on relevancy 
+     */
+    private ArrayList<WorkspaceItemInfo> getShortcutInfos(Context context, AppInfo appInfo) {
+        List<ShortcutInfo> shortcuts = new ShortcutRequest(context, appInfo.user)
+                .withContainer(appInfo.getTargetComponent())
+                .query(ShortcutRequest.PUBLISHED);
+        shortcuts = PopupPopulator.sortAndFilterShortcuts(shortcuts, null);
+        IconCache cache = LauncherAppState.getInstance(context).getIconCache();
+        ArrayList<WorkspaceItemInfo> shortcutItems = new ArrayList<>();
+        for (int i = 0; i < shortcuts.size() && i < MAX_SHORTCUTS_COUNT; i++) {
+            final ShortcutInfo shortcut = shortcuts.get(i);
+            final WorkspaceItemInfo si = new WorkspaceItemInfo(shortcut, context);
+            cache.getUnbadgedShortcutIcon(si, shortcut);
+            si.rank = i;
+            si.container = CONTAINER_SHORTCUTS;
+            shortcutItems.add(si);
+        }
+        return shortcutItems;
+    }
+
+    /**
      * Filters {@link AppInfo}s matching specified query
      */
     public static ArrayList<AppInfo> getTitleMatchResult(List<AppInfo> apps, String query) {
@@ -83,17 +120,24 @@
         return result;
     }
 
+    private ArrayList<AdapterItem> getHeroAdapterItems(Context context, List<AppInfo> apps) {
+        ArrayList<AdapterItem> adapterItems = new ArrayList<>();
+        for (int i = 0; i < apps.size(); i++) {
+            //hero app
+            AppInfo appInfo = apps.get(i);
+            ArrayList<WorkspaceItemInfo> shortcuts = getShortcutInfos(context, appInfo);
+            AdapterItem adapterItem = new HeroAppAdapterItem(appInfo, shortcuts);
+            adapterItem.searchSectionInfo = mSearchSectionInfo;
+            adapterItems.add(adapterItem);
+        }
+        return adapterItems;
+    }
+
     private ArrayList<AdapterItem> getAdapterItems(List<AppInfo> matchingApps) {
         ArrayList<AdapterItem> items = new ArrayList<>();
-        if (matchingApps.isEmpty()) {
-            return items;
-        }
-        items.add(AdapterItem.asSearchTitle(mSearchSectionInfos[SECTION_TYPE_HEADER], 0));
-        int existingItems = items.size();
-        int searchResultsCount = Math.min(matchingApps.size(), MAX_RESULTS_COUNT);
-        for (int i = 0; i < searchResultsCount; i++) {
-            AdapterItem appItem = AdapterItem.asApp(i + existingItems, "", matchingApps.get(i), i);
-            appItem.searchSectionInfo = mSearchSectionInfos[SECTION_TYPE_APPS];
+        for (int i = 0; i < matchingApps.size() && i < MAX_RESULTS_COUNT; i++) {
+            AdapterItem appItem = AdapterItem.asApp(i, "", matchingApps.get(i), i);
+            appItem.searchSectionInfo = mSearchSectionInfo;
             items.add(appItem);
         }
 
diff --git a/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java b/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java
index db10311..470191c 100644
--- a/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java
+++ b/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java
@@ -32,7 +32,7 @@
 
     public DefaultAppSearchAlgorithm(LauncherAppState launcherAppState) {
         mResultHandler = new Handler();
-        mAppsSearchPipeline = new AppsSearchPipeline(launcherAppState);
+        mAppsSearchPipeline = new AppsSearchPipeline(launcherAppState, false);
     }
 
     @Override
diff --git a/src/com/android/launcher3/views/HeroSearchResultView.java b/src/com/android/launcher3/views/HeroSearchResultView.java
new file mode 100644
index 0000000..c2a02bc
--- /dev/null
+++ b/src/com/android/launcher3/views/HeroSearchResultView.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.views;
+
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_ALL_APPS;
+
+import android.content.Context;
+import android.graphics.Point;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+
+import com.android.launcher3.BubbleTextView;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.DragSource;
+import com.android.launcher3.DropTarget;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
+import com.android.launcher3.allapps.AlphabeticalAppsList;
+import com.android.launcher3.dragndrop.DragOptions;
+import com.android.launcher3.dragndrop.DraggableView;
+import com.android.launcher3.graphics.DragPreviewProvider;
+import com.android.launcher3.model.data.AppInfo;
+import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider;
+import com.android.launcher3.touch.ItemLongClickListener;
+import com.android.launcher3.userevent.nano.LauncherLogProto;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A view representing a high confidence app search result that includes shortcuts
+ */
+public class HeroSearchResultView extends LinearLayout implements DragSource {
+
+    BubbleTextView mBubbleTextView;
+    View mIconView;
+    BubbleTextView[] mDeepShortcutTextViews = new BubbleTextView[2];
+
+    public HeroSearchResultView(Context context) {
+        super(context);
+    }
+
+    public HeroSearchResultView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public HeroSearchResultView(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        Launcher launcher = Launcher.getLauncher(getContext());
+        DeviceProfile grid = launcher.getDeviceProfile();
+        mIconView = findViewById(R.id.icon);
+        ViewGroup.LayoutParams iconParams = mIconView.getLayoutParams();
+        iconParams.height = grid.allAppsIconSizePx;
+        iconParams.width = grid.allAppsIconSizePx;
+
+
+        mBubbleTextView = findViewById(R.id.bubble_text);
+        mBubbleTextView.setOnClickListener(launcher.getItemOnClickListener());
+        mBubbleTextView.setOnLongClickListener(new HeroItemDragHandler(getContext(), this));
+        setLayoutParams(
+                new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, grid.allAppsCellHeightPx));
+
+
+        mDeepShortcutTextViews[0] = findViewById(R.id.shortcut_0);
+        mDeepShortcutTextViews[1] = findViewById(R.id.shortcut_1);
+        for (BubbleTextView bubbleTextView : mDeepShortcutTextViews) {
+            bubbleTextView.setLayoutParams(
+                    new LinearLayout.LayoutParams(grid.allAppsIconSizePx,
+                            grid.allAppsIconSizePx));
+            bubbleTextView.setOnClickListener(launcher.getItemOnClickListener());
+        }
+    }
+
+    /**
+     * Apply {@link ItemInfo} for appIcon and shortcut Icons
+     */
+    public void prepareUsingAdapterItem(AlphabeticalAppsList.HeroAppAdapterItem adapterItem) {
+        mBubbleTextView.applyFromApplicationInfo(adapterItem.appInfo);
+        mIconView.setBackground(mBubbleTextView.getIcon());
+        mIconView.setTag(adapterItem.appInfo);
+        List<WorkspaceItemInfo> shorcutInfos = adapterItem.getShortcutInfos();
+        for (int i = 0; i < mDeepShortcutTextViews.length; i++) {
+            mDeepShortcutTextViews[i].setVisibility(shorcutInfos.size() > i ? VISIBLE : GONE);
+            if (i < shorcutInfos.size()) {
+                mDeepShortcutTextViews[i].applyFromWorkspaceItem(shorcutInfos.get(i));
+            }
+        }
+
+    }
+
+    @Override
+    public void onDropCompleted(View target, DropTarget.DragObject d, boolean success) {
+        mBubbleTextView.setVisibility(VISIBLE);
+        mBubbleTextView.setIconVisible(true);
+    }
+
+    @Override
+    public void fillInLogContainerData(ItemInfo childInfo, LauncherLogProto.Target child,
+            ArrayList<LauncherLogProto.Target> parents) {
+
+    }
+
+    private void setWillDrawIcon(boolean willDraw) {
+        mIconView.setVisibility(willDraw ? View.VISIBLE : View.INVISIBLE);
+    }
+
+
+    /**
+     * Drag and drop handler for popup items in Launcher activity
+     */
+    public static class HeroItemDragHandler implements OnLongClickListener {
+        private final Launcher mLauncher;
+        private final HeroSearchResultView mContainer;
+
+        HeroItemDragHandler(Context context, HeroSearchResultView container) {
+            mLauncher = Launcher.getLauncher(context);
+            mContainer = container;
+        }
+
+        @Override
+        public boolean onLongClick(View v) {
+            if (!ItemLongClickListener.canStartDrag(mLauncher)) return false;
+            mContainer.setWillDrawIcon(false);
+
+            DraggableView draggableView = DraggableView.ofType(DraggableView.DRAGGABLE_ICON);
+            WorkspaceItemInfo itemInfo = new WorkspaceItemInfo((AppInfo) v.getTag());
+            itemInfo.container = CONTAINER_ALL_APPS;
+            DragPreviewProvider previewProvider = new ShortcutDragPreviewProvider(
+                    mContainer.mIconView, new Point());
+            mLauncher.getWorkspace().beginDragShared(mContainer.mBubbleTextView,
+                    draggableView, mContainer, itemInfo, previewProvider, new DragOptions());
+
+            return false;
+        }
+    }
+}