Merge "Separate TaskView translationX into dismiss + offset translations"
diff --git a/Android.mk b/Android.mk
index 503f9ae..ed42039 100644
--- a/Android.mk
+++ b/Android.mk
@@ -33,7 +33,8 @@
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
     LauncherPluginLib \
-    launcher_log_protos_lite
+    launcher_log_protos_lite \
+    search_ui
 
 LOCAL_SRC_FILES := \
     $(call all-java-files-under, src_build_config) \
diff --git a/proguard.flags b/proguard.flags
index 37b8093..a450183 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -45,9 +45,10 @@
 
 # BUG(70852369): Surpress additional warnings after changing from Proguard to R8
 -dontwarn android.app.**
--dontwarn android.view.**
--dontwarn android.os.**
 -dontwarn android.graphics.**
+-dontwarn android.os.**
+-dontwarn android.view.**
+-dontwarn android.window.**
 
 # Ignore warnings for hidden utility classes referenced from the shared lib
 -dontwarn com.android.internal.util.**
diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml
index 4e7c3fa..8dab915 100644
--- a/quickstep/AndroidManifest.xml
+++ b/quickstep/AndroidManifest.xml
@@ -27,6 +27,7 @@
         android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
         android:protectionLevel="signatureOrSystem" />
 
+    <uses-permission android:name="android.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS" />
     <uses-permission android:name="android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS"/>
     <uses-permission android:name="android.permission.VIBRATE"/>
     <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
diff --git a/res/layout/search_result_icon.xml b/quickstep/res/layout/search_result_icon.xml
similarity index 88%
rename from res/layout/search_result_icon.xml
rename to quickstep/res/layout/search_result_icon.xml
index 3c1dd49..e1b6dfd 100644
--- a/res/layout/search_result_icon.xml
+++ b/quickstep/res/layout/search_result_icon.xml
@@ -13,7 +13,7 @@
      limitations under the License.
 -->
 
-<com.android.launcher3.views.SearchResultIcon xmlns:launcher="http://schemas.android.com/apk/res-auto"
+<com.android.launcher3.search.SearchResultIcon xmlns:launcher="http://schemas.android.com/apk/res-auto"
     style="@style/BaseIcon.AllApps"
     launcher:iconDisplay="all_apps"
     launcher:centerVertically="true" />
diff --git a/res/layout/search_result_icon_row.xml b/quickstep/res/layout/search_result_icon_row.xml
similarity index 93%
rename from res/layout/search_result_icon_row.xml
rename to quickstep/res/layout/search_result_icon_row.xml
index 81c23e4..1393b87 100644
--- a/res/layout/search_result_icon_row.xml
+++ b/quickstep/res/layout/search_result_icon_row.xml
@@ -12,14 +12,14 @@
      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.search.SearchResultIconRow xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:launcher="http://schemas.android.com/apk/res-auto"
     android:orientation="horizontal"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:padding="@dimen/dynamic_grid_edge_margin">
 
-    <com.android.launcher3.views.SearchResultIcon
+    <com.android.launcher3.search.SearchResultIcon
         android:layout_width="wrap_content"
         android:id="@+id/icon"
         launcher:iconDisplay="hero_app"
@@ -73,4 +73,4 @@
         launcher:iconSizeOverride="@dimen/deep_shortcut_icon_size"
         launcher:layoutHorizontal="false" />
 
-</com.android.launcher3.views.SearchResultIconRow>
\ No newline at end of file
+</com.android.launcher3.search.SearchResultIconRow>
\ No newline at end of file
diff --git a/res/layout/search_result_people_item.xml b/quickstep/res/layout/search_result_people_item.xml
similarity index 93%
rename from res/layout/search_result_people_item.xml
rename to quickstep/res/layout/search_result_people_item.xml
index 7526f6f..964300d 100644
--- a/res/layout/search_result_people_item.xml
+++ b/quickstep/res/layout/search_result_people_item.xml
@@ -12,7 +12,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.launcher3.views.SearchResultPeopleView xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.launcher3.search.SearchResultPeopleView xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:gravity="center_vertical"
     android:layout_height="wrap_content"
@@ -60,4 +60,4 @@
         android:layout_width="@dimen/deep_shortcut_icon_size"
         android:layout_height="@dimen/deep_shortcut_icon_size" />
 
-</com.android.launcher3.views.SearchResultPeopleView>
\ No newline at end of file
+</com.android.launcher3.search.SearchResultPeopleView>
\ No newline at end of file
diff --git a/res/layout/search_result_play_item.xml b/quickstep/res/layout/search_result_play_item.xml
similarity index 94%
rename from res/layout/search_result_play_item.xml
rename to quickstep/res/layout/search_result_play_item.xml
index d70c56a..ecd67b1 100644
--- a/res/layout/search_result_play_item.xml
+++ b/quickstep/res/layout/search_result_play_item.xml
@@ -13,7 +13,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.launcher3.views.SearchResultPlayItem xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.launcher3.search.SearchResultPlayItem xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:padding="4dp"
@@ -76,4 +76,4 @@
     </Button>
 
 
-</com.android.launcher3.views.SearchResultPlayItem>
+</com.android.launcher3.search.SearchResultPlayItem>
diff --git a/res/layout/search_result_settings_row.xml b/quickstep/res/layout/search_result_settings_row.xml
similarity index 93%
rename from res/layout/search_result_settings_row.xml
rename to quickstep/res/layout/search_result_settings_row.xml
index 22c08bf..33c9592 100644
--- a/res/layout/search_result_settings_row.xml
+++ b/quickstep/res/layout/search_result_settings_row.xml
@@ -12,7 +12,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.launcher3.views.SearchSettingsRowView xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.launcher3.search.SearchSettingsRowView xmlns:android="http://schemas.android.com/apk/res/android"
     style="@style/TextHeadline"
     android:id="@+id/section_title"
     android:background="?android:attr/selectableItemBackground"
@@ -57,4 +57,4 @@
             android:textColor="?android:attr/textColorSecondary"
             android:textSize="@dimen/search_hero_subtitle_size" />
     </LinearLayout>
-</com.android.launcher3.views.SearchSettingsRowView>
\ No newline at end of file
+</com.android.launcher3.search.SearchSettingsRowView>
\ No newline at end of file
diff --git a/res/layout/search_result_slice.xml b/quickstep/res/layout/search_result_slice.xml
similarity index 89%
rename from res/layout/search_result_slice.xml
rename to quickstep/res/layout/search_result_slice.xml
index 24d75e9..f7dcfce 100644
--- a/res/layout/search_result_slice.xml
+++ b/quickstep/res/layout/search_result_slice.xml
@@ -12,7 +12,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.launcher3.views.SearchResultSettingsSlice xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.launcher3.search.SearchResultSettingsSlice xmlns:android="http://schemas.android.com/apk/res/android"
     android:paddingHorizontal="@dimen/dynamic_grid_cell_padding_x"
     android:layout_width="match_parent"
     android:layout_height="wrap_content">
@@ -36,5 +36,5 @@
         android:layout_marginStart="@dimen/dynamic_grid_cell_padding_x"
         android:layout_width="0dp" />
 
-</com.android.launcher3.views.SearchResultSettingsSlice>
+</com.android.launcher3.search.SearchResultSettingsSlice>
 
diff --git a/res/layout/search_result_suggest.xml b/quickstep/res/layout/search_result_suggest.xml
similarity index 89%
rename from res/layout/search_result_suggest.xml
rename to quickstep/res/layout/search_result_suggest.xml
index 01e25d5..eb5313c 100644
--- a/res/layout/search_result_suggest.xml
+++ b/quickstep/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.SearchResultSuggestion xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.launcher3.search.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"
@@ -31,4 +31,4 @@
     launcher:layoutHorizontal="true"
     android:drawablePadding="@dimen/dynamic_grid_icon_drawable_padding">
 
-</com.android.launcher3.views.SearchResultSuggestion>
\ No newline at end of file
+</com.android.launcher3.search.SearchResultSuggestion>
\ No newline at end of file
diff --git a/res/layout/search_result_thumbnail.xml b/quickstep/res/layout/search_result_thumbnail.xml
similarity index 93%
rename from res/layout/search_result_thumbnail.xml
rename to quickstep/res/layout/search_result_thumbnail.xml
index 0cc5a29..0f25336 100644
--- a/res/layout/search_result_thumbnail.xml
+++ b/quickstep/res/layout/search_result_thumbnail.xml
@@ -13,7 +13,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.launcher3.views.ThumbnailSearchResultView
+<com.android.launcher3.search.ThumbnailSearchResultView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="125dp"
     android:layout_height="125dp"/>
\ No newline at end of file
diff --git a/res/layout/search_result_widget_live.xml b/quickstep/res/layout/search_result_widget_live.xml
similarity index 66%
rename from res/layout/search_result_widget_live.xml
rename to quickstep/res/layout/search_result_widget_live.xml
index 0dd8a06..ffbad55 100644
--- a/res/layout/search_result_widget_live.xml
+++ b/quickstep/res/layout/search_result_widget_live.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<com.android.launcher3.views.SearchResultWidget android:layout_height="wrap_content"
+<com.android.launcher3.search.SearchResultWidget android:layout_height="wrap_content"
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:gravity="center"
     android:layout_width="match_parent" />
\ No newline at end of file
diff --git a/res/layout/search_result_widget_preview.xml b/quickstep/res/layout/search_result_widget_preview.xml
similarity index 64%
rename from res/layout/search_result_widget_preview.xml
rename to quickstep/res/layout/search_result_widget_preview.xml
index 942b199..7af24a1 100644
--- a/res/layout/search_result_widget_preview.xml
+++ b/quickstep/res/layout/search_result_widget_preview.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
-<com.android.launcher3.views.SearchResultWidgetPreview xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.launcher3.search.SearchResultWidgetPreview xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:padding="@dimen/dynamic_grid_cell_padding_x"
     android:layout_height="wrap_content">
     <include layout="@layout/widget_cell" android:id="@+id/widget_cell"/>
 <!--    <include layout="@layout/widget_cell_content" />-->
-</com.android.launcher3.views.SearchResultWidgetPreview>
\ No newline at end of file
+</com.android.launcher3.search.SearchResultWidgetPreview>
\ No newline at end of file
diff --git a/res/layout/search_section_title.xml b/quickstep/res/layout/search_section_title.xml
similarity index 89%
rename from res/layout/search_section_title.xml
rename to quickstep/res/layout/search_section_title.xml
index b7ba83e..5842e57 100644
--- a/res/layout/search_section_title.xml
+++ b/quickstep/res/layout/search_section_title.xml
@@ -13,7 +13,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.launcher3.views.SearchSectionHeaderView xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.launcher3.search.SearchSectionHeaderView xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/section_title"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 727fbd3..551f7b0 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -45,7 +45,6 @@
 
     <!-- Launcher app transition -->
     <dimen name="content_trans_y">50dp</dimen>
-    <dimen name="workspace_trans_y">50dp</dimen>
     <dimen name="closing_window_trans_y">115dp</dimen>
 
     <dimen name="recents_empty_message_text_size">16sp</dimen>
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index 4204597..3643d6d 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -316,12 +316,4 @@
     public void setHintUserWillBeActive() {
         addActivityFlags(ACTIVITY_STATE_USER_WILL_BE_ACTIVE);
     }
-
-    @Override
-    public void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        if (Utilities.ATLEAST_R) {
-            InteractionJankMonitorWrapper.init(getWindow().getDecorView());
-        }
-    }
 }
diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
index cc3b7b6..2d9d092 100644
--- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
@@ -33,7 +33,6 @@
 import static com.android.launcher3.config.FeatureFlags.SEPARATE_RECENTS_ACTIVITY;
 import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_TRANSITIONS;
 import static com.android.launcher3.statehandlers.DepthController.DEPTH;
-import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
 import static com.android.quickstep.TaskUtils.taskIsATargetWithMode;
 import static com.android.systemui.shared.system.QuickStepContract.getWindowCornerRadius;
 import static com.android.systemui.shared.system.QuickStepContract.supportsRoundedCornersOnWindows;
@@ -57,6 +56,7 @@
 import android.os.CancellationSignal;
 import android.os.Handler;
 import android.os.Looper;
+import android.os.SystemProperties;
 import android.util.Pair;
 import android.view.View;
 
@@ -75,6 +75,7 @@
 import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
 import com.android.launcher3.views.FloatingIconView;
 import com.android.quickstep.RemoteAnimationTargets;
+import com.android.quickstep.SystemUiProxy;
 import com.android.quickstep.util.MultiValueUpdateListener;
 import com.android.quickstep.util.RemoteAnimationProvider;
 import com.android.quickstep.util.StaggeredWorkspaceAnim;
@@ -87,6 +88,7 @@
 import com.android.systemui.shared.system.RemoteAnimationDefinitionCompat;
 import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+import com.android.systemui.shared.system.RemoteTransitionCompat;
 import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
 import com.android.systemui.shared.system.WindowManagerWrapper;
 
@@ -100,6 +102,9 @@
 
     private static final String TAG = "QuickstepTransition";
 
+    private static final boolean ENABLE_SHELL_STARTING_SURFACE =
+            SystemProperties.getBoolean("persist.debug.shell_starting_surface", false);
+
     /** Duration of status bar animations. */
     public static final int STATUS_BAR_TRANSITION_DURATION = 120;
 
@@ -149,7 +154,6 @@
     private final boolean mIsRtl;
 
     private final float mContentTransY;
-    private final float mWorkspaceTransY;
     private final float mClosingWindowTransY;
     private final float mMaxShadowRadius;
 
@@ -161,6 +165,9 @@
     private WrappedAnimationRunnerImpl mAppLaunchRunner;
     private WrappedAnimationRunnerImpl mKeyguardGoingAwayRunner;
 
+    private WrappedAnimationRunnerImpl mWallpaperOpenTransitionRunner;
+    private RemoteTransitionCompat mLauncherOpenTransition;
+
     private final AnimatorListenerAdapter mForceInvisibleListener = new AnimatorListenerAdapter() {
         @Override
         public void onAnimationStart(Animator animation) {
@@ -183,7 +190,6 @@
 
         Resources res = mLauncher.getResources();
         mContentTransY = res.getDimensionPixelSize(R.dimen.content_trans_y);
-        mWorkspaceTransY = res.getDimensionPixelSize(R.dimen.workspace_trans_y);
         mClosingWindowTransY = res.getDimensionPixelSize(R.dimen.closing_window_trans_y);
         mMaxShadowRadius = res.getDimensionPixelSize(R.dimen.max_shadow_radius);
 
@@ -445,9 +451,9 @@
             RemoteAnimationTargetCompat[] appTargets,
             RemoteAnimationTargetCompat[] wallpaperTargets,
             Rect windowTargetBounds, boolean toggleVisibility) {
-        RectF bounds = new RectF();
+        RectF launcherIconBounds = new RectF();
         FloatingIconView floatingView = FloatingIconView.getFloatingIconView(mLauncher, v,
-                toggleVisibility, bounds, true /* isOpening */);
+                toggleVisibility, launcherIconBounds, true /* isOpening */);
         Rect crop = new Rect();
         Matrix matrix = new Matrix();
 
@@ -457,43 +463,21 @@
                 new SurfaceTransactionApplier(floatingView);
         openingTargets.addReleaseCheck(surfaceApplier);
 
-        // Scale the app icon to take up the entire screen. This simplifies the math when
-        // animating the app window position / scale.
-        float smallestSize = Math.min(windowTargetBounds.height(), windowTargetBounds.width());
-        float maxScaleX = smallestSize / bounds.width();
-        float maxScaleY = smallestSize / bounds.height();
-        float scale = Math.max(maxScaleX, maxScaleY);
-        float startScale = 1f;
-        if (v instanceof BubbleTextView && !(v.getParent() instanceof DeepShortcutView)) {
-            Drawable dr = ((BubbleTextView) v).getIcon();
-            if (dr instanceof FastBitmapDrawable) {
-                startScale = ((FastBitmapDrawable) dr).getAnimatedScale();
-            }
-        }
-        final float initialStartScale = startScale;
-
         int[] dragLayerBounds = new int[2];
         mDragLayer.getLocationOnScreen(dragLayerBounds);
 
-        // Animate the app icon to the center of the window bounds in screen coordinates.
-        float centerX = windowTargetBounds.centerX() - dragLayerBounds[0];
-        float centerY = windowTargetBounds.centerY() - dragLayerBounds[1];
-
-        float dX = centerX - bounds.centerX();
-        float dY = centerY - bounds.centerY();
-
-        boolean useUpwardAnimation = bounds.top > centerY
-                || Math.abs(dY) < mLauncher.getDeviceProfile().cellHeightPx;
-        final long xDuration = useUpwardAnimation ? APP_LAUNCH_CURVED_DURATION
-                : APP_LAUNCH_DOWN_DURATION;
-        final long yDuration = useUpwardAnimation ? APP_LAUNCH_DURATION
-                : APP_LAUNCH_DOWN_CURVED_DURATION;
-        final long alphaDuration = useUpwardAnimation ? APP_LAUNCH_ALPHA_DURATION
-                : APP_LAUNCH_ALPHA_DOWN_DURATION;
+        AnimOpenProperties prop = new AnimOpenProperties(mLauncher.getResources(), mDeviceProfile,
+                windowTargetBounds, launcherIconBounds, v, dragLayerBounds[0], dragLayerBounds[1]);
+        int left = (int) (prop.cropCenterXStart - prop.cropWidthStart / 2);
+        int top = (int) (prop.cropCenterYStart - prop.cropHeightStart / 2);
+        int right = (int) (left + prop.cropWidthStart);
+        int bottom = (int) (top + prop.cropHeightStart);
+        // Set the crop here so we can calculate the corner radius below.
+        crop.set(left, top, right, bottom);
 
         RectF targetBounds = new RectF(windowTargetBounds);
-        RectF iconBounds = new RectF();
-        RectF temp = new RectF();
+        RectF floatingIconBounds = new RectF();
+        RectF tmpRectF = new RectF();
         Point tmpPos = new Point();
 
         AnimatorSet animatorSet = new AnimatorSet();
@@ -511,83 +495,81 @@
             }
         });
 
-        float shapeRevealDuration = APP_LAUNCH_DURATION * SHAPE_PROGRESS_DURATION;
-
-        final float startCrop;
-        final float endCrop;
-        if (mDeviceProfile.isVerticalBarLayout()) {
-            startCrop = windowTargetBounds.height();
-            endCrop = windowTargetBounds.width();
-        } else {
-            startCrop = windowTargetBounds.width();
-            endCrop = windowTargetBounds.height();
-        }
-
         final float initialWindowRadius = supportsRoundedCornersOnWindows(mLauncher.getResources())
-                ? startCrop / 2f : 0f;
-        final float windowRadius = mDeviceProfile.isMultiWindowMode
+                ? Math.max(crop.width(), crop.height()) / 2f
+                : 0f;
+        final float finalWindowRadius = mDeviceProfile.isMultiWindowMode
                 ? 0 : getWindowCornerRadius(mLauncher.getResources());
