Consolidate Hero search result with SearchResultIconRow

With this, we can now show app title and support drag/drop for shortcut results.

Bug: 172245107
preview: https://drive.google.com/file/d/1A4eKKTDPht-MDbfA2VFI3OuAO36fc3AS/view?usp=sharing
Change-Id: Icf94a2d23b44bfe5527aea71e27178906e5deb3e
diff --git a/res/layout/search_result_hero_app.xml b/res/layout/search_result_hero_app.xml
deleted file mode 100644
index bd0e42b..0000000
--- a/res/layout/search_result_hero_app.xml
+++ /dev/null
@@ -1,74 +0,0 @@
-<?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/layout/search_result_icon_row.xml b/res/layout/search_result_icon_row.xml
index ef3c8b2..b51896e 100644
--- a/res/layout/search_result_icon_row.xml
+++ b/res/layout/search_result_icon_row.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2020 The Android Open Source Projectza
+<?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.
@@ -14,18 +14,61 @@
 -->
 <com.android.launcher3.views.SearchResultIconRow xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:launcher="http://schemas.android.com/apk/res-auto"
-    style="@style/BaseIcon"
+    android:orientation="horizontal"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:orientation="horizontal"
-    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:padding="@dimen/dynamic_grid_edge_margin"
-    launcher:iconDisplay="hero_app"
-    launcher:layoutHorizontal="true"
-    >
+    android:padding="@dimen/dynamic_grid_edge_margin">
+
+    <com.android.launcher3.views.SearchResultIcon
+        android:layout_width="wrap_content"
+        android:id="@+id/icon"
+        launcher:iconDisplay="hero_app"
+        android:layout_height="wrap_content" />
+
+    <LinearLayout
+        android:layout_width="0dp"
+        android:layout_weight="1"
+        android:layout_height="wrap_content"
+        android:padding="@dimen/dynamic_grid_edge_margin"
+        android:orientation="vertical"
+        android:layout_gravity="center_vertical">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:id="@id/title"
+            android:layout_height="wrap_content"
+            android:gravity="start|center_vertical"
+            android:textAlignment="viewStart"
+            android:textColor="?android:attr/textColorPrimary"
+            android:textSize="@dimen/settings_hero_title_size" />
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:id="@+id/desc"
+            android:textColor="?android:attr/textColorTertiary"
+            android:textSize="@dimen/settings_hero_subtitle_size"
+            android:layout_height="wrap_content" />
+    </LinearLayout>
+
+    <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"
+        launcher:iconDisplay="shortcut_popup"
+        android:textSize="@dimen/settings_hero_subtitle_size"
+        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"
+        launcher:iconDisplay="shortcut_popup"
+        android:textSize="@dimen/settings_hero_inline_button_size"
+        launcher:iconSizeOverride="@dimen/deep_shortcut_icon_size"
+        launcher:layoutHorizontal="false" />
 
 </com.android.launcher3.views.SearchResultIconRow>
\ No newline at end of file
diff --git a/res/layout/search_result_suggest.xml b/res/layout/search_result_suggest.xml
index 1d8c803..01e25d5 100644
--- a/res/layout/search_result_suggest.xml
+++ b/res/layout/search_result_suggest.xml
@@ -12,7 +12,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.launcher3.views.SearchResultIconRow xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.launcher3.views.SearchResultSuggestion xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:launcher="http://schemas.android.com/apk/res-auto"
     style="@style/BaseIcon"
     android:layout_width="match_parent"
@@ -26,10 +26,9 @@
     launcher:iconDisplay="hero_app"
     android:drawableTint="?android:attr/textColorPrimary"
     launcher:customIcon="@drawable/ic_allapps_search"
-    launcher:iconSizeOverride="48dp"
+    launcher:iconSizeOverride="24dp"
     launcher:matchTextInsetWithQuery="true"
     launcher:layoutHorizontal="true"
-    android:drawablePadding="@dimen/dynamic_grid_icon_drawable_padding"
-    >
+    android:drawablePadding="@dimen/dynamic_grid_icon_drawable_padding">
 
