Consolidate Search result UIs

- Allow SearchAction to be represented by SearchResultIcon and SearchResultIconRow
- Fix tap enter to launch regression
- Remove Plugin Pipeline

Bug: 177223401
Test: Manual
Change-Id: Id1d445f6af3f80f840d567165051188c78230ed0
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index f44f88b..22eb15a 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -72,7 +72,7 @@
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.ItemInfoWithIcon;
 import com.android.launcher3.model.data.PackageItemInfo;
-import com.android.launcher3.model.data.RemoteActionItemInfo;
+import com.android.launcher3.model.data.SearchActionItemInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.util.SafeCloseable;
 import com.android.launcher3.views.ActivityContext;
@@ -319,14 +319,14 @@
     }
 
     /**
-     * Apply label and tag using a {@link RemoteActionItemInfo}
+     * Apply label and tag using a {@link SearchActionItemInfo}
      */
-    public void applyFromRemoteActionInfo(RemoteActionItemInfo remoteActionItemInfo) {
-        applyIconAndLabel(remoteActionItemInfo);
-        setTag(remoteActionItemInfo);
+    public void applyFromSearchActionItemInfo(SearchActionItemInfo searchActionItemInfo) {
+        applyIconAndLabel(searchActionItemInfo);
+        setTag(searchActionItemInfo);
     }
 
-    private void applyIconAndLabel(ItemInfoWithIcon info) {
+    protected void applyIconAndLabel(ItemInfoWithIcon info) {
         FastBitmapDrawable iconDrawable = newIcon(getContext(), info);
         mDotParams.color = IconPalette.getMutedColor(info.bitmap.color, 0.54f);
 
@@ -595,7 +595,8 @@
         mLongPressHelper.cancelLongPress();
     }
 
-    /** Applies the loading progress value to the progress bar.
+    /**
+     * Applies the loading progress value to the progress bar.
      *
      * If this app is installing, the progress bar will be updated with the installation progress.
      * If this app is installed and downloading incrementally, the progress bar will be updated
@@ -609,7 +610,7 @@
                     != 0) {
                 updateProgressBarUi(progressLevel, progressLevel == 100);
             } else if (info.hasPromiseIconUi() || (info.runtimeStatusFlags
-                        & ItemInfoWithIcon.FLAG_INSTALL_SESSION_ACTIVE) != 0) {
+                    & ItemInfoWithIcon.FLAG_INSTALL_SESSION_ACTIVE) != 0) {
                 updateProgressBarUi(progressLevel, promiseStateChanged);
             }
         }
@@ -765,8 +766,8 @@
                 mActivity.invalidateParent(info);
             } else if (info instanceof PackageItemInfo) {
                 applyFromItemInfoWithIcon((PackageItemInfo) info);
-            } else if (info instanceof RemoteActionItemInfo) {
-                applyFromRemoteActionInfo((RemoteActionItemInfo) info);
+            } else if (info instanceof SearchActionItemInfo) {
+                applyFromSearchActionItemInfo((SearchActionItemInfo) info);
             }
 
             mDisableRelayout = false;
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 4d51d70..20f7c23 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -547,10 +547,15 @@
             return mLauncher.startActivitySafely(v, headerItem.getIntent(), headerItem);
         }
         AdapterItem focusedItem = getActiveRecyclerView().getApps().getFocusedChild();
-        if (mSearchAdapterProvider.onAdapterItemSelected(focusedItem)) {
-            return true;
+        if (focusedItem != null) {
+            View focusedView = getActiveRecyclerView().getLayoutManager()
+                    .findViewByPosition(focusedItem.position);
+            if (focusedView != null && mSearchAdapterProvider.onAdapterItemSelected(focusedItem,
+                    focusedView)) {
+                return true;
+            }
         }
-        if (focusedItem.appInfo != null) {
+        if (focusedItem != null && focusedItem.appInfo != null) {
             ItemInfo itemInfo = focusedItem.appInfo;
             return mLauncher.startActivitySafely(v, itemInfo.getIntent(), itemInfo);
         }
diff --git a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
index 522f1d4..198c4b2 100644
--- a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
+++ b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
@@ -32,10 +32,8 @@
 import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItem;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.util.PackageManagerHelper;
-import com.android.systemui.plugins.AllAppsSearchPlugin;
 
 import java.util.ArrayList;
-import java.util.function.Consumer;
 
 /**
  * An interface to a search box that AllApps can command.
@@ -74,10 +72,7 @@
 
     @Override
     public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
-        if (mSearchAlgorithm instanceof PluginWrapper) {
-            ((PluginWrapper) mSearchAlgorithm).runOnPluginIfConnected(
-                    AllAppsSearchPlugin::startedSearchSession);
-        }
+        // Do nothing
     }
 
     @Override
@@ -174,16 +169,6 @@
     }
 
     /**
-     * A wrapper setup for running essential calls to plugin from search controller
-     */
-    public interface PluginWrapper {
-        /**
-         * executes call if plugin is connected
-         */
-        void runOnPluginIfConnected(Consumer<AllAppsSearchPlugin> plugin);
-    }
-
-    /**
      * Callback for getting search results.
      */
     public interface Callbacks {
diff --git a/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java b/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java
index e3c178b..330ec68 100644
--- a/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java
+++ b/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java
@@ -16,6 +16,7 @@
 package com.android.launcher3.allapps.search;
 
 import android.view.LayoutInflater;
+import android.view.View;
 import android.view.ViewGroup;
 
 import com.android.launcher3.BaseDraggingActivity;
@@ -47,7 +48,7 @@
     }
 
     @Override
-    public boolean onAdapterItemSelected(AllAppsGridAdapter.AdapterItem focusedItem) {
+    public boolean onAdapterItemSelected(AllAppsGridAdapter.AdapterItem adapterItem, View view) {
         return false;
     }
 }
diff --git a/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java b/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java
index 1c7247a..511de30 100644
--- a/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java
+++ b/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java
@@ -18,6 +18,7 @@
 
 
 import android.view.LayoutInflater;
+import android.view.View;
 import android.view.ViewGroup;
 
 import com.android.launcher3.BaseDraggingActivity;
@@ -61,5 +62,6 @@
      * handles selection event on search adapter item. Returns false if provider can not handle
      * event
      */
-    public abstract boolean onAdapterItemSelected(AllAppsGridAdapter.AdapterItem focusedItem);
+    public abstract boolean onAdapterItemSelected(AllAppsGridAdapter.AdapterItem adapterItem,
+            View view);
 }
diff --git a/src/com/android/launcher3/model/data/RemoteActionItemInfo.java b/src/com/android/launcher3/model/data/RemoteActionItemInfo.java
deleted file mode 100644
index d988bf9..0000000
--- a/src/com/android/launcher3/model/data/RemoteActionItemInfo.java
+++ /dev/null
@@ -1,68 +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.model.data;
-
-import android.app.RemoteAction;
-import android.os.Process;
-
-/**
- * Represents a launchable {@link RemoteAction}
- */
-public class RemoteActionItemInfo extends ItemInfoWithIcon {
-
-    private final RemoteAction mRemoteAction;
-    private final String mToken;
-    private final boolean mShouldStart;
-
-    public RemoteActionItemInfo(RemoteAction remoteAction, String token, boolean shouldStart) {
-        mShouldStart = shouldStart;
-        mToken = token;
-        mRemoteAction = remoteAction;
-        title = remoteAction.getTitle();
-        user = Process.myUserHandle();
-    }
-
-    public RemoteActionItemInfo(RemoteActionItemInfo info) {
-        super(info);
-        this.mShouldStart = info.mShouldStart;
-        this.mRemoteAction = info.mRemoteAction;
-        this.mToken = info.mToken;
-    }
-
-    @Override
-    public ItemInfoWithIcon clone() {
-        return new RemoteActionItemInfo(this);
-    }
-
-    public RemoteAction getRemoteAction() {
-        return mRemoteAction;
-    }
-
-    public String getToken() {
-        return mToken;
-    }
-
-    /**
-     * Getter method for mShouldStart
-     */
-    public boolean shouldStartInLauncher() {
-        return mShouldStart;
-    }
-
-    public boolean isEscapeHatch() {
-        return mToken.contains("item_type:[ESCAPE_HATCH]");
-    }
-}
diff --git a/src/com/android/launcher3/model/data/SearchActionItemInfo.java b/src/com/android/launcher3/model/data/SearchActionItemInfo.java
new file mode 100644
index 0000000..1831ffd
--- /dev/null
+++ b/src/com/android/launcher3/model/data/SearchActionItemInfo.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2021 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.model.data;
+
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.graphics.drawable.Icon;
+import android.os.Process;
+import android.os.UserHandle;
+
+/**
+ * Represents a SearchAction with in launcher
+ */
+public class SearchActionItemInfo extends ItemInfoWithIcon {
+
+    public static final int FLAG_SHOULD_START = 1 << 1;
+    public static final int FLAG_SHOULD_START_FOR_RESULT = FLAG_SHOULD_START | 1 << 2;
+
+    private final String mFallbackPackageName;
+
+    private int mFlags = 0;
+    private final Icon mIcon;
+
+    private Intent mIntent;
+
+    private PendingIntent mPendingIntent;
+
+    public SearchActionItemInfo(Icon icon, String packageName, UserHandle user,
+            CharSequence title) {
+        this.user = user == null ? Process.myUserHandle() : user;
+        this.title = title;
+        mFallbackPackageName = packageName;
+        mIcon = icon;
+    }
+
+    public SearchActionItemInfo(SearchActionItemInfo info) {
+        super(info);
+        mIcon = info.mIcon;
+        mFallbackPackageName = info.mFallbackPackageName;
+        mFlags = info.mFlags;
+        title = info.title;
+    }
+
+    public void setFlags(int flags) {
+        mFlags = flags;
+    }
+
+    public int getFlags() {
+        return mFlags;
+    }
+
+    @Override
+    public Intent getIntent() {
+        return mIntent;
+    }
+
+    /**
+     * Setter for mIntent with assertion for null value mPendingIntent
+     */
+    public void setIntent(Intent intent) {
+        if (mPendingIntent != null && intent != null) {
+            throw new RuntimeException(
+                    "SearchActionItemInfo can only have either an Intent or a PendingIntent");
+        }
+        mIntent = intent;
+    }
+
+    public PendingIntent getPendingIntent() {
+        return mPendingIntent;
+    }
+
+    /**
+     * Setter of mPendingIntent with assertion for null value mIntent
+     */
+    public void setPendingIntent(PendingIntent pendingIntent) {
+        if (mIntent != null && pendingIntent != null) {
+            throw new RuntimeException(
+                    "SearchActionItemInfo can only have either an Intent or a PendingIntent");
+        }
+        mPendingIntent = pendingIntent;
+    }
+
+
+    /**
+     * Returns if a flag is set on instance
+     */
+    public boolean hasFlag(int flag) {
+        return (mFlags & flag) == flag;
+    }
+
+    @Override
+    public ItemInfoWithIcon clone() {
+        return new SearchActionItemInfo(this);
+    }
+
+    public Icon getIcon() {
+        return mIcon;
+    }
+}
diff --git a/src/com/android/launcher3/touch/ItemClickHandler.java b/src/com/android/launcher3/touch/ItemClickHandler.java
index 4158735..d9483e5 100644
--- a/src/com/android/launcher3/touch/ItemClickHandler.java
+++ b/src/com/android/launcher3/touch/ItemClickHandler.java
@@ -51,7 +51,7 @@
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.ItemInfoWithIcon;
 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
-import com.android.launcher3.model.data.RemoteActionItemInfo;
+import com.android.launcher3.model.data.SearchActionItemInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.pm.InstallSessionHelper;
 import com.android.launcher3.testing.TestLogging;
@@ -96,8 +96,8 @@
             if (v instanceof PendingAppWidgetHostView) {
                 onClickPendingWidget((PendingAppWidgetHostView) v, launcher);
             }
-        } else if (tag instanceof RemoteActionItemInfo) {
-            onClickRemoteAction(launcher, (RemoteActionItemInfo) tag);
+        } else if (tag instanceof SearchActionItemInfo) {
+            onClickSearchAction(launcher, (SearchActionItemInfo) tag);
         }
     }
 