+
         appAnimator.addUpdateListener(new MultiValueUpdateListener() {
-            FloatProp mDx = new FloatProp(0, dX, 0, xDuration, AGGRESSIVE_EASE);
-            FloatProp mDy = new FloatProp(0, dY, 0, yDuration, AGGRESSIVE_EASE);
-            FloatProp mScale = new FloatProp(initialStartScale, scale, 0, APP_LAUNCH_DURATION,
-                    EXAGGERATED_EASE);
-            FloatProp mIconAlpha = new FloatProp(1f, 0f, APP_LAUNCH_ALPHA_START_DELAY,
-                    alphaDuration, LINEAR);
-            FloatProp mCroppedSize = new FloatProp(startCrop, endCrop, 0, CROP_DURATION,
-                    EXAGGERATED_EASE);
-            FloatProp mWindowRadius = new FloatProp(initialWindowRadius, windowRadius, 0,
+            FloatProp mDx = new FloatProp(0, prop.dX, 0, prop.xDuration, AGGRESSIVE_EASE);
+            FloatProp mDy = new FloatProp(0, prop.dY, 0, prop.yDuration, AGGRESSIVE_EASE);
+
+            FloatProp mIconScaleToFitScreen = new FloatProp(prop.initialAppIconScale,
+                    prop.finalAppIconScale, 0, APP_LAUNCH_DURATION, EXAGGERATED_EASE);
+            FloatProp mIconAlpha = new FloatProp(prop.iconAlphaStart, 0f,
+                    APP_LAUNCH_ALPHA_START_DELAY, prop.alphaDuration, LINEAR);
+
+            FloatProp mWindowRadius = new FloatProp(initialWindowRadius, finalWindowRadius, 0,
                     RADIUS_DURATION, EXAGGERATED_EASE);
             FloatProp mShadowRadius = new FloatProp(0, mMaxShadowRadius, 0,
                     APP_LAUNCH_DURATION, EXAGGERATED_EASE);
 
+            FloatProp mCropRectCenterX = new FloatProp(prop.cropCenterXStart, prop.cropCenterXEnd,
+                    0, CROP_DURATION, EXAGGERATED_EASE);
+            FloatProp mCropRectCenterY = new FloatProp(prop.cropCenterYStart, prop.cropCenterYEnd,
+                    0, CROP_DURATION, EXAGGERATED_EASE);
+            FloatProp mCropRectWidth = new FloatProp(prop.cropWidthStart, prop.cropWidthEnd, 0,
+                    CROP_DURATION, EXAGGERATED_EASE);
+            FloatProp mCropRectHeight = new FloatProp(prop.cropHeightStart, prop.cropHeightEnd, 0,
+                    CROP_DURATION, EXAGGERATED_EASE);
+
             @Override
             public void onUpdate(float percent) {
-                // Calculate the size.
-                float width = bounds.width() * mScale.value;
-                float height = bounds.height() * mScale.value;
+                // Calculate the size of the scaled icon.
+                float iconWidth = launcherIconBounds.width() * mIconScaleToFitScreen.value;
+                float iconHeight = launcherIconBounds.height() * mIconScaleToFitScreen.value;
 
-                // Animate the crop so that it starts off as a square.
-                final int cropWidth;
-                final int cropHeight;
-                if (mDeviceProfile.isVerticalBarLayout()) {
-                    cropWidth = (int) mCroppedSize.value;
-                    cropHeight = windowTargetBounds.height();
-                } else {
-                    cropWidth = windowTargetBounds.width();
-                    cropHeight = (int) mCroppedSize.value;
-                }
-                crop.set(0, 0, cropWidth, cropHeight);
+                int left = (int) (mCropRectCenterX.value - mCropRectWidth.value / 2);
+                int top = (int) (mCropRectCenterY.value - mCropRectHeight.value / 2);
+                int right = (int) (left + mCropRectWidth.value);
+                int bottom = (int) (top + mCropRectHeight.value);
+                crop.set(left, top, right, bottom);
 
-                // Scale the size to match the crop.
-                float scaleX = width / cropWidth;
-                float scaleY = height / cropHeight;
+                final int windowCropWidth = crop.width();
+                final int windowCropHeight = crop.height();
+
+                // Scale the size of the icon to match the size of the window crop.
+                float scaleX = iconWidth / windowCropWidth;
+                float scaleY = iconHeight / windowCropHeight;
                 float scale = Math.min(1f, Math.max(scaleX, scaleY));
 
-                float scaledCropWidth = cropWidth * scale;
-                float scaledCropHeight = cropHeight * scale;
-                float offsetX  = (scaledCropWidth - width) / 2;
-                float offsetY = (scaledCropHeight - height) / 2;
+                float scaledCropWidth = windowCropWidth * scale;
+                float scaledCropHeight = windowCropHeight * scale;
+                float offsetX  = (scaledCropWidth - iconWidth) / 2;
+                float offsetY = (scaledCropHeight - iconHeight) / 2;
 
-                // Calculate the window position.
-                temp.set(bounds);
-                temp.offset(dragLayerBounds[0], dragLayerBounds[1]);
-                temp.offset(mDx.value, mDy.value);
-                Utilities.scaleRectFAboutCenter(temp, mScale.value);
-                float windowTransX0 = temp.left - offsetX;
-                float windowTransY0 = temp.top - offsetY;
+                // Calculate the window position to match the icon position.
+                tmpRectF.set(launcherIconBounds);
+                tmpRectF.offset(dragLayerBounds[0], dragLayerBounds[1]);
+                tmpRectF.offset(mDx.value, mDy.value);
+                Utilities.scaleRectFAboutCenter(tmpRectF, mIconScaleToFitScreen.value);
+                float windowTransX0 = tmpRectF.left - offsetX;
+                float windowTransY0 = tmpRectF.top - offsetY;
+                if (ENABLE_SHELL_STARTING_SURFACE) {
+                    windowTransX0 -= crop.left * scale;
+                    windowTransY0 -= crop.top * scale;
+                }
 
                 // Calculate the icon position.
-                iconBounds.set(bounds);
-                iconBounds.offset(mDx.value, mDy.value);
-                Utilities.scaleRectFAboutCenter(iconBounds, mScale.value);
-                iconBounds.left -= offsetX;
-                iconBounds.top -= offsetY;
-                iconBounds.right += offsetX;
-                iconBounds.bottom += offsetY;
+                floatingIconBounds.set(launcherIconBounds);
+                floatingIconBounds.offset(mDx.value, mDy.value);
+                Utilities.scaleRectFAboutCenter(floatingIconBounds, mIconScaleToFitScreen.value);
+                floatingIconBounds.left -= offsetX;
+                floatingIconBounds.top -= offsetY;
+                floatingIconBounds.right += offsetX;
+                floatingIconBounds.bottom += offsetY;
 
-                float croppedHeight = (windowTargetBounds.height() - crop.height()) * scale;
-                float croppedWidth = (windowTargetBounds.width() - crop.width()) * scale;
                 SurfaceParams[] params = new SurfaceParams[appTargets.length];
                 for (int i = appTargets.length - 1; i >= 0; i--) {
                     RemoteAnimationTargetCompat target = appTargets[i];
@@ -597,7 +579,7 @@
                         matrix.setScale(scale, scale);
                         matrix.postTranslate(windowTransX0, windowTransY0);
 
-                        floatingView.update(iconBounds, mIconAlpha.value, percent, 0f,
+                        floatingView.update(floatingIconBounds, mIconAlpha.value, percent, 0f,
                                 mWindowRadius.value * scale, true /* isOpening */);
                         builder.withMatrix(matrix)
                                 .withWindowCrop(crop)
@@ -605,10 +587,11 @@
                                 .withCornerRadius(mWindowRadius.value)
                                 .withShadowRadius(mShadowRadius.value);
                     } else {
-                        tmpPos.set(target.position.x, target.position.y);
                         if (target.localBounds != null) {
                             final Rect localBounds = target.localBounds;
                             tmpPos.set(target.localBounds.left, target.localBounds.top);
+                        } else {
+                            tmpPos.set(target.position.x, target.position.y);
                         }
 
                         matrix.setTranslate(tmpPos.x, tmpPos.y);
@@ -680,6 +663,24 @@
     }
 
     /**
+     * Registers remote animations used when closing apps to home screen.
+     */
+    @Override
+    public void registerRemoteTransitions() {
+        if (SEPARATE_RECENTS_ACTIVITY.get()) {
+            return;
+        }
+        if (hasControlRemoteAppTransitionPermission()) {
+            mWallpaperOpenTransitionRunner = createWallpaperOpenRunner(false /* fromUnlock */);
+            mLauncherOpenTransition = RemoteAnimationAdapterCompat.buildRemoteTransition(
+                    new WrappedLauncherAnimationRunner<>(mWallpaperOpenTransitionRunner,
+                            false /* startAtFrontOfQueue */));
+            mLauncherOpenTransition.addHomeOpenCheck();
+            SystemUiProxy.INSTANCE.getNoCreate().registerRemoteTransition(mLauncherOpenTransition);
+        }
+    }
+
+    /**
      * Unregisters all remote animations.
      */
     @Override
@@ -698,6 +699,20 @@
         }
     }
 
+    @Override
+    public void unregisterRemoteTransitions() {
+        if (SEPARATE_RECENTS_ACTIVITY.get()) {
+            return;
+        }
+        if (hasControlRemoteAppTransitionPermission()) {
+            if (mLauncherOpenTransition == null) return;
+            SystemUiProxy.INSTANCE.getNoCreate().unregisterRemoteTransition(
+                    mLauncherOpenTransition);
+            mLauncherOpenTransition = null;
+            mWallpaperOpenTransitionRunner = null;
+        }
+    }
+
     private boolean launcherIsATargetWithMode(RemoteAnimationTargetCompat[] targets, int mode) {
         return taskIsATargetWithMode(targets, mLauncher.getTaskId(), mode);
     }
@@ -765,9 +780,10 @@
                     RemoteAnimationTargetCompat target = appTargets[i];
                     SurfaceParams.Builder builder = new SurfaceParams.Builder(target.leash);
 
-                    tmpPos.set(target.position.x, target.position.y);
                     if (target.localBounds != null) {
                         tmpPos.set(target.localBounds.left, target.localBounds.top);
+                    } else {
+                        tmpPos.set(target.position.x, target.position.y);
                     }
 
                     if (target.mode == MODE_CLOSING) {
@@ -807,7 +823,7 @@
         anim.addListener(new AnimationSuccessListener() {
             @Override
             public void onAnimationStart(Animator animation) {
-                InteractionJankMonitorWrapper.begin(cuj);
+                InteractionJankMonitorWrapper.begin(mDragLayer, cuj);
                 super.onAnimationStart(animation);
             }
 
@@ -970,4 +986,93 @@
             result.setAnimation(anim, mLauncher);
         }
     }
+
+    /**
+     * Class that holds all the variables for the app open animation.
+     */
+    static class AnimOpenProperties {
+
+        public final int cropCenterXStart;
+        public final int cropCenterYStart;
+        public final int cropWidthStart;
+        public final int cropHeightStart;
+
+        public final int cropCenterXEnd;
+        public final int cropCenterYEnd;
+        public final int cropWidthEnd;
+        public final int cropHeightEnd;
+
+        public final float dX;
+        public final float dY;
+
+        public final long xDuration;
+        public final long yDuration;
+        public final long alphaDuration;
+
+        public final float initialAppIconScale;
+        public final float finalAppIconScale;
+
+        public final float iconAlphaStart;
+
+        AnimOpenProperties(Resources r, DeviceProfile dp, Rect windowTargetBounds,
+                RectF launcherIconBounds, View view, int dragLayerLeft, int dragLayerTop) {
+            // Scale the app icon to take up the entire screen. This simplifies the math when
+            // animating the app window position / scale.
+            float smallestSize = Math.min(windowTargetBounds.height(), windowTargetBounds.width());
+            float maxScaleX = smallestSize / launcherIconBounds.width();
+            float maxScaleY = smallestSize / launcherIconBounds.height();
+            float iconStartScale = 1f;
+            if (view instanceof BubbleTextView && !(view.getParent() instanceof DeepShortcutView)) {
+                Drawable dr = ((BubbleTextView) view).getIcon();
+                if (dr instanceof FastBitmapDrawable) {
+                    iconStartScale = ((FastBitmapDrawable) dr).getAnimatedScale();
+                }
+            }
+
+            initialAppIconScale = iconStartScale;
+            finalAppIconScale = Math.max(maxScaleX, maxScaleY);
+
+            // Animate the app icon to the center of the window bounds in screen coordinates.
+            float centerX = windowTargetBounds.centerX() - dragLayerLeft;
+            float centerY = windowTargetBounds.centerY() - dragLayerTop;
+
+            dX = centerX - launcherIconBounds.centerX();
+            dY = centerY - launcherIconBounds.centerY();
+
+            boolean useUpwardAnimation = launcherIconBounds.top > centerY
+                    || Math.abs(dY) < dp.cellHeightPx;
+            xDuration = useUpwardAnimation ? APP_LAUNCH_CURVED_DURATION
+                    : APP_LAUNCH_DOWN_DURATION;
+            yDuration = useUpwardAnimation ? APP_LAUNCH_DURATION
+                    : APP_LAUNCH_DOWN_CURVED_DURATION;
+            alphaDuration = useUpwardAnimation ? APP_LAUNCH_ALPHA_DURATION
+                    : APP_LAUNCH_ALPHA_DOWN_DURATION;
+
+            if (ENABLE_SHELL_STARTING_SURFACE) {
+                iconAlphaStart = 0;
+
+                // TOOD: Share value from shell when available.
+                final float windowIconSize = Utilities.pxFromSp(108, r.getDisplayMetrics());
+
+                cropCenterXStart = windowTargetBounds.centerX();
+                cropCenterYStart = windowTargetBounds.centerY();
+
+                cropWidthStart = (int) windowIconSize;
+                cropHeightStart = (int) windowIconSize;
+            } else {
+                iconAlphaStart = 1;
+
+                cropWidthStart = cropHeightStart =
+                        Math.min(windowTargetBounds.width(), windowTargetBounds.height());
+                cropCenterXStart = cropCenterYStart =
+                        Math.min(windowTargetBounds.centerX(), windowTargetBounds.centerY());
+            }
+
+            cropWidthEnd = windowTargetBounds.width();
+            cropHeightEnd = windowTargetBounds.height();
+
+            cropCenterXEnd = windowTargetBounds.centerX();
+            cropCenterYEnd = windowTargetBounds.centerY();
+        }
+    }
 }
diff --git a/quickstep/src/com/android/launcher3/search/DeviceSearchAdapterProvider.java b/quickstep/src/com/android/launcher3/search/DeviceSearchAdapterProvider.java
new file mode 100644
index 0000000..3343cf5
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/search/DeviceSearchAdapterProvider.java
@@ -0,0 +1,149 @@
+/*
+ * 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.search;
+
+import static com.android.launcher3.allapps.AllAppsGridAdapter.VIEW_TYPE_ICON;
+
+import android.app.search.SearchTarget;
+import android.util.SparseIntArray;
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+
+import com.android.app.search.LayoutType;
+import com.android.app.search.ResultType;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
+import com.android.launcher3.allapps.AllAppsContainerView;
+import com.android.launcher3.allapps.AllAppsGridAdapter;
+import com.android.launcher3.allapps.search.SearchAdapterProvider;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.systemui.plugins.shared.SearchTargetLegacy;
+
+/**
+ * Provides views for on-device search results
+ */
+public class DeviceSearchAdapterProvider extends SearchAdapterProvider {
+
+    public static final int VIEW_TYPE_SEARCH_CORPUS_TITLE = 1 << 5;
+    public static final int VIEW_TYPE_SEARCH_ROW_WITH_BUTTON = 1 << 7;
+    public static final int VIEW_TYPE_SEARCH_ROW = 1 << 8;
+    public static final int VIEW_TYPE_SEARCH_SLICE = 1 << 9;
+    public static final int VIEW_TYPE_SEARCH_ICON_ROW = 1 << 10;
+    public static final int VIEW_TYPE_SEARCH_PEOPLE = 1 << 11;
+    public static final int VIEW_TYPE_SEARCH_THUMBNAIL = 1 << 12;
+    public static final int VIEW_TYPE_SEARCH_SUGGEST = 1 << 13;
+    public static final int VIEW_TYPE_SEARCH_ICON = (1 << 14) | VIEW_TYPE_ICON;
+    public static final int VIEW_TYPE_SEARCH_WIDGET_LIVE = 1 << 15;
+    public static final int VIEW_TYPE_SEARCH_WIDGET_PREVIEW = 1 << 16;
+
+    private final AllAppsContainerView mAppsView;
+
+    private final SparseIntArray mViewTypeToLayoutMap = new SparseIntArray();
+
+    public DeviceSearchAdapterProvider(Launcher launcher, AllAppsContainerView appsView) {
+        super(launcher);
+        mAppsView = appsView;
+
+        mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_ICON, R.layout.search_result_icon);
+        mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_CORPUS_TITLE, R.layout.search_section_title);
+        mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_ROW_WITH_BUTTON,
+                R.layout.search_result_play_item);
+        mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_ROW, R.layout.search_result_settings_row);
+        mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_SLICE, R.layout.search_result_slice);
+        mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_ICON_ROW, R.layout.search_result_icon_row);
+        mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_PEOPLE, R.layout.search_result_people_item);
+        mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_THUMBNAIL, R.layout.search_result_thumbnail);
+        mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_SUGGEST, R.layout.search_result_suggest);
+        mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_WIDGET_LIVE, R.layout.search_result_widget_live);
+        mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_WIDGET_PREVIEW,
+                R.layout.search_result_widget_preview);
+    }
+
+    @Override
+    public void onBindView(AllAppsGridAdapter.ViewHolder holder, int position) {
+        SearchAdapterItem item = (SearchAdapterItem) mAppsView.getApps().getAdapterItems().get(
+                position);
+        SearchTargetHandler
+                payloadResultView =
+                (SearchTargetHandler) holder.itemView;
+        if (!FeatureFlags.USE_SEARCH_API.get()) {
+            payloadResultView.applySearchTarget(item.getSearchTargetLegacy());
+        } else {
+            payloadResultView.applySearchTarget(item.getSearchTarget(), item.getInlineItems());
+        }
+    }
+
+    @Override
+    public boolean isSearchView(int viewType) {
+        return mViewTypeToLayoutMap.get(viewType, -1) != -1;
+    }
+
+    @Override
+    public AllAppsGridAdapter.ViewHolder onCreateViewHolder(LayoutInflater inflater,
+            ViewGroup parent, int viewType) {
+        return new AllAppsGridAdapter.ViewHolder(inflater.inflate(
+                mViewTypeToLayoutMap.get(viewType), parent, false));
+    }
+
+    @Override
+    public int getGridSpanSize(int viewType, int appsPerRow) {
+        if (viewType == VIEW_TYPE_SEARCH_THUMBNAIL
+                || viewType == VIEW_TYPE_SEARCH_WIDGET_PREVIEW) {
+            return appsPerRow;
+        }
+        return super.getGridSpanSize(viewType, appsPerRow);
+    }
+
+
+    @Override
+    public boolean onAdapterItemSelected(AllAppsGridAdapter.AdapterItem focusedItem) {
+        if (focusedItem instanceof SearchTargetHandler) {
+            SearchTargetLegacy searchTarget = ((SearchAdapterItem) focusedItem)
+                    .getSearchTargetLegacy();
+            SearchEventTracker.INSTANCE.get(mLauncher).quickSelect(searchTarget);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determines what view type should be used to present search target.
+     * Returns -1 if viewType is not found
+     */
+    public int getViewTypeForSearchTarget(SearchTarget t) {
+        if (t.getLayoutType().equals(LayoutType.TEXT_HEADER)) {
+            return VIEW_TYPE_SEARCH_CORPUS_TITLE;
+        }
+        switch (t.getResultType()) {
+            case ResultType.APPLICATION:
+                if (t.getLayoutType().equals(LayoutType.ICON_SINGLE_VERTICAL_TEXT)) {
+                    return VIEW_TYPE_SEARCH_ICON;
+                }
+                break;
+            case ResultType.SETTING:
+                if (t.getLayoutType().equals(LayoutType.ICON_SLICE)) {
+                    return VIEW_TYPE_SEARCH_SLICE;
+                }
+                return VIEW_TYPE_SEARCH_ROW;
+            case ResultType.SHORTCUT:
+                return VIEW_TYPE_SEARCH_ICON_ROW;
+            case ResultType.PLAY:
+                return VIEW_TYPE_SEARCH_ROW_WITH_BUTTON;
+        }
+        return -1;
+    }
+}
diff --git a/quickstep/src/com/android/launcher3/search/SearchAdapterItem.java b/quickstep/src/com/android/launcher3/search/SearchAdapterItem.java
new file mode 100644
index 0000000..65ac3f9
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/search/SearchAdapterItem.java
@@ -0,0 +1,79 @@
+/*
+ * 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.search;
+
+import static com.android.launcher3.search.DeviceSearchAdapterProvider.VIEW_TYPE_SEARCH_ICON;
+import static com.android.launcher3.search.DeviceSearchAdapterProvider.VIEW_TYPE_SEARCH_ICON_ROW;
+import static com.android.launcher3.search.DeviceSearchAdapterProvider.VIEW_TYPE_SEARCH_PEOPLE;
+import static com.android.launcher3.search.DeviceSearchAdapterProvider.VIEW_TYPE_SEARCH_ROW;
+import static com.android.launcher3.search.DeviceSearchAdapterProvider.VIEW_TYPE_SEARCH_ROW_WITH_BUTTON;
+import static com.android.launcher3.search.DeviceSearchAdapterProvider.VIEW_TYPE_SEARCH_SLICE;
+import static com.android.launcher3.search.DeviceSearchAdapterProvider.VIEW_TYPE_SEARCH_SUGGEST;
+import static com.android.launcher3.search.DeviceSearchAdapterProvider.VIEW_TYPE_SEARCH_THUMBNAIL;
+import static com.android.launcher3.search.DeviceSearchAdapterProvider.VIEW_TYPE_SEARCH_WIDGET_LIVE;
+import static com.android.launcher3.search.DeviceSearchAdapterProvider.VIEW_TYPE_SEARCH_WIDGET_PREVIEW;
+
+import android.app.search.SearchTarget;
+
+import com.android.launcher3.allapps.AllAppsGridAdapter;
+import com.android.systemui.plugins.shared.SearchTargetLegacy;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Extension of AdapterItem that contains an extra payload specific to item
+ */
+public class SearchAdapterItem extends AllAppsGridAdapter.AdapterItem {
+    private SearchTargetLegacy mSearchTargetLegacy;
+    private SearchTarget mSearchTarget;
+    private List<SearchTarget> mInlineItems = new ArrayList<>();
+
+
+    private static final int AVAILABLE_FOR_ACCESSIBILITY = VIEW_TYPE_SEARCH_ROW_WITH_BUTTON
+            | VIEW_TYPE_SEARCH_SLICE | VIEW_TYPE_SEARCH_ROW | VIEW_TYPE_SEARCH_PEOPLE
+            | VIEW_TYPE_SEARCH_THUMBNAIL | VIEW_TYPE_SEARCH_ICON_ROW | VIEW_TYPE_SEARCH_ICON
+            | VIEW_TYPE_SEARCH_WIDGET_PREVIEW | VIEW_TYPE_SEARCH_WIDGET_LIVE
+            | VIEW_TYPE_SEARCH_SUGGEST;
+
+    public SearchAdapterItem(SearchTargetLegacy searchTargetLegacy, int type) {
+        mSearchTargetLegacy = searchTargetLegacy;
+        viewType = type;
+    }
+
+
+    public SearchAdapterItem(SearchTarget searchTarget, int type) {
+        mSearchTarget = searchTarget;
+        viewType = type;
+    }
+
+    public SearchTargetLegacy getSearchTargetLegacy() {
+        return mSearchTargetLegacy;
+    }
+
+    public SearchTarget getSearchTarget() {
+        return mSearchTarget;
+    }
+
+    public List<SearchTarget> getInlineItems() {
+        return mInlineItems;
+    }
+    @Override
+    protected boolean isCountedForAccessibility() {
+        return (AVAILABLE_FOR_ACCESSIBILITY & viewType) == viewType;
+    }
+}
diff --git a/src/com/android/launcher3/allapps/search/SearchEventTracker.java b/quickstep/src/com/android/launcher3/search/SearchEventTracker.java
similarity index 80%
rename from src/com/android/launcher3/allapps/search/SearchEventTracker.java
rename to quickstep/src/com/android/launcher3/search/SearchEventTracker.java
index c276434..90fe661 100644
--- a/src/com/android/launcher3/allapps/search/SearchEventTracker.java
+++ b/quickstep/src/com/android/launcher3/search/SearchEventTracker.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.launcher3.allapps.search;
+package com.android.launcher3.search;
 
 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
 
@@ -21,11 +21,10 @@
 
 import androidx.annotation.Nullable;
 
-import com.android.launcher3.allapps.search.AllAppsSearchBarController.SearchTargetHandler;
 import com.android.launcher3.util.MainThreadInitializedObject;
 import com.android.systemui.plugins.AllAppsSearchPlugin;
-import com.android.systemui.plugins.shared.SearchTarget;
-import com.android.systemui.plugins.shared.SearchTargetEvent;
+import com.android.systemui.plugins.shared.SearchTargetEventLegacy;
+import com.android.systemui.plugins.shared.SearchTargetLegacy;
 
 import java.util.WeakHashMap;
 
@@ -35,7 +34,7 @@
 public class SearchEventTracker {
     @Nullable
     private AllAppsSearchPlugin mPlugin;
-    private final WeakHashMap<SearchTarget, SearchTargetHandler>
+    private final WeakHashMap<SearchTargetLegacy, SearchTargetHandler>
             mCallbacks = new WeakHashMap<>();
 
     public static final MainThreadInitializedObject<SearchEventTracker> INSTANCE =
@@ -61,26 +60,27 @@
     /**
      * Sends SearchTargetEvent to search provider
      */
-    public void notifySearchTargetEvent(SearchTargetEvent searchTargetEvent) {
+    public void notifySearchTargetEvent(SearchTargetEventLegacy searchTargetEvent) {
         if (mPlugin != null) {
-            UI_HELPER_EXECUTOR.post(() -> mPlugin.notifySearchTargetEvent(searchTargetEvent));
+            UI_HELPER_EXECUTOR.post(() -> mPlugin.notifySearchTargetEventLegacy(searchTargetEvent));
         }
     }
 
     /**
      * Registers a {@link SearchTargetHandler} to handle quick launch for specified SearchTarget.
      */
-    public void registerWeakHandler(SearchTarget searchTarget, SearchTargetHandler targetHandler) {
+    public void registerWeakHandler(SearchTargetLegacy searchTarget,
+            SearchTargetHandler targetHandler) {
         mCallbacks.put(searchTarget, targetHandler);
     }
 
     /**
      * Handles quick select for SearchTarget
      */
-    public void quickSelect(SearchTarget searchTarget) {
+    public void quickSelect(SearchTargetLegacy searchTarget) {
         SearchTargetHandler searchTargetHandler = mCallbacks.get(searchTarget);
         if (searchTargetHandler != null) {
-            searchTargetHandler.handleSelection(SearchTargetEvent.QUICK_SELECT);
+            searchTargetHandler.handleSelection(SearchTargetEventLegacy.QUICK_SELECT);
         }
     }
 
diff --git a/src/com/android/launcher3/views/SearchResultIcon.java b/quickstep/src/com/android/launcher3/search/SearchResultIcon.java
similarity index 80%
rename from src/com/android/launcher3/views/SearchResultIcon.java
rename to quickstep/src/com/android/launcher3/search/SearchResultIcon.java
index 9bcfb8c..d5fe0e8 100644
--- a/src/com/android/launcher3/views/SearchResultIcon.java
+++ b/quickstep/src/com/android/launcher3/search/SearchResultIcon.java
@@ -13,13 +13,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.launcher3.views;
+package com.android.launcher3.search;
 
 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.app.search.SearchTarget;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.ShortcutInfo;
@@ -30,12 +31,12 @@
 import android.view.View;
 import android.view.ViewGroup;
 
+import com.android.app.search.ResultType;
 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.config.FeatureFlags;
 import com.android.launcher3.icons.BitmapInfo;
 import com.android.launcher3.icons.LauncherIcons;
 import com.android.launcher3.model.data.AppInfo;
@@ -44,16 +45,17 @@
 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;
-import com.android.systemui.plugins.shared.SearchTargetEvent;
+import com.android.systemui.plugins.shared.SearchTargetEventLegacy;
+import com.android.systemui.plugins.shared.SearchTargetLegacy;
 
+import java.util.List;
 import java.util.function.Consumer;
 
 /**
  * A {@link BubbleTextView} representing a single cell result in AllApps
  */
 public class SearchResultIcon extends BubbleTextView implements
-        AllAppsSearchBarController.SearchTargetHandler, View.OnClickListener,
+        SearchTargetHandler, View.OnClickListener,
         View.OnLongClickListener {
 
 
@@ -71,7 +73,7 @@
 
     private final Launcher mLauncher;
 
-    private SearchTarget mSearchTarget;
+    private SearchTargetLegacy mSearchTarget;
     private Consumer<ItemInfoWithIcon> mOnItemInfoChanged;
 
     public SearchResultIcon(Context context) {
@@ -102,13 +104,13 @@
      * Applies search target with a ItemInfoWithIcon consumer to be called after itemInfo is
      * constructed
      */
-    public void applySearchTarget(SearchTarget searchTarget, Consumer<ItemInfoWithIcon> cb) {
+    public void applySearchTarget(SearchTargetLegacy searchTarget, Consumer<ItemInfoWithIcon> cb) {
         mOnItemInfoChanged = cb;
         applySearchTarget(searchTarget);
     }
 
     @Override
-    public void applySearchTarget(SearchTarget searchTarget) {
+    public void applySearchTarget(SearchTargetLegacy searchTarget) {
         mSearchTarget = searchTarget;
         SearchEventTracker.getInstance(getContext()).registerWeakHandler(mSearchTarget, this);
         setVisibility(VISIBLE);
@@ -129,9 +131,33 @@
         }
     }
 
+    /**
+     * Applies {@link SearchTarget} to view. registers a consumer after a corresponding
+     * {@link ItemInfoWithIcon} is created
+     */
+    public void applySearchTarget(SearchTarget searchTarget, List<SearchTarget> inlineItems,
+            Consumer<ItemInfoWithIcon> cb) {
+        mOnItemInfoChanged = cb;
+        applySearchTarget(searchTarget, inlineItems);
+    }
+
+    @Override
+    public void applySearchTarget(SearchTarget parentTarget, List<SearchTarget> children) {
+        switch (parentTarget.getResultType()) {
+            case ResultType.APPLICATION:
+                prepareUsingApp(new ComponentName(parentTarget.getPackageName(),
+                        parentTarget.getExtras().getString("class")), parentTarget.getUserHandle());
+                break;
+            case ResultType.SHORTCUT:
+                prepareUsingShortcutInfo(parentTarget.getShortcutInfo());
+                break;
+        }
+    }
+
     private void prepareUsingApp(ComponentName componentName, UserHandle userHandle) {
         AllAppsStore appsStore = mLauncher.getAppsView().getAppsStore();
         AppInfo appInfo = appsStore.getApp(new ComponentKey(componentName, userHandle));
+
         if (appInfo == null) {
             setVisibility(GONE);
             return;
@@ -179,11 +205,14 @@
     @Override
     public void handleSelection(int eventType) {
         mLauncher.getItemOnClickListener().onClick(this);
-        reportEvent(eventType);
+        if (!FeatureFlags.USE_SEARCH_API.get()) {
+            reportEvent(eventType);
+        }
     }
 
     private void reportEvent(int eventType) {
-        SearchTargetEvent.Builder b = new SearchTargetEvent.Builder(mSearchTarget, eventType);
+        SearchTargetEventLegacy.Builder b = new SearchTargetEventLegacy.Builder(mSearchTarget,
+                eventType);
         if (mSearchTarget.getItemType().equals(TARGET_TYPE_SHORTCUT)) {
             b.setShortcutPosition(0);
         }
@@ -193,7 +222,7 @@
 
     @Override
     public void onClick(View view) {
-        handleSelection(SearchTargetEvent.SELECT);
+        handleSelection(SearchTargetEventLegacy.SELECT);
     }
 
     @Override
@@ -201,7 +230,7 @@
         if (!supportsLongPress(mSearchTarget.getItemType())) {
             return false;
         }
-        reportEvent(SearchTargetEvent.LONG_PRESS);
+        reportEvent(SearchTargetEventLegacy.LONG_PRESS);
         return ItemLongClickListener.INSTANCE_ALL_APPS.onLongClick(view);
 
     }
diff --git a/src/com/android/launcher3/views/SearchResultIconRow.java b/quickstep/src/com/android/launcher3/search/SearchResultIconRow.java
similarity index 86%
rename from src/com/android/launcher3/views/SearchResultIconRow.java
rename to quickstep/src/com/android/launcher3/search/SearchResultIconRow.java
index e3c7661..80d543a 100644
--- a/src/com/android/launcher3/views/SearchResultIconRow.java
+++ b/quickstep/src/com/android/launcher3/search/SearchResultIconRow.java
@@ -13,11 +13,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.launcher3.views;
+package com.android.launcher3.search;
 
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
 
+import android.app.search.SearchTarget;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.ShortcutInfo;
@@ -32,17 +33,16 @@
 
 import androidx.annotation.Nullable;
 
+import com.android.app.search.ResultType;
 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.model.data.ItemInfoWithIcon;
 import com.android.launcher3.model.data.PackageItemInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.systemui.plugins.shared.SearchTarget;
-import com.android.systemui.plugins.shared.SearchTargetEvent;
+import com.android.systemui.plugins.shared.SearchTargetEventLegacy;
+import com.android.systemui.plugins.shared.SearchTargetLegacy;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -53,7 +53,7 @@
  * shortcuts
  */
 public class SearchResultIconRow extends LinearLayout implements
-        AllAppsSearchBarController.SearchTargetHandler, View.OnClickListener,
+        SearchTargetHandler, View.OnClickListener,
         View.OnLongClickListener, Consumer<ItemInfoWithIcon> {
     public static final int MAX_SHORTCUTS_COUNT = 2;
 
@@ -65,7 +65,7 @@
     private TextView mDescriptionView;
     private BubbleTextView[] mShortcutViews = new BubbleTextView[2];
 
-    private SearchTarget mSearchTarget;
+    private SearchTargetLegacy mSearchTarget;
     private PackageItemInfo mProviderInfo;
 
 
@@ -102,8 +102,9 @@
             lp.width = iconSize;
             bubbleTextView.setOnClickListener(view -> {
                 WorkspaceItemInfo itemInfo = (WorkspaceItemInfo) bubbleTextView.getTag();
-                SearchTargetEvent event = new SearchTargetEvent.Builder(mSearchTarget,
-                        SearchTargetEvent.CHILD_SELECT).setShortcutPosition(itemInfo.rank).build();
+                SearchTargetEventLegacy event = new SearchTargetEventLegacy.Builder(mSearchTarget,
+                        SearchTargetEventLegacy.CHILD_SELECT).setShortcutPosition(
+                        itemInfo.rank).build();
                 SearchEventTracker.getInstance(getContext()).notifySearchTargetEvent(event);
                 mLauncher.getItemOnClickListener().onClick(view);
             });
@@ -113,7 +114,17 @@
     }
 
     @Override
-    public void applySearchTarget(SearchTarget searchTarget) {
+    public void applySearchTarget(SearchTarget parentTarget, List<SearchTarget> children) {
+        mResultIcon.applySearchTarget(parentTarget, children, this);
+        if (parentTarget.getResultType() == ResultType.SHORTCUT) {
+            ShortcutInfo shortcutInfo = parentTarget.getShortcutInfo();
+            setProviderDetails(new ComponentName(shortcutInfo.getPackage(), ""),
+                    shortcutInfo.getUserHandle());
+        }
+    }
+
+    @Override
+    public void applySearchTarget(SearchTargetLegacy searchTarget) {
         mSearchTarget = searchTarget;
         mResultIcon.applySearchTarget(searchTarget, this);
         String itemType = searchTarget.getItemType();
diff --git a/src/com/android/launcher3/views/SearchResultPeopleView.java b/quickstep/src/com/android/launcher3/search/SearchResultPeopleView.java
similarity index 91%
rename from src/com/android/launcher3/views/SearchResultPeopleView.java
rename to quickstep/src/com/android/launcher3/search/SearchResultPeopleView.java
index e499bd5..8caa51c 100644
--- a/src/com/android/launcher3/views/SearchResultPeopleView.java
+++ b/quickstep/src/com/android/launcher3/search/SearchResultPeopleView.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.launcher3.views;
+package com.android.launcher3.search;
 
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
@@ -42,12 +42,10 @@
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
 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.systemui.plugins.shared.SearchTarget;
-import com.android.systemui.plugins.shared.SearchTargetEvent;
+import com.android.systemui.plugins.shared.SearchTargetEventLegacy;
+import com.android.systemui.plugins.shared.SearchTargetLegacy;
 
 import java.util.ArrayList;
 
@@ -55,7 +53,7 @@
  * A view representing a single people search result in all apps
  */
 public class SearchResultPeopleView extends LinearLayout implements
-        AllAppsSearchBarController.SearchTargetHandler {
+        SearchTargetHandler {
 
     public static final String TARGET_TYPE_PEOPLE = "people";
 
@@ -68,7 +66,7 @@
     private Intent mIntent;
 
 
-    private SearchTarget mSearchTarget;
+    private SearchTargetLegacy mSearchTarget;
 
     public SearchResultPeopleView(Context context) {
         this(context, null, 0);
@@ -101,11 +99,11 @@
             button.getLayoutParams().width = mButtonSize;
             button.getLayoutParams().height = mButtonSize;
         }
-        setOnClickListener(v -> handleSelection(SearchTargetEvent.SELECT));
+        setOnClickListener(v -> handleSelection(SearchTargetEventLegacy.SELECT));
     }
 
     @Override
-    public void applySearchTarget(SearchTarget searchTarget) {
+    public void applySearchTarget(SearchTargetLegacy searchTarget) {
         mSearchTarget = searchTarget;
         Bundle payload = searchTarget.getExtras();
         mTitleView.setText(payload.getString("title"));
@@ -188,8 +186,8 @@
             Bundle bundle = new Bundle();
             bundle.putBundle("provider", provider);
             SearchEventTracker.INSTANCE.get(getContext()).notifySearchTargetEvent(
-                    new SearchTargetEvent.Builder(mSearchTarget,
-                            SearchTargetEvent.CHILD_SELECT).setExtras(bundle).build());
+                    new SearchTargetEventLegacy.Builder(mSearchTarget,
+                            SearchTargetEventLegacy.CHILD_SELECT).setExtras(bundle).build());
         });
     }
 
@@ -199,7 +197,7 @@
             Launcher launcher = Launcher.getLauncher(getContext());
             launcher.startActivitySafely(this, mIntent, null);
             SearchEventTracker.INSTANCE.get(getContext()).notifySearchTargetEvent(
-                    new SearchTargetEvent.Builder(mSearchTarget, eventType).build());
+                    new SearchTargetEventLegacy.Builder(mSearchTarget, eventType).build());
         }
     }
 }
diff --git a/src/com/android/launcher3/views/SearchResultPlayItem.java b/quickstep/src/com/android/launcher3/search/SearchResultPlayItem.java
similarity index 65%
rename from src/com/android/launcher3/views/SearchResultPlayItem.java
rename to quickstep/src/com/android/launcher3/search/SearchResultPlayItem.java
index 86ed436..840bde9 100644
--- a/src/com/android/launcher3/views/SearchResultPlayItem.java
+++ b/quickstep/src/com/android/launcher3/search/SearchResultPlayItem.java
@@ -13,10 +13,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.launcher3.views;
+package com.android.launcher3.search;
 
 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
 
+import android.app.search.SearchAction;
+import android.app.search.SearchTarget;
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Bitmap;
@@ -27,8 +29,6 @@
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.drawable.BitmapDrawable;
-import android.net.Uri;
-import android.os.Bundle;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewGroup;
@@ -41,22 +41,19 @@
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.R;
-import com.android.launcher3.allapps.search.AllAppsSearchBarController;
-import com.android.launcher3.allapps.search.SearchEventTracker;
 import com.android.launcher3.icons.BitmapRenderer;
 import com.android.launcher3.util.Themes;
-import com.android.systemui.plugins.shared.SearchTarget;
-import com.android.systemui.plugins.shared.SearchTargetEvent;
 
 import java.io.IOException;
 import java.net.URL;
 import java.net.URLConnection;
+import java.util.List;
 
 /**
  * A View representing a PlayStore item.
  */
 public class SearchResultPlayItem extends LinearLayout implements
-        AllAppsSearchBarController.SearchTargetHandler {
+        SearchTargetHandler {
 
     public static final String TARGET_TYPE_PLAY = "play";
 
@@ -69,9 +66,8 @@
     private TextView[] mDetailViews = new TextView[3];
     private Button mPreviewButton;
     private String mPackageName;
-    private boolean mIsInstantGame;
-
-    private SearchTarget mSearchTarget;
+    private Intent mIntent;
+    private Intent mSecondaryIntent;
 
 
     public SearchResultPlayItem(Context context) {
@@ -95,7 +91,7 @@
         mIconView = findViewById(R.id.icon);
         mTitleView = findViewById(R.id.title_view);
         mPreviewButton = findViewById(R.id.try_button);
-        mPreviewButton.setOnClickListener(view -> launchInstantGame());
+        mPreviewButton.setOnClickListener(view -> launchIntent(mSecondaryIntent));
         mDetailViews[0] = findViewById(R.id.detail_0);
         mDetailViews[1] = findViewById(R.id.detail_1);
         mDetailViews[2] = findViewById(R.id.detail_2);
@@ -103,9 +99,59 @@
         ViewGroup.LayoutParams iconParams = mIconView.getLayoutParams();
         iconParams.height = mDeviceProfile.allAppsIconSizePx;
         iconParams.width = mDeviceProfile.allAppsIconSizePx;
-        setOnClickListener(view -> handleSelection(SearchTargetEvent.SELECT));
+        setOnClickListener(view -> launchIntent(mIntent));
     }
 
+    private void showIfNecessary(TextView textView, @Nullable String string) {
+        if (string == null || string.isEmpty()) {
+            textView.setVisibility(GONE);
+        } else {
+            textView.setText(string);
+            textView.setVisibility(VISIBLE);
+        }
+    }
+
+    private void launchIntent(Intent intent) {
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        getContext().startActivity(intent);
+    }
+
+    @Override
+    public void applySearchTarget(SearchTarget parentTarget, List<SearchTarget> children) {
+        if (parentTarget.getPackageName().equals(mPackageName)) {
+            return;
+        }
+        mPackageName = parentTarget.getPackageName();
+        SearchAction action = parentTarget.getSearchAction();
+        mTitleView.setText(action.getTitle());
+        showIfNecessary(mDetailViews[0], action.getSubtitle().toString());
+        mIntent = action.getIntent();
+
+        mIconView.setBackgroundResource(R.drawable.ic_deepshortcut_placeholder);
+        loadIcon(action.getIcon().getUri().toString());
+
+        mSecondaryIntent = children.size() == 1 ? children.get(0).getSearchAction().getIntent()
+                : null;
+        mPreviewButton.setVisibility(mSecondaryIntent == null ? GONE : VISIBLE);
+    }
+
+    private void loadIcon(String iconUrl) {
+        UI_HELPER_EXECUTOR.execute(() -> {
+            try {
+                URL url = new URL(iconUrl);
+                URLConnection con = url.openConnection();
+                con.addRequestProperty("Cache-Control", "max-age: 0");
+                con.setUseCaches(true);
+                Bitmap bitmap = BitmapFactory.decodeStream(con.getInputStream());
+                BitmapDrawable bitmapDrawable = new BitmapDrawable(getResources(), getRoundedBitmap(
+                        Bitmap.createScaledBitmap(bitmap, mDeviceProfile.allAppsIconSizePx,
+                                mDeviceProfile.allAppsIconSizePx, false)));
+                mIconView.post(() -> mIconView.setBackground(bitmapDrawable));
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        });
+    }
 
     private Bitmap getRoundedBitmap(Bitmap bitmap) {
         final int iconSize = bitmap.getWidth();
@@ -126,80 +172,4 @@
         });
         return output;
     }
-
-
-    @Override
-    public void applySearchTarget(SearchTarget searchTarget) {
-        mSearchTarget = searchTarget;
-        Bundle bundle = searchTarget.getExtras();
-        SearchEventTracker.INSTANCE.get(getContext()).registerWeakHandler(searchTarget, this);
-        if (bundle.getString("package", "").equals(mPackageName)) {
-            return;
-        }
-        mIsInstantGame = bundle.getBoolean("instant_game", false);
-        mPackageName = bundle.getString("package");
-        mPreviewButton.setVisibility(mIsInstantGame ? VISIBLE : GONE);
-        mTitleView.setText(bundle.getString("title"));
-//        TODO: Should use a generic type to get values b/165320033
-        showIfNecessary(mDetailViews[0], bundle.getString("price"));
-        showIfNecessary(mDetailViews[1], bundle.getString("rating"));
-
-        mIconView.setBackgroundResource(R.drawable.ic_deepshortcut_placeholder);
-        UI_HELPER_EXECUTOR.execute(() -> {
-            try {
-                URL url = new URL(bundle.getString("icon_url"));
-                URLConnection con = url.openConnection();
-//                TODO: monitor memory and investigate if it's better to use glide
-                con.addRequestProperty("Cache-Control", "max-age: 0");
-                con.setUseCaches(true);
-                Bitmap bitmap = BitmapFactory.decodeStream(con.getInputStream());
-                BitmapDrawable bitmapDrawable = new BitmapDrawable(getResources(), getRoundedBitmap(
-                        Bitmap.createScaledBitmap(bitmap, mDeviceProfile.allAppsIconSizePx,
-                                mDeviceProfile.allAppsIconSizePx, false)));
-                mIconView.post(() -> mIconView.setBackground(bitmapDrawable));
-            } catch (IOException e) {
-                e.printStackTrace();
-            }
-        });
-    }
-
-    private void showIfNecessary(TextView textView, @Nullable String string) {
-        if (string == null || string.isEmpty()) {
-            textView.setVisibility(GONE);
-        } else {
-            textView.setText(string);
-            textView.setVisibility(VISIBLE);
-        }
-    }
-
-    @Override
-    public void handleSelection(int eventType) {
-        if (mPackageName == null) return;
-        Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(
-                "https://play.google.com/store/apps/details?id="
-                        + mPackageName));
-        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        getContext().startActivity(i);
-        logSearchEvent(eventType);
-    }
-
-    private void launchInstantGame() {
-        if (!mIsInstantGame) return;
-        Intent intent = new Intent(Intent.ACTION_VIEW);
-        String referrer = "Pixel_Launcher";
-        String id = mPackageName;
-        String deepLinkUrl = "market://details?id=" + id + "&launch=true&referrer=" + referrer;
-        intent.setPackage("com.android.vending");
-        intent.setData(Uri.parse(deepLinkUrl));
-        intent.putExtra("overlay", true);
-        intent.putExtra("callerId", getContext().getPackageName());
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        getContext().startActivity(intent);
-        logSearchEvent(SearchTargetEvent.CHILD_SELECT);
-    }
-
-    private void logSearchEvent(int eventType) {
-        SearchEventTracker.INSTANCE.get(getContext()).notifySearchTargetEvent(
-                new SearchTargetEvent.Builder(mSearchTarget, eventType).build());
-    }
 }
diff --git a/src/com/android/launcher3/views/SearchResultSettingsSlice.java b/quickstep/src/com/android/launcher3/search/SearchResultSettingsSlice.java
similarity index 76%
rename from src/com/android/launcher3/views/SearchResultSettingsSlice.java
rename to quickstep/src/com/android/launcher3/search/SearchResultSettingsSlice.java
index 29e6c1b..bf50b67 100644
--- a/src/com/android/launcher3/views/SearchResultSettingsSlice.java
+++ b/quickstep/src/com/android/launcher3/search/SearchResultSettingsSlice.java
@@ -13,8 +13,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.launcher3.views;
+package com.android.launcher3.search;
 
+import android.app.search.SearchTarget;
 import android.content.Context;
 import android.net.Uri;
 import android.util.AttributeSet;
@@ -32,16 +33,16 @@
 
 import com.android.launcher3.Launcher;
 import com.android.launcher3.R;
-import com.android.launcher3.allapps.search.AllAppsSearchBarController;
-import com.android.launcher3.allapps.search.SearchEventTracker;
-import com.android.systemui.plugins.shared.SearchTarget;
-import com.android.systemui.plugins.shared.SearchTargetEvent;
+import com.android.systemui.plugins.shared.SearchTargetEventLegacy;
+import com.android.systemui.plugins.shared.SearchTargetLegacy;
+
+import java.util.List;
 
 /**
  * A slice view wrapper with settings app icon at start
  */
 public class SearchResultSettingsSlice extends LinearLayout implements
-        AllAppsSearchBarController.SearchTargetHandler, SliceView.OnSliceActionListener {
+        SearchTargetHandler, SliceView.OnSliceActionListener {
 
 
     public static final String TARGET_TYPE_SLICE = "settings_slice";
@@ -52,7 +53,7 @@
     private SliceView mSliceView;
     private View mIcon;
     private LiveData<Slice> mSliceLiveData;
-    private SearchTarget mSearchTarget;
+    private SearchTargetLegacy mSearchTarget;
     private final Launcher mLauncher;
 
     public SearchResultSettingsSlice(Context context) {
@@ -79,7 +80,7 @@
     }
 
     @Override
-    public void applySearchTarget(SearchTarget searchTarget) {
+    public void applySearchTarget(SearchTargetLegacy searchTarget) {
         reset();
         mSearchTarget = searchTarget;
         try {
@@ -91,6 +92,18 @@
     }
 
     @Override
+    public void applySearchTarget(SearchTarget parentTarget, List<SearchTarget> children) {
+        reset();
+        try {
+            mSliceLiveData = mLauncher.getLiveSearchManager().getSliceForUri(
+                    parentTarget.getSliceUri());
+            mSliceLiveData.observe(mLauncher, mSliceView);
+        } catch (Exception ex) {
+            Log.e(TAG, "unable to bind slice", ex);
+        }
+    }
+
+    @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         mSliceView.setOnSliceActionListener(this);
@@ -105,8 +118,8 @@
     @Override
     public void handleSelection(int eventType) {
         SearchEventTracker.INSTANCE.get(mLauncher).notifySearchTargetEvent(
-                new SearchTargetEvent.Builder(mSearchTarget,
-                        SearchTargetEvent.CHILD_SELECT).build());
+                new SearchTargetEventLegacy.Builder(mSearchTarget,
+                        SearchTargetEventLegacy.CHILD_SELECT).build());
     }
 
     private void reset() {
@@ -118,7 +131,7 @@
 
     @Override
     public void onSliceAction(@NonNull EventInfo eventInfo, @NonNull SliceItem sliceItem) {
-        handleSelection(SearchTargetEvent.CHILD_SELECT);
+        handleSelection(SearchTargetEventLegacy.CHILD_SELECT);
     }
 
     private Uri getSliceUri() {
diff --git a/src/com/android/launcher3/views/SearchResultSuggestion.java b/quickstep/src/com/android/launcher3/search/SearchResultSuggestion.java
similarity index 95%
rename from src/com/android/launcher3/views/SearchResultSuggestion.java
rename to quickstep/src/com/android/launcher3/search/SearchResultSuggestion.java
index c67b1cf..6a6bd1b 100644
--- a/src/com/android/launcher3/views/SearchResultSuggestion.java
+++ b/quickstep/src/com/android/launcher3/search/SearchResultSuggestion.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.launcher3.views;
+package com.android.launcher3.search;
 
 import android.content.Context;
 import android.content.res.TypedArray;
@@ -22,6 +22,7 @@
 import android.view.ViewGroup;
 
 import com.android.launcher3.R;
+import com.android.launcher3.views.BaseDragLayer;
 
 /**
  * {@link SearchResultIconRow} with custom drawable resource
diff --git a/src/com/android/launcher3/views/SearchResultWidget.java b/quickstep/src/com/android/launcher3/search/SearchResultWidget.java
similarity index 90%
rename from src/com/android/launcher3/views/SearchResultWidget.java
rename to quickstep/src/com/android/launcher3/search/SearchResultWidget.java
index f76de3d..4fe9229 100644
--- a/src/com/android/launcher3/views/SearchResultWidget.java
+++ b/quickstep/src/com/android/launcher3/search/SearchResultWidget.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.launcher3.views;
+package com.android.launcher3.search;
 
 import android.appwidget.AppWidgetHostView;
 import android.appwidget.AppWidgetProviderInfo;
@@ -32,21 +32,19 @@
 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;
+import com.android.systemui.plugins.shared.SearchTargetEventLegacy;
+import com.android.systemui.plugins.shared.SearchTargetLegacy;
 
 /**
  * displays live version of a widget upon receiving {@link AppWidgetProviderInfo} from Search
  * provider
  */
 public class SearchResultWidget extends RelativeLayout implements
-        AllAppsSearchBarController.SearchTargetHandler, DraggableView, View.OnLongClickListener {
+        SearchTargetHandler, DraggableView, View.OnLongClickListener {
 
     private static final String TAG = "SearchResultWidget";
 
@@ -60,7 +58,7 @@
     private final AppWidgetHostView mHostView;
     private final float mScaleToFit;
 
-    private SearchTarget mSearchTarget;
+    private SearchTargetLegacy mSearchTarget;
     private AppWidgetProviderInfo mProviderInfo;
 
     private SearchWidgetInfoContainer mInfoContainer;
@@ -84,7 +82,7 @@
 
         // detect tap event on widget container for search target event reporting
         mClickDetector = new GestureDetector(context,
-                new ClickListener(() -> handleSelection(SearchTargetEvent.CHILD_SELECT)));
+                new ClickListener(() -> handleSelection(SearchTargetEventLegacy.CHILD_SELECT)));
 
         mLongPressHelper = new CheckLongPressHelper(this);
         mLongPressHelper.setLongPressTimeoutFactor(1);
@@ -98,7 +96,7 @@
     }
 
     @Override
-    public void applySearchTarget(SearchTarget searchTarget) {
+    public void applySearchTarget(SearchTargetLegacy searchTarget) {
         if (searchTarget.getExtras() == null
                 || searchTarget.getExtras().getParcelable("provider") == null) {
             setVisibility(GONE);
@@ -143,7 +141,7 @@
     @Override
     public void handleSelection(int eventType) {
         SearchEventTracker.INSTANCE.get(getContext()).notifySearchTargetEvent(
-                new SearchTargetEvent.Builder(mSearchTarget, eventType).build());
+                new SearchTargetEventLegacy.Builder(mSearchTarget, eventType).build());
     }
 
     @Override
@@ -184,7 +182,7 @@
     @Override
     public boolean onLongClick(View view) {
         ItemLongClickListener.INSTANCE_ALL_APPS.onLongClick(view);
-        handleSelection(SearchTargetEvent.LONG_PRESS);
+        handleSelection(SearchTargetEventLegacy.LONG_PRESS);
         return false;
     }
 
diff --git a/src/com/android/launcher3/views/SearchResultWidgetPreview.java b/quickstep/src/com/android/launcher3/search/SearchResultWidgetPreview.java
similarity index 87%
rename from src/com/android/launcher3/views/SearchResultWidgetPreview.java
rename to quickstep/src/com/android/launcher3/search/SearchResultWidgetPreview.java
index c11c232..5effbe5 100644
--- a/src/com/android/launcher3/views/SearchResultWidgetPreview.java
+++ b/quickstep/src/com/android/launcher3/search/SearchResultWidgetPreview.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.launcher3.views;
+package com.android.launcher3.search;
 
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
@@ -32,8 +32,6 @@
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherAppWidgetProviderInfo;
 import com.android.launcher3.R;
-import com.android.launcher3.allapps.search.AllAppsSearchBarController;
-import com.android.launcher3.allapps.search.SearchEventTracker;
 import com.android.launcher3.dragndrop.DragOptions;
 import com.android.launcher3.model.WidgetItem;
 import com.android.launcher3.touch.ItemLongClickListener;
@@ -41,14 +39,14 @@
 import com.android.launcher3.widget.PendingItemDragHelper;
 import com.android.launcher3.widget.WidgetCell;
 import com.android.launcher3.widget.WidgetImageView;
-import com.android.systemui.plugins.shared.SearchTarget;
-import com.android.systemui.plugins.shared.SearchTargetEvent;
+import com.android.systemui.plugins.shared.SearchTargetEventLegacy;
+import com.android.systemui.plugins.shared.SearchTargetLegacy;
 
 /**
  * displays preview of a widget upon receiving {@link AppWidgetProviderInfo} from Search provider
  */
 public class SearchResultWidgetPreview extends LinearLayout implements
-        AllAppsSearchBarController.SearchTargetHandler, View.OnLongClickListener,
+        SearchTargetHandler, View.OnLongClickListener,
         View.OnClickListener {
 
     public static final String TARGET_TYPE_WIDGET_PREVIEW = "widget_preview";
@@ -57,7 +55,7 @@
     private WidgetCell mWidgetCell;
     private Toast mWidgetToast;
 
-    private SearchTarget mSearchTarget;
+    private SearchTargetLegacy mSearchTarget;
 
 
     public SearchResultWidgetPreview(Context context) {
@@ -85,7 +83,7 @@
     }
 
     @Override
-    public void applySearchTarget(SearchTarget searchTarget) {
+    public void applySearchTarget(SearchTargetLegacy searchTarget) {
         if (searchTarget.getExtras() == null
                 || searchTarget.getExtras().getParcelable("provider") == null) {
             setVisibility(GONE);
@@ -123,19 +121,19 @@
         new PendingItemDragHelper(mWidgetCell).startDrag(
                 imageView.getBitmapBounds(), imageView.getBitmap().getWidth(), imageView.getWidth(),
                 new Point(loc[0], loc[1]), mLauncher.getAppsView(), new DragOptions());
-        handleSelection(SearchTargetEvent.LONG_PRESS);
+        handleSelection(SearchTargetEventLegacy.LONG_PRESS);
         return true;
     }
 
     @Override
     public void onClick(View view) {
         mWidgetToast = BaseWidgetSheet.showWidgetToast(getContext(), mWidgetToast);
-        handleSelection(SearchTargetEvent.SELECT);
+        handleSelection(SearchTargetEventLegacy.SELECT);
     }
 
     @Override
     public void handleSelection(int eventType) {
         SearchEventTracker.INSTANCE.get(getContext()).notifySearchTargetEvent(
-                new SearchTargetEvent.Builder(mSearchTarget, eventType).build());
+                new SearchTargetEventLegacy.Builder(mSearchTarget, eventType).build());
     }
 }
diff --git a/src/com/android/launcher3/views/SearchSectionHeaderView.java b/quickstep/src/com/android/launcher3/search/SearchSectionHeaderView.java
similarity index 77%
rename from src/com/android/launcher3/views/SearchSectionHeaderView.java
rename to quickstep/src/com/android/launcher3/search/SearchSectionHeaderView.java
index 326c23d..ccc38db 100644
--- a/src/com/android/launcher3/views/SearchSectionHeaderView.java
+++ b/quickstep/src/com/android/launcher3/search/SearchSectionHeaderView.java
@@ -13,22 +13,24 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.launcher3.views;
+package com.android.launcher3.search;
 
+import android.app.search.SearchTarget;
 import android.content.Context;
 import android.util.AttributeSet;
 import android.widget.TextView;
 
 import androidx.annotation.Nullable;
 
-import com.android.launcher3.allapps.search.AllAppsSearchBarController;
-import com.android.systemui.plugins.shared.SearchTarget;
+import com.android.systemui.plugins.shared.SearchTargetLegacy;
+
+import java.util.List;
 
 /**
  * Header text view that shows a title for a given section in All apps search
  */
 public class SearchSectionHeaderView extends TextView implements
-        AllAppsSearchBarController.SearchTargetHandler {
+        SearchTargetHandler {
     public static final String TARGET_TYPE_SECTION_HEADER = "section_header";
 
     public SearchSectionHeaderView(Context context) {
@@ -45,7 +47,7 @@
     }
 
     @Override
-    public void applySearchTarget(SearchTarget searchTarget) {
+    public void applySearchTarget(SearchTargetLegacy searchTarget) {
         String title = searchTarget.getExtras().getString("title");
         if (title == null || !title.isEmpty()) {
             setText(title);
@@ -54,4 +56,10 @@
             setVisibility(INVISIBLE);
         }
     }
+
+    @Override
+    public void applySearchTarget(SearchTarget parentTarget, List<SearchTarget> children) {
+        setText(parentTarget.getSearchAction().getTitle());
+        setVisibility(VISIBLE);
+    }
 }
diff --git a/quickstep/src/com/android/launcher3/search/SearchServicePipeline.java b/quickstep/src/com/android/launcher3/search/SearchServicePipeline.java
new file mode 100644
index 0000000..6585213
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/search/SearchServicePipeline.java
@@ -0,0 +1,137 @@
+/*
+ * 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.search;
+
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+
+import android.app.search.Query;
+import android.app.search.SearchContext;
+import android.app.search.SearchSession;
+import android.app.search.SearchTarget;
+import android.app.search.SearchUiManager;
+import android.content.Context;
+import android.os.CancellationSignal;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.app.search.ResultType;
+import com.android.launcher3.allapps.AllAppsGridAdapter;
+import com.android.launcher3.allapps.AllAppsSectionDecorator;
+import com.android.launcher3.allapps.search.SearchPipeline;
+import com.android.launcher3.allapps.search.SearchSectionInfo;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.function.Consumer;
+
+/**
+ * Search pipeline utilizing {@link android.app.search.SearchUiManager}
+ */
+public class SearchServicePipeline implements SearchPipeline {
+    private static final int SUPPORTED_RESULT_TYPES =
+            ResultType.APPLICATION | ResultType.SHORTCUT | ResultType.PLAY | ResultType.PEOPLE
+                    | ResultType.SETTING;
+    private static final int REQUEST_TIMEOUT = 200;
+    private static final String TAG = "SearchServicePipeline";
+
+
+    private final Context mContext;
+    private final SearchSession mSession;
+    private final DeviceSearchAdapterProvider mAdapterProvider;
+
+    private boolean mCanceled = false;
+
+
+    public SearchServicePipeline(Context context, DeviceSearchAdapterProvider adapterProvider) {
+        mContext = context;
+        mAdapterProvider = adapterProvider;
+        SearchUiManager manager = context.getSystemService(SearchUiManager.class);
+        mSession = manager.createSearchSession(
+                new SearchContext(SUPPORTED_RESULT_TYPES, REQUEST_TIMEOUT, null));
+    }
+
+    @Override
+    public void query(String input, Consumer<ArrayList<AllAppsGridAdapter.AdapterItem>> callback,
+            CancellationSignal cancellationSignal) {
+        mCanceled = false;
+        Query query = new Query(input, System.currentTimeMillis(), null);
+        mSession.query(query, UI_HELPER_EXECUTOR, items -> {
+            if (!mCanceled) {
+                callback.accept(this.onResult(items));
+            }
+            Log.w(TAG, "Ignoring results due to cancel signal");
+        });
+    }
+
+    /**
+     * Given A list of search Targets, pairs a group of search targets to a AdapterItem that can
+     * be inflated in AllAppsRecyclerView
+     */
+    private ArrayList<AllAppsGridAdapter.AdapterItem> onResult(List<SearchTarget> searchTargets) {
+        HashMap<String, SearchAdapterItem> adapterMap = new LinkedHashMap<>();
+        List<SearchTarget> unmappedChildren = new ArrayList<>();
+        SearchSectionInfo section = new SearchSectionInfo();
+        section.setDecorationHandler(
+                new AllAppsSectionDecorator.SectionDecorationHandler(mContext, true));
+        for (SearchTarget target : searchTargets) {
+            if (!TextUtils.isEmpty(target.getParentId())) {
+                if (!addChildToParent(target, adapterMap)) {
+                    unmappedChildren.add(target);
+                }
+                continue;
+            }
+            int viewType = mAdapterProvider.getViewTypeForSearchTarget(target);
+            if (viewType != -1) {
+                SearchAdapterItem adapterItem = new SearchAdapterItem(target, viewType);
+                adapterItem.searchSectionInfo = section;
+                adapterMap.put(target.getId(), adapterItem);
+            }
+        }
+        for (SearchTarget s : unmappedChildren) {
+            if (!addChildToParent(s, adapterMap)) {
+                Log.w(TAG,
+                        "Unable to pair child " + s.getId() + " to parent " + s.getParentId());
+            }
+        }
+        return new ArrayList<>(adapterMap.values());
+    }
+
+    /**
+     * Adds a child SearchTarget to a collection of searchTarget children with a shared parentId.
+     * Returns false if no parent searchTarget with id=$parentId does not exists.
+     */
+    private boolean addChildToParent(SearchTarget target, HashMap<String, SearchAdapterItem> map) {
+        if (!map.containsKey(target.getParentId())) return false;
+        map.get(target.getParentId()).getInlineItems().add(target);
+        return true;
+    }
+
+    /**
+     * Unregister callbacks and destroy search session
+     */
+    public void destroy() {
+        mSession.destroy();
+    }
+
+    /**
+     * Cancels current ongoing search request.
+     */
+    public void cancel() {
+        mCanceled = true;
+    }
+}
diff --git a/src/com/android/launcher3/views/SearchSettingsRowView.java b/quickstep/src/com/android/launcher3/search/SearchSettingsRowView.java
similarity index 84%
rename from src/com/android/launcher3/views/SearchSettingsRowView.java
rename to quickstep/src/com/android/launcher3/search/SearchSettingsRowView.java
index 160ee65..6fc0046 100644
--- a/src/com/android/launcher3/views/SearchSettingsRowView.java
+++ b/quickstep/src/com/android/launcher3/search/SearchSettingsRowView.java
@@ -13,12 +13,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.launcher3.views;
+package com.android.launcher3.search;
 
 import static com.android.launcher3.FastBitmapDrawable.newIcon;
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
 
+import android.app.search.SearchAction;
+import android.app.search.SearchTarget;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -37,11 +39,9 @@
 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.model.data.PackageItemInfo;
-import com.android.systemui.plugins.shared.SearchTarget;
-import com.android.systemui.plugins.shared.SearchTargetEvent;
+import com.android.systemui.plugins.shared.SearchTargetEventLegacy;
+import com.android.systemui.plugins.shared.SearchTargetLegacy;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -50,7 +50,7 @@
  * A row of clickable TextViews with a breadcrumb for settings search.
  */
 public class SearchSettingsRowView extends LinearLayout implements
-        View.OnClickListener, AllAppsSearchBarController.SearchTargetHandler {
+        View.OnClickListener, SearchTargetHandler {
 
     public static final String TARGET_TYPE_SETTINGS_ROW = "settings_row";
 
@@ -58,7 +58,7 @@
     private TextView mTitleView;
     private TextView mBreadcrumbsView;
     private Intent mIntent;
-    private SearchTarget mSearchTarget;
+    private SearchTargetLegacy mSearchTarget;
 
 
     public SearchSettingsRowView(@NonNull Context context) {
@@ -86,7 +86,7 @@
     }
 
     @Override
-    public void applySearchTarget(SearchTarget searchTarget) {
+    public void applySearchTarget(SearchTargetLegacy searchTarget) {
         mSearchTarget = searchTarget;
         Bundle bundle = searchTarget.getExtras();
         mIntent = bundle.getParcelable("intent");
@@ -99,6 +99,14 @@
         SearchEventTracker.INSTANCE.get(getContext()).registerWeakHandler(searchTarget, this);
     }
 
+    @Override
+    public void applySearchTarget(SearchTarget parentTarget, List<SearchTarget> children) {
+        SearchAction action = parentTarget.getSearchAction();
+        mIconView.setContentDescription(action.getTitle());
+        showIfAvailable(mTitleView, action.getTitle().toString());
+        showIfAvailable(mBreadcrumbsView, action.getSubtitle().toString());
+    }
+
     private void showIfAvailable(TextView view, @Nullable String string) {
         if (TextUtils.isEmpty(string)) {
             view.setVisibility(GONE);
@@ -110,7 +118,7 @@
 
     @Override
     public void onClick(View view) {
-        handleSelection(SearchTargetEvent.SELECT);
+        handleSelection(SearchTargetEventLegacy.SELECT);
     }
 
     @Override
@@ -122,7 +130,7 @@
         launcher.startActivityForResult(mIntent, 0);
 
         SearchEventTracker.INSTANCE.get(getContext()).notifySearchTargetEvent(
-                new SearchTargetEvent.Builder(mSearchTarget, eventType).build());
+                new SearchTargetEventLegacy.Builder(mSearchTarget, eventType).build());
     }
 
     /**
diff --git a/quickstep/src/com/android/launcher3/search/SearchTargetHandler.java b/quickstep/src/com/android/launcher3/search/SearchTargetHandler.java
new file mode 100644
index 0000000..e72578d
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/search/SearchTargetHandler.java
@@ -0,0 +1,49 @@
+/*
+ * 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.search;
+
+import android.app.search.SearchTarget;
+
+import com.android.systemui.plugins.shared.SearchTargetLegacy;
+
+import java.util.List;
+
+/**
+ * An interface for supporting dynamic search results
+ */
+public interface SearchTargetHandler {
+
+    /**
+     * Update view using values from {@link SearchTargetLegacy}
+     */
+    default void applySearchTarget(SearchTargetLegacy searchTarget) {
+    }
+
+
+    /**
+     * Update view using values from {@link SearchTargetLegacy}
+     */
+    default void applySearchTarget(SearchTarget parentTarget, List<SearchTarget> children) {
+    }
+
+    /**
+     * Handles selection of SearchTarget
+     */
+    default void handleSelection(int eventType) {
+    }
+
+}
diff --git a/src/com/android/launcher3/views/ThumbnailSearchResultView.java b/quickstep/src/com/android/launcher3/search/ThumbnailSearchResultView.java
similarity index 85%
rename from src/com/android/launcher3/views/ThumbnailSearchResultView.java
rename to quickstep/src/com/android/launcher3/search/ThumbnailSearchResultView.java
index 573d48f..44f7057 100644
--- a/src/com/android/launcher3/views/ThumbnailSearchResultView.java
+++ b/quickstep/src/com/android/launcher3/search/ThumbnailSearchResultView.java
@@ -13,11 +13,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.launcher3.views;
+package com.android.launcher3.search;
 
 
-import static com.android.launcher3.views.SearchResultIcon.REMOTE_ACTION_SHOULD_START;
-import static com.android.launcher3.views.SearchResultIcon.REMOTE_ACTION_TOKEN;
+import static com.android.launcher3.search.SearchResultIcon.REMOTE_ACTION_SHOULD_START;
+import static com.android.launcher3.search.SearchResultIcon.REMOTE_ACTION_TOKEN;
 
 import android.content.Context;
 import android.content.Intent;
@@ -30,26 +30,24 @@
 import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
 
 import com.android.launcher3.Launcher;
-import com.android.launcher3.allapps.search.AllAppsSearchBarController;
-import com.android.launcher3.allapps.search.SearchEventTracker;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.RemoteActionItemInfo;
 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 com.android.systemui.plugins.shared.SearchTargetEventLegacy;
+import com.android.systemui.plugins.shared.SearchTargetLegacy;
 
 /**
  * A view representing a high confidence app search result that includes shortcuts
  */
 public class ThumbnailSearchResultView extends androidx.appcompat.widget.AppCompatImageView
-        implements AllAppsSearchBarController.SearchTargetHandler {
+        implements SearchTargetHandler {
 
     public static final String TARGET_TYPE_SCREENSHOT = "screenshot";
     public static final String TARGET_TYPE_SCREENSHOT_LEGACY = "screenshot_legacy";
 
-    private SearchTarget mSearchTarget;
+    private SearchTargetLegacy mSearchTarget;
 
     public ThumbnailSearchResultView(Context context) {
         super(context);
@@ -74,11 +72,11 @@
             ItemClickHandler.onClickAppShortcut(this, (WorkspaceItemInfo) itemInfo, launcher);
         }
         SearchEventTracker.INSTANCE.get(getContext()).notifySearchTargetEvent(
-                new SearchTargetEvent.Builder(mSearchTarget, eventType).build());
+                new SearchTargetEventLegacy.Builder(mSearchTarget, eventType).build());
     }
 
     @Override
-    public void applySearchTarget(SearchTarget target) {
+    public void applySearchTarget(SearchTargetLegacy target) {
         mSearchTarget = target;
         Bitmap bitmap;
         if (target.getRemoteAction() != null) {
@@ -110,7 +108,7 @@
         RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(null, bitmap);
         drawable.setCornerRadius(Themes.getDialogCornerRadius(getContext()));
         setImageDrawable(drawable);
-        setOnClickListener(v -> handleSelection(SearchTargetEvent.SELECT));
+        setOnClickListener(v -> handleSelection(SearchTargetEventLegacy.SELECT));
         SearchEventTracker.INSTANCE.get(getContext()).registerWeakHandler(target, this);
     }
 }
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 8c3b57a..4f62d2f 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -42,6 +42,8 @@
 import com.android.launcher3.LauncherSettings.Favorites;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.Workspace;
+import com.android.launcher3.allapps.AllAppsContainerView;
+import com.android.launcher3.allapps.search.SearchAdapterProvider;
 import com.android.launcher3.anim.AnimatorPlaybackController;
 import com.android.launcher3.appprediction.PredictionRowView;
 import com.android.launcher3.config.FeatureFlags;
@@ -51,6 +53,7 @@
 import com.android.launcher3.model.BgDataModel.FixedContainerItems;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.popup.SystemShortcut;
+import com.android.launcher3.search.DeviceSearchAdapterProvider;
 import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory;
 import com.android.launcher3.uioverrides.states.QuickstepAtomicAnimationFactory;
 import com.android.launcher3.uioverrides.touchcontrollers.NavBarToHomeTouchController;
@@ -217,6 +220,7 @@
     @Override
     public void onDestroy() {
         super.onDestroy();
+        getAppsView().getSearchUiManager().destroy();
         if (mHotseatPredictionController != null) {
             mHotseatPredictionController.destroy();
             mHotseatPredictionController = null;
@@ -264,6 +268,11 @@
     }
 
     @Override
+    public SearchAdapterProvider createSearchAdapterProvider(AllAppsContainerView appsView) {
+        return new DeviceSearchAdapterProvider(this, appsView);
+    }
+
+    @Override
     public TouchController[] createTouchControllers() {
         Mode mode = SysUINavigationMode.getMode(this);
 
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index f82bc2d..3d5b1c6 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -721,8 +721,11 @@
 
     @UiThread
     public void onGestureStarted(boolean isLikelyToStartNewTask) {
-        InteractionJankMonitorWrapper.begin(
-                InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH, 2000 /* ms timeout */);
+        // Temporarily disable this until we have a view that we can use
+        // InteractionJankMonitorWrapper.begin(mRecentsView,
+        //         InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH, 2000 /* ms timeout */);
+        // InteractionJankMonitorWrapper.begin(mRecentsView,
+        //         InteractionJankMonitorWrapper.CUJ_APP_CLOSE_TO_HOME);
         notifyGestureStartedAsync();
         setIsLikelyToStartNewTask(isLikelyToStartNewTask, false /* animate */);
         mStateCallback.setStateOnUiThread(STATE_GESTURE_STARTED);
@@ -802,6 +805,14 @@
         // Fast-finish the attaching animation if it's still running.
         maybeUpdateRecentsAttachedState(false);
         final GestureEndTarget endTarget = mGestureState.getEndTarget();
+        if (endTarget != NEW_TASK) {
+            InteractionJankMonitorWrapper.cancel(
+                    InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH);
+        }
+        if (endTarget != HOME) {
+            InteractionJankMonitorWrapper.cancel(
+                    InteractionJankMonitorWrapper.CUJ_APP_CLOSE_TO_HOME);
+        }
         switch (endTarget) {
             case HOME:
                 mStateCallback.setState(STATE_SCALED_CONTROLLER_HOME | STATE_CAPTURE_SCREENSHOT);
@@ -820,9 +831,6 @@
                 break;
         }
         ActiveGestureLog.INSTANCE.addLog("onSettledOnEndTarget " + endTarget);
-        if (endTarget != NEW_TASK) {
-            InteractionJankMonitorWrapper.cancel(InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH);
-        }
     }
 
     /** @return Whether this was the task we were waiting to appear, and thus handled it. */
@@ -1159,7 +1167,8 @@
                 TaskInfoCompat.getPipSourceRectHint(runningTaskTarget.pictureInPictureParams),
                 TaskInfoCompat.getWindowConfigurationBounds(taskInfo),
                 startBounds,
-                destinationBounds);
+                destinationBounds,
+                mRecentsView);
         // We would assume home and app window always in the same rotation While homeRotation
         // is not ROTATION_0 (which implies the rotation is turned on in launcher settings).
         if (homeRotation == ROTATION_0
@@ -1219,11 +1228,9 @@
         anim.addOnUpdateListener((r, p) -> {
             updateSysUiFlags(Math.max(p, mCurrentShift.value));
         });
-        final int cuj = InteractionJankMonitorWrapper.CUJ_APP_CLOSE_TO_HOME;
         anim.addAnimatorListener(new AnimationSuccessListener() {
             @Override
             public void onAnimationStart(Animator animation) {
-                InteractionJankMonitorWrapper.begin(cuj);
                 if (mActivity != null) {
                     removeLiveTileOverlay();
                 }
@@ -1237,13 +1244,6 @@
                 // Make sure recents is in its final state
                 maybeUpdateRecentsAttachedState(false);
                 mActivityInterface.onSwipeUpToHomeComplete(mDeviceState);
-                InteractionJankMonitorWrapper.end(cuj);
-            }
-
-            @Override
-            public void onAnimationCancel(Animator animation) {
-                super.onAnimationCancel(animation);
-                InteractionJankMonitorWrapper.cancel(cuj);
             }
         });
         if (mRecentsAnimationTargets != null) {
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index b4f20d1..5bed929 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -396,4 +396,9 @@
             pa.addFloat(recentsView, FULLSCREEN_PROGRESS, 1, 0, LINEAR);
         }
     }
+
+    /** Called when OverviewService is bound to this process */
+    void onOverviewServiceBound() {
+        // Do nothing
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
index 901040d..a80c111 100644
--- a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
@@ -22,12 +22,14 @@
 import static com.android.launcher3.GestureNavContract.EXTRA_ICON_POSITION;
 import static com.android.launcher3.GestureNavContract.EXTRA_ICON_SURFACE;
 import static com.android.launcher3.GestureNavContract.EXTRA_REMOTE_CALLBACK;
+import static com.android.launcher3.Utilities.createHomeIntent;
 import static com.android.launcher3.anim.Interpolators.ACCEL;
 import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME;
 
 import android.animation.ObjectAnimator;
 import android.annotation.TargetApi;
 import android.app.ActivityOptions;
+import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Matrix;
@@ -126,7 +128,11 @@
         ActivityOptions options = ActivityOptions.makeCustomAnimation(mContext, 0, 0);
         Intent intent = new Intent(mGestureState.getHomeIntent());
         mActiveAnimationFactory.addGestureContract(intent);
-        mContext.startActivity(intent, options.toBundle());
+        try {
+            mContext.startActivity(intent, options.toBundle());
+        } catch (NullPointerException | ActivityNotFoundException | SecurityException e) {
+            mContext.startActivity(createHomeIntent());
+        }
         return mActiveAnimationFactory;
     }
 
diff --git a/quickstep/src/com/android/quickstep/ImageActionsApi.java b/quickstep/src/com/android/quickstep/ImageActionsApi.java
index ba8ba33..b04905c 100644
--- a/quickstep/src/com/android/quickstep/ImageActionsApi.java
+++ b/quickstep/src/com/android/quickstep/ImageActionsApi.java
@@ -22,11 +22,14 @@
 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
 import static com.android.quickstep.util.ImageActionUtils.persistBitmapAndStartActivity;
 
+import android.app.prediction.AppTarget;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ShortcutInfo;
 import android.graphics.Bitmap;
 import android.graphics.Insets;
 import android.graphics.Rect;
+import android.graphics.RectF;
 import android.util.Log;
 
 import androidx.annotation.Nullable;
@@ -96,4 +99,12 @@
         ImageActionUtils.saveScreenshot(mSystemUiProxy, screenshot, screenshotBounds, visibleInsets,
                 task);
     }
+
+    /**
+     * Share the image when user taps on overview share targets.
+     */
+    @UiThread
+    public void shareImage(RectF rectF, ShortcutInfo shortcutInfo, AppTarget appTarget) {
+        ImageActionUtils.shareImage(mContext, mBitmapSupplier, rectF, shortcutInfo, appTarget, TAG);
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
index 9f435f5..7630bc4 100644
--- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
@@ -270,4 +270,11 @@
                 + res.getDimensionPixelSize(R.dimen.overview_actions_height);
         return actionsHeight;
     }
-}
\ No newline at end of file
+
+    @Override
+    void onOverviewServiceBound() {
+        final BaseQuickstepLauncher activity = getCreatedActivity();
+        if (activity == null) return;
+        activity.getAppTransitionManager().registerRemoteTransitions();
+    }
+}
diff --git a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
index eb33f98..b258a10 100644
--- a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
+++ b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
@@ -66,6 +66,7 @@
     private final RectF mOneHandedModeRegion = new RectF();
     private int mCurrentDisplayRotation;
     private int mNavBarGesturalHeight;
+    private int mNavBarLargerGesturalHeight;
     private boolean mEnableMultipleRegions;
     private Resources mResources;
     private OrientationRectF mLastRectTouched;
@@ -106,6 +107,9 @@
         mMode = mode;
         mContractInfo = contractInfo;
         mNavBarGesturalHeight = getNavbarSize(ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE);
+        mNavBarLargerGesturalHeight = ResourceUtils.getDimenByName(
+                ResourceUtils.NAVBAR_BOTTOM_GESTURE_LARGER_SIZE, resources,
+                mNavBarGesturalHeight);
     }
 
     private void refreshTouchRegion(Info info, Resources newRes) {
@@ -234,6 +238,7 @@
         Point size = display.realSize;
         int rotation = display.rotation;
         int touchHeight = mNavBarGesturalHeight;
+        int largerGesturalHeight = mNavBarLargerGesturalHeight;
         OrientationRectF orientationRectF =
                 new OrientationRectF(0, 0, size.x, size.y, rotation);
         if (mMode == SysUINavigationMode.Mode.NO_BUTTON) {
@@ -256,7 +261,8 @@
             }
         }
         // One handed gestural only active on portrait mode
-        mOneHandedModeRegion.set(0, orientationRectF.bottom - touchHeight, size.x, size.y);
+        mOneHandedModeRegion.set(0, orientationRectF.bottom - mNavBarLargerGesturalHeight,
+                size.x, size.y);
 
         return orientationRectF;
     }
@@ -378,6 +384,7 @@
         }
         pw.println(regions.toString());
         pw.println("  mNavBarGesturalHeight=" + mNavBarGesturalHeight);
+        pw.println("  mNavBarLargerGesturalHeight=" + mNavBarLargerGesturalHeight);
         pw.println("  mOneHandedModeRegion=" + mOneHandedModeRegion);
     }
 
diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
index fd9c315..985389e 100644
--- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
+++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
@@ -175,7 +175,12 @@
                 return;
             }
 
-            InteractionJankMonitorWrapper.begin(InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH);
+            final T activity = mActivityInterface.getCreatedActivity();
+            if (activity != null) {
+                InteractionJankMonitorWrapper.begin(
+                        activity.getRootView(),
+                        InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH);
+            }
 
             // Otherwise, start overview.
             mListener = mActivityInterface.createActivityInitListener(this::onActivityReady);
diff --git a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
index 49feef0..fb8f9fe 100644
--- a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
+++ b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
@@ -20,10 +20,10 @@
 import static android.content.Intent.ACTION_PACKAGE_CHANGED;
 import static android.content.Intent.ACTION_PACKAGE_REMOVED;
 
+import static com.android.launcher3.Utilities.createHomeIntent;
 import static com.android.launcher3.config.FeatureFlags.SEPARATE_RECENTS_ACTIVITY;
 import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter;
 import static com.android.systemui.shared.system.PackageManagerWrapper.ACTION_PREFERRED_ACTIVITY_CHANGED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED;
 
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -75,9 +75,7 @@
     public OverviewComponentObserver(Context context, RecentsAnimationDeviceState deviceState) {
         mContext = context;
         mDeviceState = deviceState;
-        mCurrentHomeIntent = new Intent(Intent.ACTION_MAIN)
-                .addCategory(Intent.CATEGORY_HOME)
-                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mCurrentHomeIntent = createHomeIntent();
         mMyHomeIntent = new Intent(mCurrentHomeIntent).setPackage(mContext.getPackageName());
         ResolveInfo info = context.getPackageManager().resolveActivity(mMyHomeIntent, 0);
         ComponentName myHomeComponent =
@@ -119,10 +117,6 @@
         updateOverviewTargets();
     }
 
-    public boolean assistantGestureIsConstrained() {
-        return (mDeviceState.getSystemUiStateFlags() & SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED) != 0;
-    }
-
     /**
      * Update overview intent and {@link BaseActivityInterface} based off the current launcher home
      * component.
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index d050030..7beeae2 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -21,6 +21,7 @@
 import static com.android.launcher3.QuickstepAppTransitionManagerImpl.RECENTS_LAUNCH_DURATION;
 import static com.android.launcher3.QuickstepAppTransitionManagerImpl.STATUS_BAR_TRANSITION_DURATION;
 import static com.android.launcher3.QuickstepAppTransitionManagerImpl.STATUS_BAR_TRANSITION_PRE_DELAY;
+import static com.android.launcher3.Utilities.createHomeIntent;
 import static com.android.launcher3.testing.TestProtocol.OVERVIEW_STATE_ORDINAL;
 import static com.android.quickstep.TaskUtils.taskIsATargetWithMode;
 import static com.android.quickstep.TaskViewUtils.createRecentsWindowAnimator;
@@ -45,6 +46,7 @@
 import com.android.launcher3.R;
 import com.android.launcher3.WrappedAnimationRunnerImpl;
 import com.android.launcher3.WrappedLauncherAnimationRunner;
+import com.android.launcher3.allapps.search.SearchAdapterProvider;
 import com.android.launcher3.anim.Interpolators;
 import com.android.launcher3.anim.PendingAnimation;
 import com.android.launcher3.compat.AccessibilityManagerCompat;
@@ -91,6 +93,7 @@
 
     // Strong refs to runners which are cleared when the activity is destroyed
     private WrappedAnimationRunnerImpl mActivityLaunchAnimationRunner;
+    private SearchAdapterProvider mSearchAdapterProvider;
 
     /**
      * Init drag layer and overview panel views.
@@ -307,9 +310,7 @@
     }
 
     public void startHome() {
-        startActivity(new Intent(Intent.ACTION_MAIN)
-                .addCategory(Intent.CATEGORY_HOME)
-                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+        startActivity(createHomeIntent());
     }
 
     @Override
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationController.java b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
index bc5e18d..646c5a0 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationController.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
@@ -136,6 +136,7 @@
         UI_HELPER_EXECUTOR.execute(() -> {
             mController.finish(toRecents, sendUserLeaveHint);
             InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH);
+            InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_APP_CLOSE_TO_HOME);
             if (callback != null) {
                 MAIN_EXECUTOR.execute(callback);
             }
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index 960abeb..74b56e9 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -23,6 +23,7 @@
 import static com.android.quickstep.SysUINavigationMode.Mode.THREE_BUTTONS;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_GLOBAL_ACTIONS_SHOWING;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
@@ -373,7 +374,7 @@
      * @return the system ui state flags.
      */
     // TODO(141886704): See if we can remove this
-    public @SystemUiStateFlags int getSystemUiStateFlags() {
+    public int getSystemUiStateFlags() {
         return mSystemUiStateFlags;
     }
 
@@ -406,6 +407,13 @@
     }
 
     /**
+     * @return whether assistant gesture is constraint
+     */
+    public boolean isAssistantGestureIsConstrained() {
+        return (mSystemUiStateFlags & SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED) != 0;
+    }
+
+    /**
      * @return whether the bubble stack is expanded
      */
     public boolean isBubblesExpanded() {
diff --git a/quickstep/src/com/android/quickstep/SysUINavigationMode.java b/quickstep/src/com/android/quickstep/SysUINavigationMode.java
index 71bf1bb..efec037 100644
--- a/quickstep/src/com/android/quickstep/SysUINavigationMode.java
+++ b/quickstep/src/com/android/quickstep/SysUINavigationMode.java
@@ -73,6 +73,7 @@
     private Mode mMode;
 
     private int mNavBarGesturalHeight;
+    private int mNavBarLargerGesturalHeight;
 
     private final List<NavigationModeChangeListener> mChangeListeners = new ArrayList<>();
     private final List<OneHandedModeChangeListener> mOneHandedOverlayChangeListeners =
@@ -112,6 +113,17 @@
 
         if (mNavBarGesturalHeight != newGesturalHeight) {
             mNavBarGesturalHeight = newGesturalHeight;
+        }
+
+        int newLargerGesturalHeight = ResourceUtils.getDimenByName(
+                ResourceUtils.NAVBAR_BOTTOM_GESTURE_LARGER_SIZE, mContext.getResources(),
+                INVALID_RESOURCE_HANDLE);
+        if (newLargerGesturalHeight == INVALID_RESOURCE_HANDLE) {
+            Log.e(TAG, "Failed to get system resource ID. Incompatible framework version?");
+            return;
+        }
+        if (mNavBarLargerGesturalHeight != newLargerGesturalHeight) {
+            mNavBarLargerGesturalHeight = newLargerGesturalHeight;
             dispatchOneHandedOverlayChange();
         }
     }
@@ -122,6 +134,9 @@
         mNavBarGesturalHeight = ResourceUtils.getDimenByName(
                 ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE, mContext.getResources(),
                 INVALID_RESOURCE_HANDLE);
+        mNavBarLargerGesturalHeight = ResourceUtils.getDimenByName(
+                ResourceUtils.NAVBAR_BOTTOM_GESTURE_LARGER_SIZE, mContext.getResources(),
+                mNavBarGesturalHeight);
 
         if (modeInt == INVALID_RESOURCE_HANDLE) {
             Log.e(TAG, "Failed to get system resource ID. Incompatible framework version?");
@@ -143,7 +158,7 @@
 
     private void dispatchOneHandedOverlayChange() {
         for (OneHandedModeChangeListener listener : mOneHandedOverlayChangeListeners) {
-            listener.onOneHandedModeChanged(mNavBarGesturalHeight);
+            listener.onOneHandedModeChanged(mNavBarLargerGesturalHeight);
         }
     }
 
@@ -158,7 +173,7 @@
 
     public int addOneHandedOverlayChangeListener(OneHandedModeChangeListener listener) {
         mOneHandedOverlayChangeListeners.add(listener);
-        return mNavBarGesturalHeight;
+        return mNavBarLargerGesturalHeight;
     }
 
     public void removeOneHandedOverlayChangeListener(OneHandedModeChangeListener listener) {
@@ -182,4 +197,4 @@
     public interface OneHandedModeChangeListener {
         void onOneHandedModeChanged(int newGesturalHeight);
     }
-}
\ No newline at end of file
+}
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index a214d81..ca55468 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -35,6 +35,7 @@
 import com.android.systemui.shared.recents.IPinnedStackAnimationListener;
 import com.android.systemui.shared.recents.ISystemUiProxy;
 import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.system.RemoteTransitionCompat;
 
 /**
  * Holds the reference to SystemUI.
@@ -408,4 +409,26 @@
             }
         }
     }
+
+    @Override
+    public void registerRemoteTransition(RemoteTransitionCompat remoteTransition) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.registerRemoteTransition(remoteTransition);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call registerRemoteTransition");
+            }
+        }
+    }
+
+    @Override
+    public void unregisterRemoteTransition(RemoteTransitionCompat remoteTransition) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.unregisterRemoteTransition(remoteTransition);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call registerRemoteTransition");
+            }
+        }
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 1e0a00a..1f7cec5 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -136,6 +136,12 @@
                 SystemUiProxy.INSTANCE.get(TouchInteractionService.this).setProxy(proxy);
                 TouchInteractionService.this.initInputMonitor();
                 preloadOverview(true /* fromInit */);
+                mDeviceState.runOnUserUnlocked(() -> {
+                    final BaseActivityInterface ai =
+                            mOverviewComponentObserver.getActivityInterface();
+                    if (ai == null) return;
+                    ai.onOverviewServiceBound();
+                });
             });
             sIsInitialized = true;
         }
@@ -466,7 +472,8 @@
                             this,
                             mGestureState,
                             InputConsumer.NO_OP, mInputMonitorCompat,
-                            mOverviewComponentObserver.assistantGestureIsConstrained());
+                            mDeviceState,
+                            event);
                 } else if (mDeviceState.canTriggerOneHandedAction(event)
                     && !mDeviceState.isOneHandedModeActive()) {
                     // Consume gesture event for triggering one handed feature.
@@ -563,12 +570,8 @@
         }
         if (mDeviceState.isFullyGesturalNavMode()) {
             if (mDeviceState.canTriggerAssistantAction(event, newGestureState.getRunningTask())) {
-                base = new AssistantInputConsumer(
-                    this,
-                    newGestureState,
-                    base,
-                    mInputMonitorCompat,
-                    mOverviewComponentObserver.assistantGestureIsConstrained());
+                base = new AssistantInputConsumer(this, newGestureState, base, mInputMonitorCompat,
+                        mDeviceState, event);
             }
 
             if (FeatureFlags.ENABLE_QUICK_CAPTURE_GESTURE.get()) {
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java
index 580e4ec..a3cd7df 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java
@@ -44,9 +44,12 @@
 import com.android.quickstep.BaseActivityInterface;
 import com.android.quickstep.GestureState;
 import com.android.quickstep.InputConsumer;
+import com.android.quickstep.RecentsAnimationDeviceState;
 import com.android.quickstep.SystemUiProxy;
 import com.android.systemui.shared.system.InputMonitorCompat;
 
+import java.util.function.Consumer;
+
 /**
  * Touch consumer for handling events to launch assistant from launcher
  */
@@ -81,19 +84,18 @@
     private final int mAngleThreshold;
     private final float mSquaredSlop;
     private final Context mContext;
-    private final GestureDetector mGestureDetector;
-    private final boolean mIsAssistGestureConstrained;
+    private final Consumer<MotionEvent> mGestureDetector;
 
     public AssistantInputConsumer(
             Context context,
             GestureState gestureState,
             InputConsumer delegate,
             InputMonitorCompat inputMonitor,
-            boolean isAssistGestureConstrained) {
+            RecentsAnimationDeviceState deviceState,
+            MotionEvent startEvent) {
         super(delegate, inputMonitor);
         final Resources res = context.getResources();
         mContext = context;
-        mIsAssistGestureConstrained = isAssistGestureConstrained;
         mDragDistThreshold = res.getDimension(R.dimen.gestures_assistant_drag_threshold);
         mFlingDistThreshold = res.getDimension(R.dimen.gestures_assistant_fling_threshold);
         mTimeThreshold = res.getInteger(R.integer.assistant_gesture_min_time_threshold);
@@ -104,7 +106,11 @@
         mSquaredSlop = slop * slop;
         mActivityInterface = gestureState.getActivityInterface();
 
-        mGestureDetector = new GestureDetector(context, new AssistantGestureListener());
+        boolean flingDisabled = deviceState.isAssistantGestureIsConstrained()
+                || deviceState.isInDeferredGestureRegion(startEvent);
+        mGestureDetector = flingDisabled
+                ? ev -> { }
+                : new GestureDetector(context, new AssistantGestureListener())::onTouchEvent;
     }
 
     @Override
@@ -201,7 +207,7 @@
                 break;
         }
 
-        mGestureDetector.onTouchEvent(ev);
+        mGestureDetector.accept(ev);
 
         if (mState != STATE_ACTIVE) {
             mDelegate.onMotionEvent(ev);
@@ -214,12 +220,6 @@
             if (mDistance >= mDragDistThreshold && mTimeFraction >= 1) {
                 SystemUiProxy.INSTANCE.get(mContext).onAssistantGestureCompletion(0);
                 startAssistantInternal();
-
-                Bundle args = new Bundle();
-                args.putInt(OPA_BUNDLE_TRIGGER, OPA_BUNDLE_TRIGGER_DIAG_SWIPE_GESTURE);
-                args.putInt(INVOCATION_TYPE_KEY, INVOCATION_TYPE_GESTURE);
-                SystemUiProxy.INSTANCE.get(mContext).startAssistant(args);
-                mLaunchedAssistant = true;
             } else {
                 SystemUiProxy.INSTANCE.get(mContext).onAssistantProgress(mLastProgress);
             }
@@ -233,6 +233,12 @@
                 13, // HapticFeedbackConstants.GESTURE_END
                 HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
         }
+
+        Bundle args = new Bundle();
+        args.putInt(OPA_BUNDLE_TRIGGER, OPA_BUNDLE_TRIGGER_DIAG_SWIPE_GESTURE);
+        args.putInt(INVOCATION_TYPE_KEY, INVOCATION_TYPE_GESTURE);
+        SystemUiProxy.INSTANCE.get(mContext).startAssistant(args);
+        mLaunchedAssistant = true;
     }
 
     /**
@@ -250,8 +256,7 @@
     private class AssistantGestureListener extends SimpleOnGestureListener {
         @Override
         public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
-            if (!mIsAssistGestureConstrained
-                && isValidAssistantGestureAngle(velocityX, -velocityY)
+            if (isValidAssistantGestureAngle(velocityX, -velocityY)
                     && mDistance >= mFlingDistThreshold
                     && !mLaunchedAssistant
                     && mState != STATE_DELEGATE_ACTIVE) {
@@ -259,11 +264,6 @@
                 SystemUiProxy.INSTANCE.get(mContext).onAssistantGestureCompletion(
                     (float) Math.sqrt(velocityX * velocityX + velocityY * velocityY));
                 startAssistantInternal();
-
-                Bundle args = new Bundle();
-                args.putInt(INVOCATION_TYPE_KEY, INVOCATION_TYPE_GESTURE);
-                SystemUiProxy.INSTANCE.get(mContext).startAssistant(args);
-                mLaunchedAssistant = true;
             }
             return true;
         }
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
index 5aaea00..85ecab1 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
@@ -19,6 +19,7 @@
 import static android.view.MotionEvent.ACTION_POINTER_DOWN;
 import static android.view.MotionEvent.ACTION_UP;
 
+import static com.android.launcher3.Utilities.createHomeIntent;
 import static com.android.launcher3.Utilities.squaredHypot;
 import static com.android.launcher3.Utilities.squaredTouchSlop;
 import static com.android.launcher3.util.VelocityUtils.PX_PER_MS;
@@ -203,9 +204,7 @@
                 public void onAnimationEnd(Animator animation) {
                     if (dismissTask) {
                         // For now, just start the home intent so user is prompted to unlock the device.
-                        mContext.startActivity(new Intent(Intent.ACTION_MAIN)
-                                .addCategory(Intent.CATEGORY_HOME)
-                                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+                        mContext.startActivity(createHomeIntent());
                         mHomeLaunched = true;
                     }
                     mStateCallback.setState(STATE_HANDLER_INVALIDATED);
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OverviewWithoutFocusInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OverviewWithoutFocusInputConsumer.java
index 924b32c..864e08d 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OverviewWithoutFocusInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OverviewWithoutFocusInputConsumer.java
@@ -15,10 +15,12 @@
  */
 package com.android.quickstep.inputconsumers;
 
+import static com.android.launcher3.Utilities.createHomeIntent;
 import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
 import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_GESTURE;
 
+import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.graphics.PointF;
 import android.view.MotionEvent;
@@ -77,7 +79,11 @@
 
     @Override
     public void onSwipeUp(boolean wasFling, PointF finalVelocity) {
-        mContext.startActivity(mGestureState.getHomeIntent());
+        try {
+            mContext.startActivity(mGestureState.getHomeIntent());
+        } catch (NullPointerException | ActivityNotFoundException | SecurityException e) {
+            mContext.startActivity(createHomeIntent());
+        }
         ActiveGestureLog.INSTANCE.addLog("startQuickstep");
         BaseActivity activity = BaseDraggingActivity.fromContext(mContext);
         int state = (mGestureState != null && mGestureState.getEndTarget() != null)
diff --git a/quickstep/src/com/android/quickstep/util/ImageActionUtils.java b/quickstep/src/com/android/quickstep/util/ImageActionUtils.java
index e998e9a..d022085 100644
--- a/quickstep/src/com/android/quickstep/util/ImageActionUtils.java
+++ b/quickstep/src/com/android/quickstep/util/ImageActionUtils.java
@@ -22,15 +22,19 @@
 import static com.android.launcher3.util.Executors.THREAD_POOL_EXECUTOR;
 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
 
+import android.app.prediction.AppTarget;
 import android.content.ClipData;
 import android.content.ClipDescription;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ShortcutInfo;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Insets;
 import android.graphics.Picture;
 import android.graphics.Rect;
+import android.graphics.RectF;
 import android.net.Uri;
 import android.util.Log;
 
@@ -71,6 +75,34 @@
     }
 
     /**
+     * Launch the activity to share image for overview sharing. This is to share cropped bitmap
+     * with specific share targets (with shortcutInfo and appTarget) rendered in overview.
+     */
+    @UiThread
+    public static void shareImage(Context context, Supplier<Bitmap> bitmapSupplier, RectF rectF,
+            ShortcutInfo shortcutInfo, AppTarget appTarget, String tag) {
+        if (bitmapSupplier.get() == null) {
+            return;
+        }
+        Rect crop = new Rect();
+        rectF.round(crop);
+        Intent intent = new Intent();
+        Uri uri =  getImageUri(bitmapSupplier.get(), crop, context, tag);
+        ClipData clipdata = new ClipData(new ClipDescription("content",
+                new String[]{"image/png"}),
+                new ClipData.Item(uri));
+        intent.setAction(Intent.ACTION_SEND)
+            .setComponent(new ComponentName(appTarget.getPackageName(), appTarget.getClassName()))
+            .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+            .addFlags(FLAG_GRANT_READ_URI_PERMISSION)
+            .setType("image/png")
+            .putExtra(Intent.EXTRA_STREAM, uri)
+            .putExtra(Intent.EXTRA_SHORTCUT_ID, shortcutInfo.getId())
+            .setClipData(clipdata);
+        context.startActivity(intent);
+    }
+
+    /**
      * Launch the activity to share image.
      */
     @UiThread
diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
index dd3e31f..a89aaf4 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
@@ -49,6 +49,7 @@
 
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.testing.TestProtocol;
 import com.android.launcher3.touch.PagedOrientationHandler;
@@ -156,7 +157,8 @@
         Resources res = context.getResources();
         int originalSmallestWidth = res.getConfiguration().smallestScreenWidthDp
                 * res.getDisplayMetrics().densityDpi / DENSITY_DEVICE_STABLE;
-        if (originalSmallestWidth < 600) {
+        if (originalSmallestWidth < 600 && !mContext.getResources().getBoolean(
+                R.bool.allow_rotation)) {
             mFlags |= FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_DENSITY;
         }
         mFlags |= FLAG_SWIPE_UP_NOT_RUNNING;
diff --git a/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java b/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java
index 8fbd645..378f25b 100644
--- a/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java
+++ b/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java
@@ -28,6 +28,7 @@
 import android.util.Log;
 import android.view.Surface;
 import android.view.SurfaceControl;
+import android.view.View;
 
 import androidx.annotation.NonNull;
 
@@ -91,7 +92,8 @@
             @NonNull Rect sourceRectHint,
             @NonNull Rect appBounds,
             @NonNull Rect startBounds,
-            @NonNull Rect destinationBounds) {
+            @NonNull Rect destinationBounds,
+            @NonNull View view) {
         mTaskId = taskId;
         mComponentName = componentName;
         mLeash = leash;
@@ -110,7 +112,7 @@
         addListener(new AnimationSuccessListener() {
             @Override
             public void onAnimationStart(Animator animation) {
-                InteractionJankMonitorWrapper.begin(CUJ_APP_CLOSE_TO_PIP);
+                InteractionJankMonitorWrapper.begin(view, CUJ_APP_CLOSE_TO_PIP);
                 super.onAnimationStart(animation);
             }
 
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index b9e0f62..475953b 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -23,6 +23,7 @@
 import static com.android.launcher3.tapl.TestHelpers.getHomeIntentInPackage;
 import static com.android.launcher3.tapl.TestHelpers.getLauncherInMyProcess;
 import static com.android.launcher3.ui.AbstractLauncherUiTest.DEFAULT_ACTIVITY_TIMEOUT;
+import static com.android.launcher3.ui.AbstractLauncherUiTest.DEFAULT_BROADCAST_TIMEOUT_SECS;
 import static com.android.launcher3.ui.AbstractLauncherUiTest.DEFAULT_UI_TIMEOUT;
 import static com.android.launcher3.ui.AbstractLauncherUiTest.resolveSystemApp;
 import static com.android.launcher3.ui.AbstractLauncherUiTest.startAppFast;
@@ -66,6 +67,8 @@
 import org.junit.runner.RunWith;
 import org.junit.runners.model.Statement;
 
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 import java.util.function.Consumer;
 import java.util.function.Function;
 
@@ -112,11 +115,16 @@
             @Override
             public void evaluate() throws Throwable {
                 TestCommandReceiver.callCommand(TestCommandReceiver.ENABLE_TEST_LAUNCHER);
+                OverviewUpdateHandler updateHandler =
+                        MAIN_EXECUTOR.submit(OverviewUpdateHandler::new).get();
                 UiDevice.getInstance(getInstrumentation()).executeShellCommand(
                         getLauncherCommand(mOtherLauncherActivity));
+                updateHandler.mChangeCounter
+                        .await(DEFAULT_BROADCAST_TIMEOUT_SECS, TimeUnit.SECONDS);
                 try {
                     base.evaluate();
                 } finally {
+                    MAIN_EXECUTOR.submit(updateHandler::destroy).get();
                     TestCommandReceiver.callCommand(TestCommandReceiver.DISABLE_TEST_LAUNCHER);
                     UiDevice.getInstance(getInstrumentation()).executeShellCommand(
                             getLauncherCommand(getLauncherInMyProcess()));
@@ -241,4 +249,30 @@
     private int getTaskCount(RecentsActivity recents) {
         return recents.<RecentsView>getOverviewPanel().getTaskViewCount();
     }
+
+    private class OverviewUpdateHandler {
+
+        final RecentsAnimationDeviceState mRads;
+        final OverviewComponentObserver mObserver;
+        final CountDownLatch mChangeCounter;
+
+        OverviewUpdateHandler() {
+            Context ctx = getInstrumentation().getTargetContext();
+            mRads = new RecentsAnimationDeviceState(ctx);
+            mObserver = new OverviewComponentObserver(ctx, mRads);
+            mChangeCounter = new CountDownLatch(1);
+            if (mObserver.getHomeIntent().getComponent()
+                    .getPackageName().equals(mOtherLauncherActivity.packageName)) {
+                // Home already same
+                mChangeCounter.countDown();
+            } else {
+                mObserver.setOverviewChangeListener(b -> mChangeCounter.countDown());
+            }
+        }
+
+        void destroy() {
+            mObserver.onDestroy();
+            mRads.destroy();
+        }
+    }
 }
diff --git a/res/layout/launcher_preview_layout.xml b/res/layout/launcher_preview_layout.xml
index 4a20c70..1691680 100644
--- a/res/layout/launcher_preview_layout.xml
+++ b/res/layout/launcher_preview_layout.xml
@@ -29,23 +29,8 @@
         launcher:containerType="workspace"
         launcher:pageIndicator="@+id/page_indicator"/>
 
-    <com.android.launcher3.Hotseat
+    <include
         android:id="@+id/hotseat"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:importantForAccessibility="no"
-        android:theme="@style/HomeScreenElementTheme"
-        launcher:containerType="hotseat" />
-
-    <com.android.launcher3.InsettableFrameLayout
-        android:id="@+id/apps_view"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent" >
-
-        <include
-            android:id="@id/search_container_all_apps"
-            layout="@layout/search_container_all_apps"/>
-
-    </com.android.launcher3.InsettableFrameLayout>
+        layout="@layout/hotseat" />
 
 </com.android.launcher3.InsettableFrameLayout>
\ No newline at end of file
diff --git a/robolectric_tests/src/com/android/launcher3/util/LauncherUIHelper.java b/robolectric_tests/src/com/android/launcher3/util/LauncherUIHelper.java
index f019a20..fdddab4 100644
--- a/robolectric_tests/src/com/android/launcher3/util/LauncherUIHelper.java
+++ b/robolectric_tests/src/com/android/launcher3/util/LauncherUIHelper.java
@@ -18,6 +18,8 @@
 import static android.view.View.MeasureSpec.EXACTLY;
 import static android.view.View.MeasureSpec.makeMeasureSpec;
 
+import static com.android.launcher3.Utilities.createHomeIntent;
+
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
@@ -46,10 +48,7 @@
      */
     public static String getLauncherClassName() {
         Context context = RuntimeEnvironment.application;
-        Intent homeIntent = new Intent(Intent.ACTION_MAIN)
-                .addCategory(Intent.CATEGORY_HOME)
-                .setPackage(context.getPackageName())
-                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        Intent homeIntent = createHomeIntent().setPackage(context.getPackageName());
 
         List<ResolveInfo> launchers = context.getPackageManager()
                 .queryIntentActivities(homeIntent, 0);
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index 52f0a4a..5bfde15 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -43,6 +43,9 @@
 import androidx.annotation.Nullable;
 
 import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.allapps.AllAppsContainerView;
+import com.android.launcher3.allapps.search.DefaultSearchAdapterProvider;
+import com.android.launcher3.allapps.search.SearchAdapterProvider;
 import com.android.launcher3.logging.InstanceId;
 import com.android.launcher3.logging.InstanceIdSequence;
 import com.android.launcher3.model.data.ItemInfo;
@@ -187,7 +190,7 @@
                 logAppLaunch(item, instanceId);
             }
             return true;
-        } catch (NullPointerException|ActivityNotFoundException|SecurityException e) {
+        } catch (NullPointerException | ActivityNotFoundException | SecurityException e) {
             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
             Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
         }
@@ -290,4 +293,12 @@
         display.getSize(mwSize);
         return new WindowBounds(new Rect(0, 0, mwSize.x, mwSize.y), new Rect());
     }
+
+    /**
+     * Creates and returns {@link SearchAdapterProvider} for build variant specific search result
+     * views
+     */
+    public SearchAdapterProvider createSearchAdapterProvider(AllAppsContainerView allapps) {
+        return new DefaultSearchAdapterProvider(this);
+    }
 }
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 5b55c4b..0274775 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -1596,6 +1596,7 @@
 
         mOverlayManager.onActivityDestroyed(this);
         mAppTransitionManager.unregisterRemoteAnimations();
+        mAppTransitionManager.unregisterRemoteTransitions();
         mUserChangedCallbackCloseable.close();
         mLifecycleRegistry.setCurrentState(Lifecycle.State.DESTROYED);
         mLiveSearchManager.stop();
diff --git a/src/com/android/launcher3/LauncherAppTransitionManager.java b/src/com/android/launcher3/LauncherAppTransitionManager.java
index 24e0d14..ac3ad9f 100644
--- a/src/com/android/launcher3/LauncherAppTransitionManager.java
+++ b/src/com/android/launcher3/LauncherAppTransitionManager.java
@@ -67,4 +67,18 @@
     public void unregisterRemoteAnimations() {
         // Do nothing
     }
+
+    /**
+     * Registers remote transitions for certain system transitions.
+     */
+    public void registerRemoteTransitions() {
+        // Do nothing
+    }
+
+    /**
+     * Unregisters all remote transitions.
+     */
+    public void unregisterRemoteTransitions() {
+        // Do nothing
+    }
 }
diff --git a/src/com/android/launcher3/ResourceUtils.java b/src/com/android/launcher3/ResourceUtils.java
index c9fb75a..f60e1f8 100644
--- a/src/com/android/launcher3/ResourceUtils.java
+++ b/src/com/android/launcher3/ResourceUtils.java
@@ -25,6 +25,8 @@
     public static final int INVALID_RESOURCE_HANDLE = -1;
     public static final String NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE = "navigation_bar_width";
     public static final String NAVBAR_BOTTOM_GESTURE_SIZE = "navigation_bar_gesture_height";
+    public static final String NAVBAR_BOTTOM_GESTURE_LARGER_SIZE =
+            "navigation_bar_gesture_larger_height";
 
     public static int getNavbarSize(String resName, Resources res) {
         return getDimenByName(resName, res, DEFAULT_NAVBAR_VALUE);
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index df5d234..8066aa6 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -461,6 +461,15 @@
     }
 
     /**
+     * Returns an intent for starting the default home activity
+     */
+    public static Intent createHomeIntent() {
+        return new Intent(Intent.ACTION_MAIN)
+                .addCategory(Intent.CATEGORY_HOME)
+                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+    }
+
+    /**
      * Wraps a message with a TTS span, so that a different message is spoken than
      * what is getting displayed.
      * @param msg original message
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 558c6a8..4d51d70 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -16,7 +16,6 @@
 package com.android.launcher3.allapps;
 
 import static com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItem;
-import static com.android.launcher3.allapps.AllAppsGridAdapter.SearchAdapterItem;
 import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_HAS_SHORTCUT_PERMISSION;
 import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_CHANGE_PERMISSION;
 import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_ENABLED;
@@ -57,7 +56,7 @@
 import com.android.launcher3.InsettableFrameLayout;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
-import com.android.launcher3.allapps.search.SearchEventTracker;
+import com.android.launcher3.allapps.search.SearchAdapterProvider;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.keyboard.FocusedItemDecorator;
 import com.android.launcher3.model.data.AppInfo;
@@ -68,7 +67,6 @@
 import com.android.launcher3.util.Themes;
 import com.android.launcher3.views.RecyclerViewFastScroller;
 import com.android.launcher3.views.SpringRelativeLayout;
-import com.android.systemui.plugins.shared.SearchTarget;
 
 /**
  * The all apps view container.
@@ -110,6 +108,8 @@
 
     private Rect mInsets = new Rect();
 
+    SearchAdapterProvider mSearchAdapterProvider;
+
     public AllAppsContainerView(Context context) {
         this(context, null);
     }
@@ -124,6 +124,7 @@
         mLauncher = BaseDraggingActivity.fromContext(context);
         mLauncher.addOnDeviceProfileChangeListener(this);
 
+        mSearchAdapterProvider = mLauncher.createSearchAdapterProvider(this);
         mSearchQueryBuilder = new SpannableStringBuilder();
         Selection.setSelection(mSearchQueryBuilder, 0);
 
@@ -141,6 +142,7 @@
         addSpringView(R.id.all_apps_tabs_view_pager);
 
         mMultiValueAlpha = new MultiValueAlpha(this, ALPHA_CHANNEL_COUNT);
+
     }
 
     /**
@@ -545,9 +547,7 @@
             return mLauncher.startActivitySafely(v, headerItem.getIntent(), headerItem);
         }
         AdapterItem focusedItem = getActiveRecyclerView().getApps().getFocusedChild();
-        if (focusedItem instanceof SearchAdapterItem) {
-            SearchTarget searchTarget = ((SearchAdapterItem) focusedItem).getSearchTarget();
-            SearchEventTracker.INSTANCE.get(getContext()).quickSelect(searchTarget);
+        if (mSearchAdapterProvider.onAdapterItemSelected(focusedItem)) {
             return true;
         }
         if (focusedItem.appInfo != null) {
@@ -569,6 +569,10 @@
         return null;
     }
 
+    public SearchAdapterProvider getSearchAdapterProvider() {
+        return mSearchAdapterProvider;
+    }
+
     public RecyclerViewFastScroller getScrollBar() {
         AllAppsRecyclerView rv = getActiveRecyclerView();
         return rv == null ? null : rv.getScrollbar();
@@ -677,7 +681,8 @@
         AdapterHolder(boolean isWork) {
             mIsWork = isWork;
             appsList = new AlphabeticalAppsList(mLauncher, mAllAppsStore, isWork);
-            adapter = new AllAppsGridAdapter(mLauncher, getLayoutInflater(), appsList);
+            adapter = new AllAppsGridAdapter(mLauncher, getLayoutInflater(), appsList,
+                    mSearchAdapterProvider);
             appsList.setAdapter(adapter);
             layoutManager = adapter.getLayoutManager();
         }
diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
index 3c88288..715c142 100644
--- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
+++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
@@ -41,13 +41,11 @@
 import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.BubbleTextView;
 import com.android.launcher3.R;
-import com.android.launcher3.allapps.search.AllAppsSearchBarController.SearchTargetHandler;
+import com.android.launcher3.allapps.search.SearchAdapterProvider;
 import com.android.launcher3.allapps.search.SearchSectionInfo;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.model.data.AppInfo;
 import com.android.launcher3.util.PackageManagerHelper;
-import com.android.launcher3.views.SearchResultWidget;
-import com.android.systemui.plugins.shared.SearchTarget;
 
 import java.util.List;
 
@@ -72,31 +70,11 @@
     // 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_ROW_WITH_BUTTON = 1 << 7;
-
-    public static final int VIEW_TYPE_SEARCH_ROW = 1 << 8;
-
-    public static final int VIEW_TYPE_SEARCH_SLICE = 1 << 9;
-
-    public static final int VIEW_TYPE_SEARCH_ICON_ROW = 1 << 10;
-
-    public static final int VIEW_TYPE_SEARCH_PEOPLE = 1 << 11;
-
-    public static final int VIEW_TYPE_SEARCH_THUMBNAIL = 1 << 12;
-
-    public static final int VIEW_TYPE_SEARCH_SUGGEST = 1 << 13;
-
-    public static final int VIEW_TYPE_SEARCH_ICON = 1 << 14;
-
-    public static final int VIEW_TYPE_SEARCH_WIDGET_LIVE = 1 << 15;
-
-    public static final int VIEW_TYPE_SEARCH_WIDGET_PREVIEW = 1 << 16;
-
     // Common view type masks
     public static final int VIEW_TYPE_MASK_DIVIDER = VIEW_TYPE_ALL_APPS_DIVIDER;
-    public static final int VIEW_TYPE_MASK_ICON = VIEW_TYPE_ICON | VIEW_TYPE_SEARCH_ICON;
+    public static final int VIEW_TYPE_MASK_ICON = VIEW_TYPE_ICON;
+
+    private final SearchAdapterProvider mSearchAdapterProvider;
 
     /**
      * ViewHolder for each icon.
@@ -177,32 +155,8 @@
             return item;
         }
 
-        boolean isCountedForAccessibility() {
-            return viewType == VIEW_TYPE_ICON
-                    || viewType == VIEW_TYPE_SEARCH_ROW_WITH_BUTTON
-                    || viewType == VIEW_TYPE_SEARCH_SLICE
-                    || viewType == VIEW_TYPE_SEARCH_ROW
-                    || viewType == VIEW_TYPE_SEARCH_PEOPLE
-                    || viewType == VIEW_TYPE_SEARCH_THUMBNAIL
-                    || viewType == VIEW_TYPE_SEARCH_ICON_ROW
-                    || viewType == VIEW_TYPE_SEARCH_ICON
-                    || viewType == VIEW_TYPE_SEARCH_SUGGEST;
-        }
-    }
-
-    /**
-     * Extension of AdapterItem that contains an extra payload specific to item
-     */
-    public static class SearchAdapterItem extends AdapterItem {
-        private SearchTarget mSearchTarget;
-
-        public SearchAdapterItem(SearchTarget searchTarget, int type) {
-            mSearchTarget = searchTarget;
-            viewType = type;
-        }
-
-        public SearchTarget getSearchTarget() {
-            return mSearchTarget;
+        protected boolean isCountedForAccessibility() {
+            return viewType == VIEW_TYPE_ICON || viewType == VIEW_TYPE_SEARCH_MARKET;
         }
     }
 
@@ -289,9 +243,8 @@
             int viewType = mApps.getAdapterItems().get(position).viewType;
             if (isIconViewType(viewType)) {
                 return 1 * SPAN_MULTIPLIER;
-            } else if (viewType == VIEW_TYPE_SEARCH_THUMBNAIL
-                    || viewType == VIEW_TYPE_SEARCH_WIDGET_PREVIEW) {
-                return mAppsPerRow;
+            } else if (mSearchAdapterProvider.isSearchView(viewType)) {
+                return mSearchAdapterProvider.getGridSpanSize(viewType, mAppsPerRow);
             } else {
                 // Section breaks span the full width
                 return mAppsPerRow * SPAN_MULTIPLIER;
@@ -321,7 +274,7 @@
     private Intent mMarketSearchIntent;
 
     public AllAppsGridAdapter(BaseDraggingActivity launcher, LayoutInflater inflater,
-            AlphabeticalAppsList apps) {
+            AlphabeticalAppsList apps, SearchAdapterProvider searchAdapterProvider) {
         Resources res = launcher.getResources();
         mLauncher = launcher;
         mApps = apps;
@@ -334,6 +287,8 @@
         mOnIconClickListener = launcher.getItemOnClickListener();
 
         setAppsPerRow(mLauncher.getDeviceProfile().inv.numAllAppsColumns);
+
+        mSearchAdapterProvider = searchAdapterProvider;
     }
 
     public void setAppsPerRow(int appsPerRow) {
@@ -406,40 +361,11 @@
             case VIEW_TYPE_ALL_APPS_DIVIDER:
                 return new ViewHolder(mLayoutInflater.inflate(
                         R.layout.all_apps_divider, parent, false));
-            case VIEW_TYPE_SEARCH_ICON:
-                return new ViewHolder(mLayoutInflater.inflate(
-                        R.layout.search_result_icon, parent, false));
-            case VIEW_TYPE_SEARCH_CORPUS_TITLE:
-                return new ViewHolder(
-                        mLayoutInflater.inflate(R.layout.search_section_title, parent, false));
-            case VIEW_TYPE_SEARCH_ROW_WITH_BUTTON:
-                return new ViewHolder(mLayoutInflater.inflate(
-                        R.layout.search_result_play_item, parent, false));
-            case VIEW_TYPE_SEARCH_ROW:
-                return new ViewHolder(mLayoutInflater.inflate(
-                        R.layout.search_result_settings_row, parent, false));
-            case VIEW_TYPE_SEARCH_SLICE:
-                return new ViewHolder(mLayoutInflater.inflate(
-                        R.layout.search_result_slice, parent, false));
-            case VIEW_TYPE_SEARCH_ICON_ROW:
-                return new ViewHolder(mLayoutInflater.inflate(
-                        R.layout.search_result_icon_row, parent, false));
-            case VIEW_TYPE_SEARCH_PEOPLE:
-                return new ViewHolder(mLayoutInflater.inflate(
-                        R.layout.search_result_people_item, parent, false));
-            case VIEW_TYPE_SEARCH_THUMBNAIL:
-                return new ViewHolder(mLayoutInflater.inflate(
-                        R.layout.search_result_thumbnail, parent, false));
-            case VIEW_TYPE_SEARCH_SUGGEST:
-                return new ViewHolder(mLayoutInflater.inflate(
-                        R.layout.search_result_suggest, parent, false));
-            case VIEW_TYPE_SEARCH_WIDGET_LIVE:
-                return new ViewHolder(mLayoutInflater.inflate(
-                        R.layout.search_result_widget_live, parent, false));
-            case VIEW_TYPE_SEARCH_WIDGET_PREVIEW:
-                return new ViewHolder(mLayoutInflater.inflate(
-                        R.layout.search_result_widget_preview, parent, false));
             default:
+                if (mSearchAdapterProvider.isSearchView(viewType)) {
+                    return mSearchAdapterProvider.onCreateViewHolder(mLayoutInflater, parent,
+                            viewType);
+                }
                 throw new RuntimeException("Unexpected view type");
         }
     }
@@ -472,25 +398,11 @@
                     searchView.setVisibility(View.GONE);
                 }
                 break;
-            case VIEW_TYPE_SEARCH_CORPUS_TITLE:
-            case VIEW_TYPE_SEARCH_ROW_WITH_BUTTON:
-            case VIEW_TYPE_SEARCH_SLICE:
-            case VIEW_TYPE_SEARCH_ROW:
-            case VIEW_TYPE_SEARCH_ICON:
-            case VIEW_TYPE_SEARCH_ICON_ROW:
-            case VIEW_TYPE_SEARCH_PEOPLE:
-            case VIEW_TYPE_SEARCH_THUMBNAIL:
-            case VIEW_TYPE_SEARCH_SUGGEST:
-            case VIEW_TYPE_SEARCH_WIDGET_LIVE:
-            case VIEW_TYPE_SEARCH_WIDGET_PREVIEW:
-                SearchAdapterItem item =
-                        (SearchAdapterItem) mApps.getAdapterItems().get(position);
-                SearchTargetHandler payloadResultView = (SearchTargetHandler) holder.itemView;
-                payloadResultView.applySearchTarget(item.getSearchTarget());
-                break;
             case VIEW_TYPE_ALL_APPS_DIVIDER:
                 // nothing to do
                 break;
+            default:
+                mSearchAdapterProvider.onBindView(holder, position);
         }
     }
 
@@ -501,9 +413,6 @@
         if (holder.itemView instanceof AllAppsSectionDecorator.SelfDecoratingView) {
             ((AllAppsSectionDecorator.SelfDecoratingView) holder.itemView).removeDecoration();
         }
-        if (holder.itemView instanceof SearchResultWidget) {
-            ((SearchResultWidget) holder.itemView).removeListener();
-        }
     }
 
     @Override
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index 1fa43d0..e61b95d 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -104,7 +104,6 @@
         pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_ALL_APPS_DIVIDER, 1);
         pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_SEARCH_MARKET, 1);
         pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_ICON, approxRows * mNumAppsPerRow);