-</com.android.launcher3.views.SearchResultIconRow>
\ No newline at end of file
+</com.android.launcher3.views.SearchResultSuggestion>
\ No newline at end of file
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index c3ad1eb..96c30b5 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
 /* Copyright 2008, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
@@ -30,13 +29,13 @@
     <attr name="isWorkspaceDarkText" format="boolean" />
     <attr name="workspaceTextColor" format="color" />
     <attr name="workspaceShadowColor" format="color" />
-    <attr name="workspaceAmbientShadowColor" format="color"/>
+    <attr name="workspaceAmbientShadowColor" format="color" />
     <attr name="workspaceKeyShadowColor" format="color" />
     <attr name="workspaceStatusBarScrim" format="reference" />
     <attr name="widgetsTheme" format="reference" />
     <attr name="loadingIconColor" format="color" />
-    <attr name="iconOnlyShortcutColor" format="color"/>
-    <attr name="eduHalfSheetBGColor" format="color"/>
+    <attr name="iconOnlyShortcutColor" format="color" />
+    <attr name="eduHalfSheetBGColor" format="color" />
 
     <attr name="folderDotColor" format="color" />
     <attr name="folderFillColor" format="color" />
@@ -69,13 +68,12 @@
         <attr name="folderDotColor" />
     </declare-styleable>
 
-    <declare-styleable name="SearchResultIconRow">
+    <declare-styleable name="SearchResultSuggestion">
         <attr name="customIcon" format="reference" />
         <attr name="matchTextInsetWithQuery" format="boolean" />
     </declare-styleable>
 
 
-
     <declare-styleable name="ShadowInfo">
         <attr name="ambientShadowColor" format="color" />
         <attr name="ambientShadowBlur" format="dimension" />
@@ -167,7 +165,7 @@
         <attr name="android:src" />
         <attr name="android:shadowColor" />
         <attr name="android:elevation" />
-        <attr name="darkTintColor" format="color"/>
+        <attr name="darkTintColor" format="color" />
     </declare-styleable>
 
     <declare-styleable name="RecyclerViewFastScroller">
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index f59f02f..5387e1b 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -248,4 +248,9 @@
     <!-- Onboarding bottomsheet related -->
     <dimen name="bottom_sheet_edu_padding">24dp</dimen>
 
+    <!-- Search related -->
+    <dimen name="settings_hero_title_size">16sp</dimen>
+    <dimen name="settings_hero_subtitle_size">15sp</dimen>
+    <dimen name="settings_hero_inline_button_size">12sp</dimen>
+
 </resources>
diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
index f773191..7018f20 100644
--- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
+++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
@@ -75,8 +75,6 @@
 
     public static final int VIEW_TYPE_SEARCH_CORPUS_TITLE = 1 << 5;
 
-    public static final int VIEW_TYPE_SEARCH_HERO_APP = 1 << 6;
-
     public static final int VIEW_TYPE_SEARCH_ROW_WITH_BUTTON = 1 << 7;
 
     public static final int VIEW_TYPE_SEARCH_ROW = 1 << 8;
@@ -178,7 +176,6 @@
 
         boolean isCountedForAccessibility() {
             return viewType == VIEW_TYPE_ICON
-                    || viewType == VIEW_TYPE_SEARCH_HERO_APP
                     || viewType == VIEW_TYPE_SEARCH_ROW_WITH_BUTTON
                     || viewType == VIEW_TYPE_SEARCH_SLICE
                     || viewType == VIEW_TYPE_SEARCH_ROW
@@ -411,9 +408,6 @@
             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));
             case VIEW_TYPE_SEARCH_ROW_WITH_BUTTON:
                 return new ViewHolder(mLayoutInflater.inflate(
                         R.layout.search_result_play_item, parent, false));
@@ -478,7 +472,6 @@
                 break;
             case VIEW_TYPE_SEARCH_CORPUS_TITLE:
             case VIEW_TYPE_SEARCH_ROW_WITH_BUTTON:
-            case VIEW_TYPE_SEARCH_HERO_APP:
             case VIEW_TYPE_SEARCH_ROW:
             case VIEW_TYPE_SEARCH_ICON:
             case VIEW_TYPE_SEARCH_ICON_ROW:
diff --git a/src/com/android/launcher3/touch/ItemClickHandler.java b/src/com/android/launcher3/touch/ItemClickHandler.java
index d56391d..9b9cb0a 100644
--- a/src/com/android/launcher3/touch/ItemClickHandler.java
+++ b/src/com/android/launcher3/touch/ItemClickHandler.java
@@ -96,6 +96,8 @@
             if (v instanceof PendingAppWidgetHostView) {
                 onClickPendingWidget((PendingAppWidgetHostView) v, launcher);
             }
+        } else if (tag instanceof RemoteActionItemInfo) {
+            onClickRemoteAction(launcher, (RemoteActionItemInfo) tag);
         }
     }
 
diff --git a/src/com/android/launcher3/views/HeroSearchResultView.java b/src/com/android/launcher3/views/HeroSearchResultView.java
deleted file mode 100644
index a098df9..0000000
--- a/src/com/android/launcher3/views/HeroSearchResultView.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * 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 static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
-
-import android.content.Context;
-import android.content.pm.ShortcutInfo;
-import android.graphics.Point;
-import android.util.AttributeSet;
-import android.util.Pair;
-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.LauncherAppState;
-import com.android.launcher3.R;
-import com.android.launcher3.allapps.AllAppsStore;
-import com.android.launcher3.allapps.search.AllAppsSearchBarController.SearchTargetHandler;
-import com.android.launcher3.allapps.search.SearchEventTracker;
-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.ItemInfoWithIcon;
-import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider;
-import com.android.launcher3.touch.ItemLongClickListener;
-import com.android.launcher3.util.ComponentKey;
-import com.android.systemui.plugins.shared.SearchTarget;
-import com.android.systemui.plugins.shared.SearchTargetEvent;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A view representing a high confidence app search result that includes shortcuts
- * TODO (sfufa@) consolidate this with SearchResultIconRow
- */
-public class HeroSearchResultView extends LinearLayout implements DragSource, SearchTargetHandler {
-
-    public static final String TARGET_TYPE_HERO_APP = "hero_app";
-
-    public static final int MAX_SHORTCUTS_COUNT = 2;
-
-    private SearchTarget mSearchTarget;
-    private BubbleTextView mBubbleTextView;
-    private View mIconView;
-    private 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(view -> {
-            handleSelection(SearchTargetEvent.SELECT);
-            launcher.getItemOnClickListener().onClick(view);
-        });
-        mBubbleTextView.setOnLongClickListener(new HeroItemDragHandler(getContext(), this));
-
-
-        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(view -> {
-                WorkspaceItemInfo itemInfo = (WorkspaceItemInfo) bubbleTextView.getTag();
-                SearchTargetEvent event = new SearchTargetEvent.Builder(mSearchTarget,
-                        SearchTargetEvent.CHILD_SELECT).setShortcutPosition(itemInfo.rank).build();
-                SearchEventTracker.getInstance(getContext()).notifySearchTargetEvent(event);
-                launcher.getItemOnClickListener().onClick(view);
-            });
-        }
-    }
-
-    @Override
-    public void applySearchTarget(SearchTarget searchTarget) {
-        mSearchTarget = searchTarget;
-        AllAppsStore apps = Launcher.getLauncher(getContext()).getAppsView().getAppsStore();
-        AppInfo appInfo = apps.getApp(new ComponentKey(searchTarget.getComponentName(),
-                searchTarget.getUserHandle()));
-        List<ShortcutInfo> infos = mSearchTarget.getShortcutInfos();
-
-        ArrayList<Pair<ShortcutInfo, ItemInfoWithIcon>> shortcuts = new ArrayList<>();
-        for (int i = 0; infos != null && i < infos.size() && i < MAX_SHORTCUTS_COUNT; i++) {
-            ShortcutInfo shortcutInfo = infos.get(i);
-            ItemInfoWithIcon si = new WorkspaceItemInfo(shortcutInfo, getContext());
-            si.rank = i;
-            shortcuts.add(new Pair<>(shortcutInfo, si));
-        }
-
-        mBubbleTextView.applyFromApplicationInfo(appInfo);
-        mIconView.setBackground(mBubbleTextView.getIcon());
-        mIconView.setTag(appInfo);
-        LauncherAppState appState = LauncherAppState.getInstance(getContext());
-        for (int i = 0; i < mDeepShortcutTextViews.length; i++) {
-            BubbleTextView shortcutView = mDeepShortcutTextViews[i];
-            mDeepShortcutTextViews[i].setVisibility(shortcuts.size() > i ? VISIBLE : GONE);
-            if (i < shortcuts.size()) {
-                Pair<ShortcutInfo, ItemInfoWithIcon> p = shortcuts.get(i);
-                //apply ItemInfo and prepare view
-                shortcutView.applyFromWorkspaceItem((WorkspaceItemInfo) p.second);
-                MODEL_EXECUTOR.execute(() -> {
-                    // load unbadged shortcut in background and update view when icon ready
-                    appState.getIconCache().getUnbadgedShortcutIcon(p.second, p.first);
-                    MAIN_EXECUTOR.post(() -> shortcutView.reapplyItemInfo(p.second));
-                });
-            }
-        }
-        SearchEventTracker.INSTANCE.get(getContext()).registerWeakHandler(searchTarget, this);
-    }
-
-    @Override
-    public void onDropCompleted(View target, DropTarget.DragObject d, boolean success) {
-        mBubbleTextView.setVisibility(VISIBLE);
-        mBubbleTextView.setIconVisible(true);
-    }
-
-    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());
-
-            SearchTargetEvent event = new SearchTargetEvent.Builder(mContainer.mSearchTarget,
-                    SearchTargetEvent.LONG_PRESS).build();
-            SearchEventTracker.INSTANCE.get(mLauncher).notifySearchTargetEvent(event);
-            return false;
-        }
-    }
-
-    @Override
-    public void handleSelection(int eventType) {
-        ItemInfo itemInfo = (ItemInfo) mBubbleTextView.getTag();
-        if (itemInfo == null) return;
-        Launcher launcher = Launcher.getLauncher(getContext());
-        launcher.startActivitySafely(this, itemInfo.getIntent(), itemInfo);
-
-        SearchEventTracker.INSTANCE.get(getContext()).notifySearchTargetEvent(
-                new SearchTargetEvent.Builder(mSearchTarget, eventType).build());
-    }
-}
diff --git a/src/com/android/launcher3/views/SearchResultIcon.java b/src/com/android/launcher3/views/SearchResultIcon.java
index ea06d5b..0851b54 100644
--- a/src/com/android/launcher3/views/SearchResultIcon.java
+++ b/src/com/android/launcher3/views/SearchResultIcon.java
@@ -15,16 +15,35 @@
  */
 package com.android.launcher3.views;
 
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+
+import android.app.RemoteAction;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.pm.ShortcutInfo;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.os.UserHandle;
 import android.util.AttributeSet;
 import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.UiThread;
 
 import com.android.launcher3.BubbleTextView;
 import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.allapps.AllAppsStore;
 import com.android.launcher3.allapps.search.AllAppsSearchBarController;
 import com.android.launcher3.allapps.search.SearchEventTracker;