@@ -246,23 +246,31 @@
     }
 
     /**
-     * Event handler for a {@link android.app.RemoteAction} click
-     *
+     * Event handler for a {@link SearchActionItemInfo} click
      */
-    public static void onClickRemoteAction(Launcher launcher,
-            RemoteActionItemInfo remoteActionInfo) {
-        try {
-            PendingIntent pendingIntent = remoteActionInfo.getRemoteAction().getActionIntent();
-            if (remoteActionInfo.shouldStartInLauncher()) {
-                launcher.startIntentSenderForResult(pendingIntent.getIntentSender(), 0, null, 0, 0,
-                        0);
+    public static void onClickSearchAction(Launcher launcher, SearchActionItemInfo itemInfo) {
+        if (itemInfo.getIntent() != null) {
+            if (itemInfo.hasFlag(SearchActionItemInfo.FLAG_SHOULD_START_FOR_RESULT)) {
+                launcher.startActivityForResult(itemInfo.getIntent(), 0);
             } else {
-                pendingIntent.send();
+                launcher.startActivity(itemInfo.getIntent());
             }
-        } catch (PendingIntent.CanceledException | IntentSender.SendIntentException e) {
-            Toast.makeText(launcher,
-                    launcher.getResources().getText(R.string.shortcut_not_available),
-                    Toast.LENGTH_SHORT).show();
+        } else if (itemInfo.getPendingIntent() != null) {
+            try {
+                PendingIntent pendingIntent = itemInfo.getPendingIntent();
+                if (!itemInfo.hasFlag(SearchActionItemInfo.FLAG_SHOULD_START)) {
+                    pendingIntent.send();
+                } else if (itemInfo.hasFlag(SearchActionItemInfo.FLAG_SHOULD_START_FOR_RESULT)) {
+                    launcher.startIntentSenderForResult(pendingIntent.getIntentSender(), 0, null, 0,
+                            0, 0);
+                } else {
+                    launcher.startIntentSender(pendingIntent.getIntentSender(), null, 0, 0, 0);
+                }
+            } catch (PendingIntent.CanceledException | IntentSender.SendIntentException e) {
+                Toast.makeText(launcher,
+                        launcher.getResources().getText(R.string.shortcut_not_available),
+                        Toast.LENGTH_SHORT).show();
+            }
         }
     }
 
@@ -272,7 +280,7 @@
         Intent intent;
         if (item instanceof ItemInfoWithIcon
                 && (((ItemInfoWithIcon) item).runtimeStatusFlags
-                    & ItemInfoWithIcon.FLAG_INSTALL_SESSION_ACTIVE) != 0) {
+                & ItemInfoWithIcon.FLAG_INSTALL_SESSION_ACTIVE) != 0) {
             ItemInfoWithIcon appInfo = (ItemInfoWithIcon) item;
             intent = new PackageManagerHelper(launcher)
                     .getMarketIntent(appInfo.getTargetComponent().getPackageName());