-        pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_SEARCH_CORPUS_TITLE, 1);
 
         mViewHeights.clear();
         mViewHeights.put(AllAppsGridAdapter.VIEW_TYPE_ICON, grid.allAppsCellHeightPx);
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index f9ab196..c03619e 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -142,7 +142,8 @@
         float shiftCurrent = progress * mShiftRange;
 
         mAppsView.setTranslationY(shiftCurrent);
-        if (FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
+        if (FeatureFlags.ENABLE_DEVICE_SEARCH.get()
+                && !FeatureFlags.DISABLE_INITIAL_IME_IN_ALLAPPS.get()) {
             mInsetController.setProgress(progress);
         }
     }
@@ -233,7 +234,9 @@
     public void setupViews(AllAppsContainerView appsView, ScrimView scrimView) {
         mAppsView = appsView;
         mScrimView = scrimView;
-        if (FeatureFlags.ENABLE_DEVICE_SEARCH.get() && BuildCompat.isAtLeastR()) {
+        if (FeatureFlags.ENABLE_DEVICE_SEARCH.get()
+                && !FeatureFlags.DISABLE_INITIAL_IME_IN_ALLAPPS.get()
+                && BuildCompat.isAtLeastR()) {
             mInsetController = new AllAppsInsetTransitionController(mShiftRange, mAppsView);
             mLauncher.getSystemUiController().updateUiState(UI_STATE_ALLAPPS,
                     View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
@@ -261,7 +264,8 @@
         if (Float.compare(mProgress, 1f) == 0) {
             mAppsView.reset(false /* animate */);
         }
-        if (FeatureFlags.ENABLE_DEVICE_SEARCH.get() && BuildCompat.isAtLeastR()) {
+        if (FeatureFlags.ENABLE_DEVICE_SEARCH.get()
+                && !FeatureFlags.DISABLE_INITIAL_IME_IN_ALLAPPS.get() && BuildCompat.isAtLeastR()) {
             mInsetController.onAnimationEnd(mProgress);
             if (Float.compare(mProgress, 0f) == 0) {
                 mLauncher.getLiveSearchManager().start();
diff --git a/src/com/android/launcher3/allapps/SearchUiManager.java b/src/com/android/launcher3/allapps/SearchUiManager.java
index aa056a0..f926086 100644
--- a/src/com/android/launcher3/allapps/SearchUiManager.java
+++ b/src/com/android/launcher3/allapps/SearchUiManager.java
@@ -59,6 +59,11 @@
             Interpolator interpolator);
 
     /**
+     * Called when activity is destroyed. Used to close search system services
+     */
+    default void destroy(){}
+
+    /**
      * Returns true if the QSB should be visible for the given set of visible elements
      */
     default boolean isQsbVisible(int visibleElements) {
diff --git a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
index bc5a5f2..522f1d4 100644
--- a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
+++ b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
@@ -15,7 +15,6 @@
  */
 package com.android.launcher3.allapps.search;
 
-import android.os.Bundle;
 import android.text.Editable;
 import android.text.TextUtils;
 import android.text.TextWatcher;
@@ -34,10 +33,8 @@
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.util.PackageManagerHelper;
 import com.android.systemui.plugins.AllAppsSearchPlugin;
-import com.android.systemui.plugins.shared.SearchTarget;
 
 import java.util.ArrayList;
-import java.util.List;
 import java.util.function.Consumer;
 
 /**
@@ -63,7 +60,7 @@
      */
     public final void initialize(
             SearchAlgorithm searchAlgorithm, ExtendedEditText input,
-            BaseDraggingActivity launcher, Callbacks cb, Consumer<List<Bundle>> secondaryCb) {
+            BaseDraggingActivity launcher, Callbacks cb) {
         mCb = cb;
         mLauncher = launcher;
 
@@ -211,23 +208,5 @@
         void clearSearchResult();
     }
 
-    /**
-     * An interface for supporting dynamic search results
-     */
-    public interface SearchTargetHandler {
-
-        /**
-         * Update view using values from {@link SearchTarget}
-         */
-        void applySearchTarget(SearchTarget searchTarget);
-
-        /**
-         * Handles selection of SearchTarget
-         */
-        default void handleSelection(int eventType) {
-        }
-
-    }
-
 
 }
\ No newline at end of file
diff --git a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
index bd2f04d..4f79fb8 100644
--- a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
+++ b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
@@ -24,7 +24,6 @@
 
 import android.content.Context;
 import android.graphics.Rect;
-import android.os.Bundle;
 import android.text.Selection;
 import android.text.SpannableStringBuilder;
 import android.text.method.TextKeyListener;
@@ -50,15 +49,13 @@
 import com.android.launcher3.config.FeatureFlags;
 
 import java.util.ArrayList;
-import java.util.List;
-import java.util.function.Consumer;
 
 /**
  * Layout to contain the All-apps search UI.
  */
 public class AppsSearchContainerLayout extends ExtendedEditText
         implements SearchUiManager, AllAppsSearchBarController.Callbacks,
-        AllAppsStore.OnUpdateListener, Insettable, Consumer<List<Bundle>> {
+        AllAppsStore.OnUpdateListener, Insettable {
 
     private final BaseDraggingActivity mLauncher;
     private final AllAppsSearchBarController mSearchBarController;
@@ -141,7 +138,7 @@
         mAppsView = appsView;
         mSearchBarController.initialize(
                 new DefaultAppSearchAlgorithm(mLauncher, LauncherAppState.getInstance(mLauncher)),
-                this, mLauncher, this, this);
+                this, mLauncher, this);
     }
 
     @Override
@@ -234,9 +231,4 @@
     public EditText getEditText() {
         return this;
     }
-
-    @Override
-    public void accept(List<Bundle> bundles) {
-        // TODO: Render the result on mAppsView object
-    }
 }
diff --git a/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java b/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java
new file mode 100644
index 0000000..e3c178b
--- /dev/null
+++ b/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java
@@ -0,0 +1,53 @@
+/*
+ * 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.allapps.search;
+
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+
+import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.allapps.AllAppsGridAdapter;
+
+/**
+ * Provides views for local search results
+ */
+public class DefaultSearchAdapterProvider extends SearchAdapterProvider {
+
+    public DefaultSearchAdapterProvider(BaseDraggingActivity launcher) {
+        super(launcher);
+    }
+
+    @Override
+    public void onBindView(AllAppsGridAdapter.ViewHolder holder, int position) {
+
+    }
+
+    @Override
+    public boolean isSearchView(int viewType) {
+        return false;
+    }
+
+    @Override
+    public AllAppsGridAdapter.ViewHolder onCreateViewHolder(LayoutInflater layoutInflater,
+            ViewGroup parent, int viewType) {
+        return null;
+    }
+
+    @Override
+    public boolean onAdapterItemSelected(AllAppsGridAdapter.AdapterItem focusedItem) {
+        return false;
+    }
+}
diff --git a/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java b/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java
new file mode 100644
index 0000000..1c7247a
--- /dev/null
+++ b/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java
@@ -0,0 +1,65 @@
+/*
+ * 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.allapps.search;
+
+
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+
+import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.allapps.AllAppsGridAdapter;
+
+/**
+ * A UI expansion wrapper providing for search results
+ */
+public abstract class SearchAdapterProvider {
+
+    protected final BaseDraggingActivity mLauncher;
+
+    public SearchAdapterProvider(BaseDraggingActivity launcher) {
+        mLauncher = launcher;
+    }
+
+    /**
+     * Called from RecyclerView.Adapter#onBindViewHolder
+     */
+    public abstract void onBindView(AllAppsGridAdapter.ViewHolder holder, int position);
+
+    /**
+     * Returns whether or not viewType can be handled by searchProvider
+     */
+    public abstract boolean isSearchView(int viewType);
+
+    /**
+     * Called from RecyclerView.Adapter#onCreateViewHolder
+     */
+    public abstract AllAppsGridAdapter.ViewHolder onCreateViewHolder(LayoutInflater layoutInflater,
+            ViewGroup parent, int viewType);
+
+    /**
+     * Returns how many cells a view should span
+     */
+    public int getGridSpanSize(int viewType, int appsPerRow) {
+        return appsPerRow * AllAppsGridAdapter.SPAN_MULTIPLIER;
+    }
+
+    /**
+     * handles selection event on search adapter item. Returns false if provider can not handle
+     * event
+     */
+    public abstract boolean onAdapterItemSelected(AllAppsGridAdapter.AdapterItem focusedItem);
+}
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 68641d9..81174d8 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -98,6 +98,12 @@
     public static final BooleanFlag ENABLE_DEVICE_SEARCH = getDebugFlag(
             "ENABLE_DEVICE_SEARCH", false, "Allows on device search in all apps");
 
+    public static final BooleanFlag USE_SEARCH_API = getDebugFlag(
+            "USE_SEARCH_API", true, "Use SearchUIManager api for device search");
+
+    public static final BooleanFlag DISABLE_INITIAL_IME_IN_ALLAPPS = getDebugFlag(
+            "DISABLE_INITIAL_IME_IN_ALLAPPS", false, "Disable default IME state in all apps");
+
     public static final BooleanFlag FOLDER_NAME_SUGGEST = new DeviceFlag(
             "FOLDER_NAME_SUGGEST", true,
             "Suggests folder names instead of blank text.");
diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
index efc1201..3a9986e 100644
--- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
+++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
@@ -64,7 +64,6 @@
 import com.android.launcher3.LauncherSettings.Favorites;
 import com.android.launcher3.R;
 import com.android.launcher3.WorkspaceLayoutManager;
-import com.android.launcher3.allapps.SearchUiManager;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.folder.FolderIcon;
 import com.android.launcher3.icons.BaseIconFactory;
@@ -512,16 +511,6 @@
             mWorkspace.addViewToCellLayout(qsb, 0, R.id.search_container_workspace, lp, true);
         }
 
-        // Setup search view
-        SearchUiManager searchUiManager = mRootView.findViewById(R.id.search_container_all_apps);
-        mRootView.findViewById(R.id.apps_view).setTranslationY(
-                mDp.heightPx - searchUiManager.getScrollRangeDelta(mInsets));
-        ViewGroup searchView = (ViewGroup) searchUiManager;
-        searchView.setEnabled(false);
-        for (int i = 0; i < searchView.getChildCount(); i++) {
-            searchView.getChildAt(i).setEnabled(false);
-        }
-
         measureView(mRootView, mDp.widthPx, mDp.heightPx);
         dispatchVisibilityAggregated(mRootView, true);
         measureView(mRootView, mDp.widthPx, mDp.heightPx);
diff --git a/src/com/android/launcher3/model/AllAppsList.java b/src/com/android/launcher3/model/AllAppsList.java
index 8d5cf74..c57c3e4 100644
--- a/src/com/android/launcher3/model/AllAppsList.java
+++ b/src/com/android/launcher3/model/AllAppsList.java
@@ -26,6 +26,7 @@
 import android.content.pm.LauncherActivityInfo;
 import android.content.pm.LauncherApps;
 import android.os.LocaleList;
+import android.os.Process;
 import android.os.UserHandle;
 import android.util.Log;
 
@@ -161,14 +162,18 @@
     /** Updates the given PackageInstallInfo's associated AppInfo's installation info. */
     public List<AppInfo> updatePromiseInstallInfo(PackageInstallInfo installInfo) {
         List<AppInfo> updatedAppInfos = new ArrayList<>();
-        UserHandle user = installInfo.user;
+        UserHandle user = Process.myUserHandle();
         for (int i = data.size() - 1; i >= 0; i--) {
             final AppInfo appInfo = data.get(i);
             final ComponentName tgtComp = appInfo.getTargetComponent();
             if (tgtComp != null && tgtComp.getPackageName().equals(installInfo.packageName)
                     && appInfo.user.equals(user)) {
                 if (installInfo.state == PackageInstallInfo.STATUS_INSTALLED_DOWNLOADING
-                            || installInfo.state == PackageInstallInfo.STATUS_INSTALLING) {
+                        || installInfo.state == PackageInstallInfo.STATUS_INSTALLING) {
+                    if (appInfo.isAppStartable()
+                            && installInfo.state == PackageInstallInfo.STATUS_INSTALLING) {
+                        continue;
+                    }
                     appInfo.setProgressLevel(installInfo);
 
                     updatedAppInfos.add(appInfo);
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index 896bfb6..3275d59 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -38,6 +38,7 @@
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.pm.PackageInstallInfo;
 import com.android.launcher3.pm.UserCache;
 import com.android.launcher3.shortcuts.ShortcutRequest;
 import com.android.launcher3.util.FlagOp;
@@ -246,6 +247,7 @@
 
                         if (isNewApkAvailable
                                 && si.itemType == Favorites.ITEM_TYPE_APPLICATION) {
+                            si.setProgressLevel(100, PackageInstallInfo.STATUS_INSTALLED);
                             iconCache.getTitleAndIcon(si, si.usingLowResIcon());
                             infoUpdated = true;
                         }
diff --git a/src/com/android/launcher3/model/data/AppInfo.java b/src/com/android/launcher3/model/data/AppInfo.java
index 39247c2..dde0cf4 100644
--- a/src/com/android/launcher3/model/data/AppInfo.java
+++ b/src/com/android/launcher3/model/data/AppInfo.java
@@ -94,8 +94,6 @@
         componentName = info.componentName;
         title = Utilities.trim(info.title);
         intent = new Intent(info.intent);
-        user = info.user;
-        runtimeStatusFlags = info.runtimeStatusFlags;
     }
 
     @VisibleForTesting
@@ -114,6 +112,7 @@
             .setComponent(componentName)
             .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+        setProgressLevel(installInfo);
         user = installInfo.user;
     }
 
diff --git a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
index b8a71d3..d95e708 100644
--- a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
+++ b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
@@ -129,7 +129,9 @@
     protected ItemInfoWithIcon(ItemInfoWithIcon info) {
         super(info);
         bitmap = info.bitmap;
+        mProgressLevel = info.mProgressLevel;
         runtimeStatusFlags = info.runtimeStatusFlags;
+        user = info.user;
     }
 
     @Override
@@ -195,8 +197,8 @@
                     : runtimeStatusFlags & ~FLAG_INCREMENTAL_DOWNLOAD_ACTIVE;
         } else {
             mProgressLevel = status == PackageInstallInfo.STATUS_INSTALLED ? 100 : 0;
-            runtimeStatusFlags = runtimeStatusFlags & ~FLAG_INSTALL_SESSION_ACTIVE;
-            runtimeStatusFlags = runtimeStatusFlags & ~FLAG_INCREMENTAL_DOWNLOAD_ACTIVE;
+            runtimeStatusFlags &= ~FLAG_INSTALL_SESSION_ACTIVE;
+            runtimeStatusFlags &= ~FLAG_INCREMENTAL_DOWNLOAD_ACTIVE;
         }
     }
 
diff --git a/src/com/android/launcher3/states/RotationHelper.java b/src/com/android/launcher3/states/RotationHelper.java
index ecf4f36..ba28e82 100644
--- a/src/com/android/launcher3/states/RotationHelper.java
+++ b/src/com/android/launcher3/states/RotationHelper.java
@@ -51,7 +51,7 @@
     public static final int REQUEST_ROTATE = 1;
     public static final int REQUEST_LOCK = 2;
 
-    private final Activity mActivity;
+    private Activity mActivity;
     private final SharedPreferences mSharedPrefs;
 
     private boolean mIgnoreAutoRotateSettings;
@@ -95,6 +95,7 @@
 
     @Override
     public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
+        if (mDestroyed) return;
         boolean wasRotationEnabled = mHomeRotationEnabled;
         mHomeRotationEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
                 getAllowRotationDefaultValue());
@@ -141,6 +142,7 @@
     public void destroy() {
         if (!mDestroyed) {
             mDestroyed = true;
+            mActivity = null;
             if (mSharedPrefs != null) {
                 mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
             }
diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
index 23baaf0..10cd04c 100644
--- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
+++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
@@ -261,7 +261,9 @@
         mCanBlockFling = mFromState == NORMAL;
         mFlingBlockCheck.unblockFling();
         // Must be called after all the animation controllers have been paused
-        if (FeatureFlags.ENABLE_DEVICE_SEARCH.get() && BuildCompat.isAtLeastR()
+        if (FeatureFlags.ENABLE_DEVICE_SEARCH.get()
+                && !FeatureFlags.DISABLE_INITIAL_IME_IN_ALLAPPS.get()
+                && BuildCompat.isAtLeastR()
                 && (mToState == ALL_APPS || mToState == NORMAL)) {
             mLauncher.getAllAppsController().getInsetController().onDragStart(
                     mFromState == NORMAL ? 1f : 0f);
diff --git a/src_plugins/com/android/systemui/plugins/AllAppsSearchPlugin.java b/src_plugins/com/android/systemui/plugins/AllAppsSearchPlugin.java
index 5cc238d..0b48c07 100644
--- a/src_plugins/com/android/systemui/plugins/AllAppsSearchPlugin.java
+++ b/src_plugins/com/android/systemui/plugins/AllAppsSearchPlugin.java
@@ -19,11 +19,12 @@
 import android.app.Activity;
 import android.os.Bundle;
 import android.os.CancellationSignal;
+import android.os.Parcelable;
 import android.view.View;
 
 import com.android.systemui.plugins.annotations.ProvidesInterface;
-import com.android.systemui.plugins.shared.SearchTarget;
-import com.android.systemui.plugins.shared.SearchTargetEvent;
+import com.android.systemui.plugins.shared.SearchTargetEventLegacy;
+import com.android.systemui.plugins.shared.SearchTargetLegacy;
 
 import java.util.List;
 import java.util.function.Consumer;
@@ -34,20 +35,25 @@
 @ProvidesInterface(action = AllAppsSearchPlugin.ACTION, version = AllAppsSearchPlugin.VERSION)
 public interface AllAppsSearchPlugin extends Plugin {
     String ACTION = "com.android.systemui.action.PLUGIN_ALL_APPS_SEARCH_ACTIONS";
-    int VERSION = 8;
+    int VERSION = 9;
 
-    void setup(Activity activity, View view);
+    /**
+     * init plugin
+     */
+    void setup(Activity activity, View view, boolean useLegacy);
 
     /**
      * Send launcher state related signals.
      */
     void onStateTransitionStart(int fromState, int toState);
+
     void onStateTransitionComplete(int state);
 
     /**
      * Send launcher window focus and visibility changed signals.
      */
     void onWindowFocusChanged(boolean hasFocus);
+
     void onWindowVisibilityChanged(int visibility);
 
     /**
@@ -59,22 +65,41 @@
     /**
      * Main function that triggers search.
      *
-     * @param input string that has been typed by a user
-     * @param inputArgs extra info that may be relevant for the input query
-     * @param results contains the result that will be rendered in all apps search surface
+     * @param input              string that has been typed by a user
+     * @param inputArgs          extra info that may be relevant for the input query
+     * @param results            contains the result that will be rendered in all apps search
+     *                           surface
      * @param cancellationSignal {@link CancellationSignal} can be used to share status of current
      */
-    void query(String input, Bundle inputArgs, Consumer<List<SearchTarget>> results,
+    void queryLegacy(String input, Bundle inputArgs, Consumer<List<SearchTargetLegacy>> results,
+            CancellationSignal cancellationSignal);
+
+    /**
+     * Main function that triggers search.
+     *
+     * @param input              string that has been typed by a user
+     * @param inputArgs          extra info that may be relevant for the input query
+     * @param results            contains the result that will be rendered in all apps search
+     *                           surface
+     * @param cancellationSignal {@link CancellationSignal} can be used to share status of current
+     */
+    void query(String input, Bundle inputArgs, Consumer<List<Parcelable>> results,
             CancellationSignal cancellationSignal);
 
     /**
      * Send over search target interaction events to Plugin
      */
-    void notifySearchTargetEvent(SearchTargetEvent event);
+    void notifySearchTargetEventLegacy(SearchTargetEventLegacy event);
+
+    /**
+     * Send over search target interaction events to Plugin
+     */
+    void notifySearchTargetEvent(Parcelable event);
 
     /**
      * Launcher activity lifecycle callbacks
      */
     void onResume(int state);
+
     void onStop(int state);
 }
\ No newline at end of file
diff --git a/src_plugins/com/android/systemui/plugins/shared/SearchTargetEvent.java b/src_plugins/com/android/systemui/plugins/shared/SearchTargetEventLegacy.java
similarity index 75%
rename from src_plugins/com/android/systemui/plugins/shared/SearchTargetEvent.java
rename to src_plugins/com/android/systemui/plugins/shared/SearchTargetEventLegacy.java
index 290fe54..7fbd6ac 100644
--- a/src_plugins/com/android/systemui/plugins/shared/SearchTargetEvent.java
+++ b/src_plugins/com/android/systemui/plugins/shared/SearchTargetEventLegacy.java
@@ -19,8 +19,11 @@
 
 /**
  * Event used for the feedback loop to the plugin. (and future aiai)
+ *
+ * @deprecated Use SearchTargetEvent
  */
-public class SearchTargetEvent {
+@Deprecated
+public class SearchTargetEventLegacy {
     public static final int POSITION_NONE = -1;
 
     public static final int SELECT = 0;
@@ -28,12 +31,13 @@
     public static final int LONG_PRESS = 2;
     public static final int CHILD_SELECT = 3;
 
-    private final SearchTarget mSearchTarget;
+    private final SearchTargetLegacy mSearchTarget;
     private final int mEventType;
     private final int mShortcutPosition;
     private final Bundle mExtras;
 
-    public SearchTargetEvent(SearchTarget searchTarget, int eventType, int shortcutPosition,
+    public SearchTargetEventLegacy(SearchTargetLegacy searchTarget, int eventType,
+            int shortcutPosition,
             Bundle extras) {
         mSearchTarget = searchTarget;
         mEventType = eventType;
@@ -42,7 +46,7 @@
     }
 
 
-    public SearchTarget getSearchTarget() {
+    public SearchTargetLegacy getSearchTarget() {
         return mSearchTarget;
     }
 
@@ -59,15 +63,15 @@
     }
 
     /**
-     * A builder for {@link SearchTarget}
+     * A builder for {@link SearchTargetLegacy}
      */
     public static final class Builder {
-        private final SearchTarget mSearchTarget;
+        private final SearchTargetLegacy mSearchTarget;
         private final int mEventType;
         private int mShortcutPosition = POSITION_NONE;
         private Bundle mExtras;
 
-        public Builder(SearchTarget searchTarget, int eventType) {
+        public Builder(SearchTargetLegacy searchTarget, int eventType) {
             mSearchTarget = searchTarget;
             mEventType = eventType;
         }
@@ -82,8 +86,9 @@
             return this;
         }
 
-        public SearchTargetEvent build() {
-            return new SearchTargetEvent(mSearchTarget, mEventType, mShortcutPosition, mExtras);
+        public SearchTargetEventLegacy build() {
+            return new SearchTargetEventLegacy(mSearchTarget, mEventType, mShortcutPosition,
+                    mExtras);
         }
     }
 
diff --git a/src_plugins/com/android/systemui/plugins/shared/SearchTarget.java b/src_plugins/com/android/systemui/plugins/shared/SearchTargetLegacy.java
similarity index 89%
rename from src_plugins/com/android/systemui/plugins/shared/SearchTarget.java
rename to src_plugins/com/android/systemui/plugins/shared/SearchTargetLegacy.java
index 2c7972e..2a6ba88 100644
--- a/src_plugins/com/android/systemui/plugins/shared/SearchTarget.java
+++ b/src_plugins/com/android/systemui/plugins/shared/SearchTargetLegacy.java
@@ -25,8 +25,11 @@
 
 /**
  * Used to return all apps search targets.
+ *
+ * @deprecated Use SearchTarget
  */
-public class SearchTarget implements Comparable<SearchTarget> {
+@Deprecated
+public class SearchTargetLegacy implements Comparable<SearchTargetLegacy> {
 
     private final String mItemId;
     private final String mItemType;
@@ -39,7 +42,7 @@
     private final RemoteAction mRemoteAction;
     private final Bundle mExtras;
 
-    private SearchTarget(String itemId, String itemType, float score,
+    private SearchTargetLegacy(String itemId, String itemType, float score,
             ComponentName componentName, UserHandle userHandle, List<ShortcutInfo> shortcutInfos,
             RemoteAction remoteAction, Bundle extras) {
         mItemId = itemId;
@@ -85,12 +88,12 @@
     }
 
     @Override
-    public int compareTo(SearchTarget o) {
+    public int compareTo(SearchTargetLegacy o) {
         return Float.compare(o.mScore, mScore);
     }
 
     /**
-     * A builder for {@link SearchTarget}
+     * A builder for {@link SearchTargetLegacy}
      */
     public static final class Builder {
 
@@ -158,13 +161,13 @@
         }
 
         /**
-         * Builds a {@link SearchTarget}
+         * Builds a {@link SearchTargetLegacy}
          */
-        public SearchTarget build() {
+        public SearchTargetLegacy build() {
             if (mItemId == null) {
                 throw new IllegalStateException("Item ID is required for building SearchTarget");
             }
-            return new SearchTarget(mItemId, mItemType, mScore, mComponentName, mUserHandle,
+            return new SearchTargetLegacy(mItemId, mItemType, mScore, mComponentName, mUserHandle,
                     mShortcutInfos,
                     mRemoteAction, mExtras);
         }
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index e118481..37dd4d2 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -150,7 +150,7 @@
         return "Activity leak detector has found leaked activities, " + dumpHprofData() + ".";
     }
 
-    private static String dumpHprofData() {
+    public static String dumpHprofData() {
         try {
             final String fileName = getInstrumentation().getTargetContext().getFilesDir().getPath()
                     + "/ActivityLeakHeapDump.hprof";
@@ -234,25 +234,11 @@
         return mDevice;
     }
 
-    private boolean hasSystemUiObject(String resId) {
-        return mDevice.hasObject(By.res(SYSTEMUI_PACKAGE, resId));
-    }
-
     @Before
     public void setUp() throws Exception {
-        Log.d(TAG, "Before disabling battery defender");
-        mDevice.executeShellCommand("setprop vendor.battery.defender.disable 1");
-        Log.d(TAG, "Before enabling stay awake");
-        mDevice.executeShellCommand("settings put global stay_on_while_plugged_in 3");
-        for (int i = 0; i < 10 && hasSystemUiObject("keyguard_status_view"); ++i) {
-            Log.d(TAG, "Before unlocking the phone");
-            mDevice.executeShellCommand("input keyevent 82");
-            mDevice.waitForIdle();
-        }
-        Assert.assertTrue("Keyguard still visible",
+        Assert.assertTrue("Keyguard is visible",
                 mDevice.wait(
                         Until.gone(By.res(SYSTEMUI_PACKAGE, "keyguard_status_view")), 60000));
-        Log.d(TAG, "Keyguard is not visible");
 
         final String launcherPackageName = mDevice.getLauncherPackageName();
         try {
diff --git a/tests/src/com/android/launcher3/ui/WorkTabTest.java b/tests/src/com/android/launcher3/ui/WorkTabTest.java
index ac0d355..aef26ae 100644
--- a/tests/src/com/android/launcher3/ui/WorkTabTest.java
+++ b/tests/src/com/android/launcher3/ui/WorkTabTest.java
@@ -150,11 +150,15 @@
         waitForLauncherCondition("Launcher did not show the next edu screen", l -> {
             Log.d(TestProtocol.WORK_PROFILE_REMOVED,
                     "running test attempt" + attempt.getAndIncrement());
+            if (!(l.getAppsView().getContentView() instanceof AllAppsPagedView)) {
+                Log.d(TestProtocol.WORK_PROFILE_REMOVED, "Work tab not setup. Skipping test");
+                return false;
+            }
             return ((AllAppsPagedView) l.getAppsView().getContentView()).getCurrentPage()
                     == WORK_PAGE && ((TextView) workEduView.findViewById(
                     R.id.content_text)).getText().equals(
                     l.getResources().getString(R.string.work_profile_edu_work_apps));
-        });
+        }, 60000);
     }
 
     @Test