+import com.android.launcher3.icons.BitmapInfo;
+import com.android.launcher3.icons.LauncherIcons;
 import com.android.launcher3.model.data.AppInfo;
+import com.android.launcher3.model.data.ItemInfoWithIcon;
+import com.android.launcher3.model.data.RemoteActionItemInfo;
+import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.touch.ItemLongClickListener;
 import com.android.launcher3.util.ComponentKey;
 import com.android.systemui.plugins.shared.SearchTarget;
@@ -39,6 +58,17 @@
 
 
     public static final String TARGET_TYPE_APP = "app";
+    public static final String TARGET_TYPE_HERO_APP = "hero_app";
+    public static final String TARGET_TYPE_SHORTCUT = "shortcut";
+    public static final String TARGET_TYPE_REMOTE_ACTION = "remote_action";
+    public static final String TARGET_TYPE_SUGGEST = "suggest";
+
+    public static final String REMOTE_ACTION_SHOULD_START = "should_start_for_result";
+    public static final String REMOTE_ACTION_TOKEN = "action_token";
+
+
+    private static final String[] LONG_PRESS_SUPPORTED_TYPES =
+            new String[]{TARGET_TYPE_APP, TARGET_TYPE_SHORTCUT, TARGET_TYPE_HERO_APP};
 
     private final Launcher mLauncher;
 
@@ -64,26 +94,96 @@
         setOnFocusChangeListener(mLauncher.getFocusHandler());
         setOnClickListener(this);
         setOnLongClickListener(this);
-        getLayoutParams().height = mLauncher.getDeviceProfile().allAppsCellHeightPx;
+        setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+                mLauncher.getDeviceProfile().allAppsCellHeightPx));
     }
 
     @Override
     public void applySearchTarget(SearchTarget searchTarget) {
         mSearchTarget = searchTarget;
-        AllAppsStore appsStore = mLauncher.getAppsView().getAppsStore();
         SearchEventTracker.getInstance(getContext()).registerWeakHandler(mSearchTarget, this);
-        if (searchTarget.getItemType().equals(TARGET_TYPE_APP)) {
-            AppInfo appInfo = appsStore.getApp(new ComponentKey(searchTarget.getComponentName(),
-                    searchTarget.getUserHandle()));
-            applyFromApplicationInfo(appInfo);
+        switch (searchTarget.getItemType()) {
+            case TARGET_TYPE_APP:
+            case TARGET_TYPE_HERO_APP:
+                prepareUsingApp(searchTarget.getComponentName(), searchTarget.getUserHandle());
+                break;
+            case TARGET_TYPE_SHORTCUT:
+                prepareUsingShortcutInfo(searchTarget.getShortcutInfos().get(0));
+                break;
+            case TARGET_TYPE_REMOTE_ACTION:
+            case TARGET_TYPE_SUGGEST:
+                prepareUsingRemoteAction(searchTarget.getRemoteAction(),
+                        searchTarget.getExtras().getString(REMOTE_ACTION_TOKEN),
+                        searchTarget.getExtras().getBoolean(REMOTE_ACTION_SHOULD_START),
+                        searchTarget.getItemType().equals(TARGET_TYPE_REMOTE_ACTION));
+                break;
         }
     }
 
+    private void prepareUsingApp(ComponentName componentName, UserHandle userHandle) {
+        AllAppsStore appsStore = mLauncher.getAppsView().getAppsStore();
+        AppInfo appInfo = appsStore.getApp(new ComponentKey(componentName, userHandle));
+        applyFromApplicationInfo(appInfo);
+    }
+
+
+    private void prepareUsingShortcutInfo(ShortcutInfo shortcutInfo) {
+        WorkspaceItemInfo workspaceItemInfo = new WorkspaceItemInfo(shortcutInfo, getContext());
+        applyFromWorkspaceItem(workspaceItemInfo);
+        LauncherAppState launcherAppState = LauncherAppState.getInstance(getContext());
+        MODEL_EXECUTOR.execute(() -> {
+            launcherAppState.getIconCache().getShortcutIcon(workspaceItemInfo, shortcutInfo);
+            reapplyItemInfoAsync(workspaceItemInfo);
+        });
+    }
+
+    private void prepareUsingRemoteAction(RemoteAction remoteAction, String token, boolean start,
+            boolean useIconToBadge) {
+        RemoteActionItemInfo itemInfo = new RemoteActionItemInfo(remoteAction, token, start);
+
+        applyFromRemoteActionInfo(itemInfo);
+        if (!loadIconFromResource()) {
+            UI_HELPER_EXECUTOR.post(() -> {
+                // If the Drawable from the remote action is not AdaptiveBitmap, styling will not
+                // work.
+                try (LauncherIcons li = LauncherIcons.obtain(getContext())) {
+                    Drawable d = itemInfo.getRemoteAction().getIcon().loadDrawable(getContext());
+                    BitmapInfo bitmap = li.createBadgedIconBitmap(d, itemInfo.user,
+                            Build.VERSION.SDK_INT);
+
+                    if (useIconToBadge) {
+                        BitmapInfo placeholder = li.createIconBitmap(
+                                itemInfo.getRemoteAction().getTitle().toString().substring(0, 1),
+                                bitmap.color);
+                        itemInfo.bitmap = li.badgeBitmap(placeholder.icon, bitmap);
+                    } else {
+                        itemInfo.bitmap = bitmap;
+                    }
+                    reapplyItemInfoAsync(itemInfo);
+                }
+            });
+        }
+    }
+
+    @UiThread
+    void reapplyItemInfoAsync(ItemInfoWithIcon itemInfoWithIcon) {
+        MAIN_EXECUTOR.post(() -> reapplyItemInfo(itemInfoWithIcon));
+    }
+
+
     @Override
     public void handleSelection(int eventType) {
         mLauncher.getItemOnClickListener().onClick(this);
-        SearchEventTracker.INSTANCE.get(mLauncher).notifySearchTargetEvent(
-                new SearchTargetEvent.Builder(mSearchTarget, eventType).build());
+        reportEvent(eventType);
+    }
+
+    private void reportEvent(int eventType) {
+        SearchTargetEvent.Builder b = new SearchTargetEvent.Builder(mSearchTarget, eventType);
+        if (mSearchTarget.getItemType().equals(TARGET_TYPE_SHORTCUT)) {
+            b.setShortcutPosition(0);
+        }
+        SearchEventTracker.INSTANCE.get(mLauncher).notifySearchTargetEvent(b.build());
+
     }
 
     @Override
@@ -93,8 +193,22 @@
 
     @Override
     public boolean onLongClick(View view) {
-        SearchEventTracker.INSTANCE.get(mLauncher).notifySearchTargetEvent(
-                new SearchTargetEvent.Builder(mSearchTarget, SearchTargetEvent.LONG_PRESS).build());
+        if (!supportsLongPress(mSearchTarget.getItemType())) {
+            return false;
+        }
+        reportEvent(SearchTargetEvent.LONG_PRESS);
         return ItemLongClickListener.INSTANCE_ALL_APPS.onLongClick(view);
+
+    }
+
+    private boolean supportsLongPress(String type) {
+        for (String t : LONG_PRESS_SUPPORTED_TYPES) {
+            if (t.equals(type)) return true;
+        }
+        return false;
+    }
+
+    protected boolean loadIconFromResource() {
+        return false;
     }
 }
diff --git a/src/com/android/launcher3/views/SearchResultIconRow.java b/src/com/android/launcher3/views/SearchResultIconRow.java
index bdbe890..03332c1 100644
--- a/src/com/android/launcher3/views/SearchResultIconRow.java
+++ b/src/com/android/launcher3/views/SearchResultIconRow.java
@@ -17,188 +17,173 @@
 
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
-import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
 
-import android.app.RemoteAction;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.ShortcutInfo;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.drawable.Drawable;
-import android.os.Build;
+import android.os.UserHandle;
 import android.util.AttributeSet;
-import android.widget.EditText;
+import android.util.Pair;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.TextView;
 
-import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.android.launcher3.BubbleTextView;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.R;
 import com.android.launcher3.allapps.search.AllAppsSearchBarController;
 import com.android.launcher3.allapps.search.SearchEventTracker;
-import com.android.launcher3.icons.BitmapInfo;
-import com.android.launcher3.icons.LauncherIcons;
-import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.ItemInfoWithIcon;
-import com.android.launcher3.model.data.RemoteActionItemInfo;
+import com.android.launcher3.model.data.PackageItemInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.touch.ItemClickHandler;
-import com.android.launcher3.util.Themes;
 import com.android.systemui.plugins.shared.SearchTarget;
 import com.android.systemui.plugins.shared.SearchTargetEvent;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
- * A view representing a stand alone shortcut search result
+ * A full width representation of {@link SearchResultIcon} with a secondary label and inline
+ * shortcuts
  */
-public class SearchResultIconRow extends DoubleShadowBubbleTextView implements
-        AllAppsSearchBarController.SearchTargetHandler {
+public class SearchResultIconRow extends LinearLayout implements
+        AllAppsSearchBarController.SearchTargetHandler, View.OnClickListener,
+        View.OnLongClickListener {
+    public static final int MAX_SHORTCUTS_COUNT = 2;
 
 
-    public static final String TARGET_TYPE_REMOTE_ACTION = "remote_action";
-    public static final String TARGET_TYPE_SUGGEST = "suggest";
-    public static final String TARGET_TYPE_SHORTCUT = "shortcut";
-
-
-    public static final String REMOTE_ACTION_SHOULD_START = "should_start_for_result";
-    public static final String REMOTE_ACTION_TOKEN = "action_token";
-
-    private final boolean mMatchesInset;
+    private final Launcher mLauncher;
+    private final LauncherAppState mLauncherAppState;
+    private SearchResultIcon mResultIcon;
+    private TextView mTitleView;
+    private TextView mDescriptionView;
+    private BubbleTextView[] mShortcutViews = new BubbleTextView[2];
 
     private SearchTarget mSearchTarget;
+    private PackageItemInfo mProviderInfo;
 
-    @Nullable private Drawable mCustomIcon;
 
-    public SearchResultIconRow(@NonNull Context context) {
+    public SearchResultIconRow(Context context) {
         this(context, null, 0);
     }
 
-    public SearchResultIconRow(@NonNull Context context,
+    public SearchResultIconRow(Context context,
             @Nullable AttributeSet attrs) {
         this(context, attrs, 0);
     }
 
-    public SearchResultIconRow(@NonNull Context context, @Nullable AttributeSet attrs,
-            int defStyleAttr) {
+    public SearchResultIconRow(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                R.styleable.SearchResultIconRow, defStyleAttr, 0);
-        mMatchesInset = a.getBoolean(R.styleable.SearchResultIconRow_matchTextInsetWithQuery,
-                false);
-
-        int customIconResId = a.getResourceId(R.styleable.SearchResultIconRow_customIcon, 0);
-
-        if (customIconResId != 0) {
-            mCustomIcon = Launcher.getLauncher(context).getDrawable(customIconResId);
-        }
-
-        a.recycle();
-    }
-
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        Launcher launcher = Launcher.getLauncher(getContext());
-        if (mMatchesInset && launcher.getAppsView() != null && getParent() != null) {
-            EditText editText = launcher.getAppsView().getSearchUiManager().getEditText();
-            if (editText != null) {
-                int counterOffset = getIconSize() + getCompoundDrawablePadding() / 2;
-                setPadding(editText.getLeft() - counterOffset, getPaddingTop(),
-                        getPaddingRight(), getPaddingBottom());
-            }
-        }
+        mLauncher = Launcher.getLauncher(getContext());
+        mLauncherAppState = LauncherAppState.getInstance(getContext());
     }
 
     @Override
-    protected void drawFocusHighlight(Canvas canvas) {
-        mHighlightPaint.setColor(mHighlightColor);
-        float r = Themes.getDialogCornerRadius(getContext());
-        canvas.drawRoundRect(0, 0, getWidth(), getHeight(), r, r, mHighlightPaint);
-    }
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        int iconSize = mLauncher.getDeviceProfile().allAppsIconSizePx;
 
+        mResultIcon = findViewById(R.id.icon);
+        mTitleView = findViewById(R.id.title);
+        mDescriptionView = findViewById(R.id.desc);
+        mShortcutViews[0] = findViewById(R.id.shortcut_0);
+        mShortcutViews[1] = findViewById(R.id.shortcut_1);
+        mResultIcon.getLayoutParams().height = iconSize;
+        mResultIcon.getLayoutParams().width = iconSize;
+        for (BubbleTextView bubbleTextView : mShortcutViews) {
+            ViewGroup.LayoutParams lp = bubbleTextView.getLayoutParams();
+            lp.width = iconSize;
+            bubbleTextView.setOnClickListener(view -> {
+                WorkspaceItemInfo itemInfo = (WorkspaceItemInfo) bubbleTextView.getTag();
+                SearchTargetEvent event = new SearchTargetEvent.Builder(mSearchTarget,
+                        SearchTargetEvent.CHILD_SELECT).setShortcutPosition(itemInfo.rank).build();
+                SearchEventTracker.getInstance(getContext()).notifySearchTargetEvent(event);
+                mLauncher.getItemOnClickListener().onClick(view);
+            });
+        }
+        setOnClickListener(this);
+        setOnLongClickListener(this);
+    }
 
     @Override
     public void applySearchTarget(SearchTarget searchTarget) {
         mSearchTarget = searchTarget;
-        String type = searchTarget.getItemType();
-        if (type.equals(TARGET_TYPE_REMOTE_ACTION) || type.equals(TARGET_TYPE_SUGGEST)) {
-            prepareUsingRemoteAction(searchTarget.getRemoteAction(),
-                    searchTarget.getExtras().getString(REMOTE_ACTION_TOKEN),
-                    searchTarget.getExtras().getBoolean(REMOTE_ACTION_SHOULD_START),
-                    type.equals(TARGET_TYPE_REMOTE_ACTION));
+        mResultIcon.applySearchTarget(searchTarget);
+        mResultIcon.setTextVisibility(false);
+        mTitleView.setText(mResultIcon.getText());
+        String itemType = searchTarget.getItemType();
+        boolean showDesc = itemType.equals(SearchResultIcon.TARGET_TYPE_SHORTCUT);
+        mDescriptionView.setVisibility(showDesc ? VISIBLE : GONE);
 
-        } else if (type.equals(TARGET_TYPE_SHORTCUT)) {
-            prepareUsingShortcutInfo(searchTarget.getShortcutInfos().get(0));
+        if (itemType.equals(SearchResultIcon.TARGET_TYPE_SHORTCUT)) {
+            ShortcutInfo shortcutInfo = searchTarget.getShortcutInfos().get(0);
+            setProviderDetails(new ComponentName(shortcutInfo.getPackage(), ""),
+                    shortcutInfo.getUserHandle());
+        } else if (itemType.equals(SearchResultIcon.TARGET_TYPE_HERO_APP)) {
+            showInlineShortcuts(mSearchTarget.getShortcutInfos());
         }
-        setOnClickListener(v -> handleSelection(SearchTargetEvent.SELECT));
-        SearchEventTracker.INSTANCE.get(getContext()).registerWeakHandler(searchTarget, this);
+        if (!itemType.equals(SearchResultIcon.TARGET_TYPE_HERO_APP)) {
+            showInlineShortcuts(new ArrayList<>());
+        }
     }
 
-    private void prepareUsingShortcutInfo(ShortcutInfo shortcutInfo) {
-        WorkspaceItemInfo workspaceItemInfo = new WorkspaceItemInfo(shortcutInfo, getContext());
-        applyFromWorkspaceItem(workspaceItemInfo);
-        LauncherAppState launcherAppState = LauncherAppState.getInstance(getContext());
-        if (!loadIconFromResource()) {
-            MODEL_EXECUTOR.execute(() -> {
-                launcherAppState.getIconCache().getShortcutIcon(workspaceItemInfo, shortcutInfo);
-                reapplyItemInfoAsync(workspaceItemInfo);
+    private void showInlineShortcuts(List<ShortcutInfo> infos) {
+        if (infos == null) return;
+        ArrayList<Pair<ShortcutInfo, ItemInfoWithIcon>> shortcuts = new ArrayList<>();
+        for (int i = 0; infos != null && i < infos.size() && i < MAX_SHORTCUTS_COUNT; i++) {
+            ShortcutInfo shortcutInfo = infos.get(i);
+            ItemInfoWithIcon si = new WorkspaceItemInfo(shortcutInfo, getContext());
+            si.rank = i;
+            shortcuts.add(new Pair<>(shortcutInfo, si));
+        }
+
+        for (int i = 0; i < mShortcutViews.length; i++) {
+            BubbleTextView shortcutView = mShortcutViews[i];
+            mShortcutViews[i].setVisibility(shortcuts.size() > i ? VISIBLE : GONE);
+            if (i < shortcuts.size()) {
+                Pair<ShortcutInfo, ItemInfoWithIcon> p = shortcuts.get(i);
+                //apply ItemInfo and prepare view
+                shortcutView.applyFromWorkspaceItem((WorkspaceItemInfo) p.second);
+                MODEL_EXECUTOR.execute(() -> {
+                    // load unbadged shortcut in background and update view when icon ready
+                    mLauncherAppState.getIconCache().getUnbadgedShortcutIcon(p.second, p.first);
+                    MAIN_EXECUTOR.post(() -> shortcutView.reapplyItemInfo(p.second));
+                });
+            }
+        }
+    }
+
+
+    private void setProviderDetails(ComponentName componentName, UserHandle userHandle) {
+        PackageItemInfo packageItemInfo = new PackageItemInfo(componentName.getPackageName());
+        if (mProviderInfo == packageItemInfo) return;
+        MODEL_EXECUTOR.post(() -> {
+            packageItemInfo.user = userHandle;
+            mLauncherAppState.getIconCache().getTitleAndIconForApp(packageItemInfo, true);
+            MAIN_EXECUTOR.post(() -> {
+                mDescriptionView.setText(packageItemInfo.title);
+                mProviderInfo = packageItemInfo;
             });
-        }
-    }
-
-    private void prepareUsingRemoteAction(RemoteAction remoteAction, String token, boolean start,
-            boolean useIconToBadge) {
-        RemoteActionItemInfo itemInfo = new RemoteActionItemInfo(remoteAction, token, start);
-
-        applyFromRemoteActionInfo(itemInfo);
-        if (itemInfo.isEscapeHatch() || !loadIconFromResource()) {
-            UI_HELPER_EXECUTOR.post(() -> {
-                // If the Drawable from the remote action is not AdaptiveBitmap, styling will not
-                // work.
-                try (LauncherIcons li = LauncherIcons.obtain(getContext())) {
-                    Drawable d = itemInfo.getRemoteAction().getIcon().loadDrawable(getContext());
-                    BitmapInfo bitmap = li.createBadgedIconBitmap(d, itemInfo.user,
-                            Build.VERSION.SDK_INT);
-
-                    if (useIconToBadge) {
-                        BitmapInfo placeholder = li.createIconBitmap(
-                                itemInfo.getRemoteAction().getTitle().toString().substring(0, 1),
-                                bitmap.color);
-                        itemInfo.bitmap = li.badgeBitmap(placeholder.icon, bitmap);
-                    } else {
-                        itemInfo.bitmap = bitmap;
-                    }
-                    reapplyItemInfoAsync(itemInfo);
-                }
-            });
-        }
-
-    }
-
-    private boolean loadIconFromResource() {
-        if (mCustomIcon == null) return false;
-        setIcon(mCustomIcon);
-        return true;
-    }
-
-    void reapplyItemInfoAsync(ItemInfoWithIcon itemInfoWithIcon) {
-        MAIN_EXECUTOR.post(() -> {
-            reapplyItemInfo(itemInfoWithIcon);
-            mCustomIcon = getIcon();
         });
     }
 
     @Override
     public void handleSelection(int eventType) {
-        ItemInfo itemInfo = (ItemInfo) getTag();
-        Launcher launcher = Launcher.getLauncher(getContext());
-        if (itemInfo instanceof WorkspaceItemInfo) {
-            ItemClickHandler.onClickAppShortcut(this, (WorkspaceItemInfo) itemInfo, launcher);
-        } else {
-            ItemClickHandler.onClickRemoteAction(launcher, (RemoteActionItemInfo) itemInfo);
-        }
-        SearchEventTracker.INSTANCE.get(getContext()).notifySearchTargetEvent(
-                new SearchTargetEvent.Builder(mSearchTarget, eventType).build());
+        mResultIcon.handleSelection(eventType);
+    }
+
+    @Override
+    public void onClick(View view) {
+        mResultIcon.performClick();
+    }
+
+    @Override
+    public boolean onLongClick(View view) {
+        mResultIcon.performLongClick();
+        return false;
     }
 }
diff --git a/src/com/android/launcher3/views/SearchResultSuggestion.java b/src/com/android/launcher3/views/SearchResultSuggestion.java
new file mode 100644
index 0000000..ab94bf0
--- /dev/null
+++ b/src/com/android/launcher3/views/SearchResultSuggestion.java
@@ -0,0 +1,62 @@
+/*
+ * 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 android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.ViewGroup;
+
+import com.android.launcher3.R;
+
+/**
+ * {@link SearchResultIconRow} with custom drawable resource
+ */
+public class SearchResultSuggestion extends SearchResultIcon {
+
+    private final Drawable mCustomIcon;
+
+    public SearchResultSuggestion(Context context) {
+        this(context, null, 0);
+    }
+
+    public SearchResultSuggestion(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public SearchResultSuggestion(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        TypedArray a = context.obtainStyledAttributes(attrs,
+                R.styleable.SearchResultSuggestion, defStyle, 0);
+        mCustomIcon = a.getDrawable(R.styleable.SearchResultSuggestion_customIcon);
+        a.recycle();
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        ViewGroup.LayoutParams lp = getLayoutParams();
+        lp.height = BaseDragLayer.LayoutParams.WRAP_CONTENT;
+    }
+
+    @Override
+    protected boolean loadIconFromResource() {
+        setIcon(mCustomIcon);
+        return true;
+    }
+}
diff --git a/src/com/android/launcher3/views/ThumbnailSearchResultView.java b/src/com/android/launcher3/views/ThumbnailSearchResultView.java
index e929d7f..f213f22 100644
--- a/src/com/android/launcher3/views/ThumbnailSearchResultView.java
+++ b/src/com/android/launcher3/views/ThumbnailSearchResultView.java
@@ -15,8 +15,9 @@
  */
 package com.android.launcher3.views;
 
-import static com.android.launcher3.views.SearchResultIconRow.REMOTE_ACTION_SHOULD_START;
-import static com.android.launcher3.views.SearchResultIconRow.REMOTE_ACTION_TOKEN;
+
+import static com.android.launcher3.views.SearchResultIcon.REMOTE_ACTION_SHOULD_START;
+import static com.android.launcher3.views.SearchResultIcon.REMOTE_ACTION_TOKEN;
 
 import android.content.Context;
 import android.content.Intent;