Merge "Fix continueComputingRecentsScrollIfNecessary() running infinitely" into ub-launcher3-rvc-dev
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
index 78cc2dc..7f8f0a0 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
@@ -48,6 +48,7 @@
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.IntStream;
 
 /**
  * Controller class for managing user onboaridng flow for hybrid hotseat
@@ -110,7 +111,8 @@
             ItemInfo info = (ItemInfo) view.getTag();
             if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
                 folders.add((FolderInfo) info);
-            } else if (info instanceof WorkspaceItemInfo) {
+            } else if (info instanceof WorkspaceItemInfo && info.container == LauncherSettings
+                    .Favorites.CONTAINER_HOTSEAT) {
                 putIntoFolder.add((WorkspaceItemInfo) info);
             }
         }
@@ -206,6 +208,7 @@
             View child = mHotseat.getChildAt(i, 0);
             if (child == null || child.getTag() == null) continue;
             ItemInfo tag = (ItemInfo) child.getTag();
+            if (tag.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION) continue;
             mLauncher.getModelWriter().moveItemInDatabase(tag,
                     LauncherSettings.Favorites.CONTAINER_DESKTOP, pageId, i, toRow);
             mNewItems.add(tag);
@@ -300,13 +303,23 @@
     }
 
     void showEdu() {
+        int childCount = mHotseat.getShortcutsAndWidgets().getChildCount();
+        CellLayout cellLayout = mLauncher.getWorkspace().getScreenWithId(Workspace.FIRST_SCREEN_ID);
         // hotseat is already empty and does not require migration. show edu tip
-        if (mHotseat.getShortcutsAndWidgets().getChildCount() == 0) {
-            new ArrowTipView(mLauncher).show(mLauncher.getString(R.string.hotseat_auto_enrolled),
+        boolean requiresMigration = IntStream.range(0, childCount).anyMatch(i -> {
+            View v = mHotseat.getShortcutsAndWidgets().getChildAt(i);
+            return v != null && v.getTag() != null && ((ItemInfo) v.getTag()).container
+                    != LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
+        });
+        boolean canMigrateToFirstPage = cellLayout.makeSpaceForHotseatMigration(false);
+        if (requiresMigration && canMigrateToFirstPage) {
+            showDialog();
+        } else {
+            new ArrowTipView(mLauncher).show(mLauncher.getString(
+                    requiresMigration ? R.string.hotseat_tip_no_empty_slots
+                            : R.string.hotseat_auto_enrolled),
                     mHotseat.getTop());
             finishOnboarding();
-        } else {
-            showDialog();
         }
     }
 
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
index 1aff8e9..cb8d1c4 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
@@ -16,9 +16,6 @@
 package com.android.launcher3.hybridhotseat;
 
 import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
-import static com.android.launcher3.logging.LoggerUtils.newAction;
-import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
-import static com.android.launcher3.logging.LoggerUtils.newLauncherEvent;
 
 import android.animation.Animator;
 import android.animation.AnimatorSet;
@@ -32,7 +29,6 @@
 import android.content.ComponentName;
 import android.os.Bundle;
 import android.os.Process;
-import android.provider.DeviceConfig;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
@@ -60,7 +56,6 @@
 import com.android.launcher3.dragndrop.DragOptions;
 import com.android.launcher3.icons.IconCache;
 import com.android.launcher3.logging.FileLog;
-import com.android.launcher3.logging.UserEventDispatcher;
 import com.android.launcher3.model.data.AppInfo;
 import com.android.launcher3.model.data.FolderInfo;
 import com.android.launcher3.model.data.ItemInfo;
@@ -70,12 +65,12 @@
 import com.android.launcher3.popup.SystemShortcut;
 import com.android.launcher3.shortcuts.ShortcutKey;
 import com.android.launcher3.touch.ItemLongClickListener;
-import com.android.launcher3.uioverrides.DeviceFlag;
 import com.android.launcher3.uioverrides.PredictedAppIcon;
 import com.android.launcher3.uioverrides.QuickstepLauncher;
 import com.android.launcher3.userevent.nano.LauncherLogProto;
 import com.android.launcher3.util.ComponentKey;
 
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -155,9 +150,9 @@
     }
 
     /**
-     * Returns whether or not the prediction controller is ready to show predictions
+     * Returns whether or not user has seen hybrid hotseat education
      */
-    public boolean isReady() {
+    public boolean isEduSeen() {
         return mLauncher.getSharedPrefs().getBoolean(HotseatEduController.KEY_HOTSEAT_EDU_SEEN,
                 false);
     }
@@ -186,7 +181,7 @@
     }
 
     private void fillGapsWithPrediction(boolean animate, Runnable callback) {
-        if (!isReady() || mUIUpdatePaused || mDragObject != null) {
+        if (mUIUpdatePaused || mDragObject != null) {
             return;
         }
         List<WorkspaceItemInfo> predictedApps = mapToWorkspaceItemInfo(mComponentKeyMappers);
@@ -262,6 +257,10 @@
         if (mAppPredictor != null) {
             mAppPredictor.destroy();
         }
+        if (mHotseatEduController != null) {
+            mHotseatEduController.destroy();
+            mHotseatEduController = null;
+        }
     }
 
     /**
@@ -291,11 +290,16 @@
                         .setPredictedTargetCount(mHotSeatItemsCount)
                         .setExtras(getAppPredictionContextExtra())
                         .build());
-        mAppPredictor.registerPredictionUpdates(mLauncher.getMainExecutor(),
-                this::setPredictedApps);
+        WeakReference<HotseatPredictionController> controllerRef = new WeakReference<>(this);
+        mAppPredictor.registerPredictionUpdates(mLauncher.getApplicationContext().getMainExecutor(),
+                list -> {
+                    if (controllerRef.get() != null) {
+                        controllerRef.get().setPredictedApps(list);
+                    }
+                });
+
         setPauseUIUpdate(false);
-        performBetaCheck();
-        if (!isReady()) {
+        if (!isEduSeen()) {
             mHotseatEduController = new HotseatEduController(mLauncher, this::createPredictor);
         }
         mAppPredictor.requestPredictionUpdate();
@@ -386,9 +390,8 @@
         predictionLog.append("]");
         if (Utilities.IS_DEBUG_DEVICE) FileLog.d(TAG, predictionLog.toString());
         updateDependencies();
-        if (isReady()) {
             fillGapsWithPrediction();
-        } else if (mHotseatEduController != null) {
+        if (!isEduSeen() && mHotseatEduController != null) {
             mHotseatEduController.setPredictedApps(mapToWorkspaceItemInfo(mComponentKeyMappers));
         }
         // should invalidate cache if AiAi sends empty list of AppTargets
@@ -682,42 +685,6 @@
         }
     }
 
-    private void performBetaCheck() {
-        if (isReady()) return;
-        int hotseatItemsCount = mHotseat.getShortcutsAndWidgets().getChildCount();
-
-        int maxItems = DeviceConfig.getInt(
-                DeviceFlag.NAMESPACE_LAUNCHER, "max_homepage_items_for_migration", 5);
-
-        // -1 to exclude smart space
-        int workspaceItemCount = mLauncher.getWorkspace().getScreenWithId(
-                Workspace.FIRST_SCREEN_ID).getShortcutsAndWidgets().getChildCount() - 1;
-
-        // opt user into the feature without onboarding tip or migration if they don't have any
-        // open spots in their hotseat and have more than maxItems in their hotseat + workspace
-
-        if (hotseatItemsCount == mHotSeatItemsCount && workspaceItemCount + hotseatItemsCount
-                > maxItems) {
-            mLauncher.getSharedPrefs().edit().putBoolean(HotseatEduController.KEY_HOTSEAT_EDU_SEEN,
-                    true).apply();
-
-            LauncherLogProto.Action action = newAction(LauncherLogProto.Action.Type.TOUCH);
-            LauncherLogProto.Target target = newContainerTarget(LauncherLogProto.ContainerType.TIP);
-            action.touch = LauncherLogProto.Action.Touch.TAP;
-            target.tipType = LauncherLogProto.TipType.HYBRID_HOTSEAT;
-            target.controlType = LauncherLogProto.ControlType.HYBRID_HOTSEAT_CANCELED;
-
-            // temporarily encode details in log target (go/hotseat_migration)
-            target.rank = 2;
-            target.cardinality = (workspaceItemCount * 1000) + hotseatItemsCount;
-            target.pageIndex = maxItems;
-            LauncherLogProto.LauncherEvent event = newLauncherEvent(action, target);
-            UserEventDispatcher.newInstance(mLauncher).dispatchUserEvent(event, null);
-
-
-        }
-    }
-
     /**
      * Fill in predicted_rank field based on app prediction.
      * Only applicable when {@link ItemInfo#itemType} is PREDICTED_HOTSEAT
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index ceb7166..a2d9e17 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -182,6 +182,7 @@
         super.onDestroy();
         if (mHotseatPredictionController != null) {
             mHotseatPredictionController.destroy();
+            mHotseatPredictionController = null;
         }
     }
 
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
index 9e53959..c643858 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
@@ -35,8 +35,6 @@
 
 import android.view.MotionEvent;
 
-import androidx.annotation.Nullable;
-
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.Utilities;
@@ -57,7 +55,7 @@
  */
 public class QuickSwitchTouchController extends AbstractStateChangeTouchController {
 
-    private @Nullable TaskView mTaskToLaunch;
+    protected final RecentsView mOverviewPanel;
 
     public QuickSwitchTouchController(Launcher launcher) {
         this(launcher, SingleAxisSwipeDetector.HORIZONTAL);
@@ -65,6 +63,7 @@
 
     protected QuickSwitchTouchController(Launcher l, SingleAxisSwipeDetector.Direction dir) {
         super(l, dir);
+        mOverviewPanel = l.getOverviewPanel();
     }
 
     @Override
@@ -94,7 +93,6 @@
     public void onDragStart(boolean start, float startDisplacement) {
         super.onDragStart(start, startDisplacement);
         mStartContainerType = LauncherLogProto.ContainerType.NAVBAR;
-        mTaskToLaunch = mLauncher.<RecentsView>getOverviewPanel().getTaskViewAt(0);
         ActivityManagerWrapper.getInstance()
                 .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
     }
@@ -102,7 +100,6 @@
     @Override
     protected void onSwipeInteractionCompleted(LauncherState targetState, int logAction) {
         super.onSwipeInteractionCompleted(targetState, logAction);
-        mTaskToLaunch = null;
     }
 
     @Override
@@ -141,13 +138,15 @@
     }
 
     private void updateFullscreenProgress(float progress) {
-        if (mTaskToLaunch != null) {
-            mTaskToLaunch.setFullscreenProgress(progress);
-            int sysuiFlags = progress > UPDATE_SYSUI_FLAGS_THRESHOLD
-                    ? mTaskToLaunch.getThumbnail().getSysUiStatusNavFlags()
-                    : 0;
-            mLauncher.getSystemUiController().updateUiState(UI_STATE_OVERVIEW, sysuiFlags);
+        mOverviewPanel.setFullscreenProgress(progress);
+        int sysuiFlags = 0;
+        if (progress > UPDATE_SYSUI_FLAGS_THRESHOLD) {
+            TaskView tv = mOverviewPanel.getTaskViewAt(0);
+            if (tv != null) {
+                sysuiFlags = tv.getThumbnail().getSysUiStatusNavFlags();
+            }
         }
+        mLauncher.getSystemUiController().updateUiState(UI_STATE_OVERVIEW, sysuiFlags);
     }
 
     @Override
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
index 9540ccf..c554cf6 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
@@ -345,10 +345,7 @@
         mAppWindowAnimationHelper.updateTargetRect(TEMP_RECT);
         if (mDeviceState.isFullyGesturalNavMode()) {
             // We can drag all the way to the top of the screen.
-            // TODO(b/149609070): Landscape apps are currently limited in
-            //   their ability to scale past the target rect.
-            float dragFactor = (float) dp.heightPx / mTransitionDragLength;
-            mDragLengthFactor = displayRotation == 0 ? dragFactor : Math.min(1.0f, dragFactor);
+            mDragLengthFactor = (float) dp.heightPx / mTransitionDragLength;
             Pair<Float, Float> dragFactorStartAndMaxProgress =
                     mActivityInterface.getSwipeUpPullbackStartAndMaxProgress();
             mDragLengthFactorStartPullback = dragFactorStartAndMaxProgress.first;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java
index 9b47520..512bbac 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java
@@ -239,7 +239,8 @@
         setLayoutParams(params);
         setScaleX(taskView.getScaleX());
         setScaleY(taskView.getScaleY());
-        mOptionLayout.setOrientation(orientationHandler.getTaskMenuLayoutOrientation());
+        mOptionLayout.setOrientation(orientationHandler
+                .getTaskMenuLayoutOrientation(mOptionLayout));
         setPosition(sTempRect.left - insets.left, sTempRect.top - insets.top,
             taskView.getPagedOrientationHandler());
     }
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
index f8f927b..97652aa 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
@@ -448,14 +448,12 @@
     }
 
     public void setOrientationState(RecentsOrientedState orientationState) {
-        int iconRotation = orientationState.getTouchRotation();
         PagedOrientationHandler orientationHandler = orientationState.getOrientationHandler();
         boolean isRtl = orientationHandler.getRecentsRtlSetting(getResources());
         LayoutParams snapshotParams = (LayoutParams) mSnapshotView.getLayoutParams();
         int thumbnailPadding = (int) getResources().getDimension(R.dimen.task_thumbnail_top_margin);
         LayoutParams iconParams = (LayoutParams) mIconView.getLayoutParams();
-        int rotation = orientationState.getTouchRotationDegrees();
-        switch (iconRotation) {
+        switch (orientationHandler.getRotation()) {
             case Surface.ROTATION_90:
                 iconParams.gravity = (isRtl ? END : START) | CENTER_VERTICAL;
                 iconParams.rightMargin = -thumbnailPadding;
@@ -480,7 +478,7 @@
                 break;
         }
         mIconView.setLayoutParams(iconParams);
-        mIconView.setRotation(rotation);
+        mIconView.setRotation(orientationHandler.getDegreesRotated());
 
         if (mMenuView != null) {
             mMenuView.onRotationChanged();
@@ -671,7 +669,7 @@
             mContextualChip.setScaleY(0f);
             GradientDrawable scrimDrawable = (GradientDrawable) getResources().getDrawable(
                     R.drawable.chip_scrim_gradient, mActivity.getTheme());
-            float cornerRadius = TaskCornerRadius.get(mActivity);
+            float cornerRadius = getTaskCornerRadius();
             scrimDrawable.setCornerRadii(
                     new float[]{0, 0, 0, 0, cornerRadius, cornerRadius, cornerRadius,
                             cornerRadius});
@@ -690,6 +688,10 @@
         }
     }
 
+    public float getTaskCornerRadius() {
+        return TaskCornerRadius.get(mActivity);
+    }
+
     /**
      * Clears the contextual chip from TaskView.
      *
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index 3bb8b07..10e3a28 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -252,13 +252,10 @@
         super.onActivityFlagsChanged(changeBits);
     }
 
-    /**
-     * Sets the back button visibility based on the current state/window focus.
-     */
-    private void onLauncherStateOrFocusChanged() {
+    public boolean shouldBackButtonBeHidden(LauncherState toState) {
         Mode mode = SysUINavigationMode.getMode(this);
         boolean shouldBackButtonBeHidden = mode.hasGestures
-                && getStateManager().getState().hasFlag(FLAG_HIDE_BACK_BUTTON)
+                && toState.hasFlag(FLAG_HIDE_BACK_BUTTON)
                 && hasWindowFocus()
                 && (getActivityFlags() & ACTIVITY_STATE_TRANSITION_ACTIVE) == 0;
         if (shouldBackButtonBeHidden) {
@@ -266,6 +263,14 @@
             shouldBackButtonBeHidden = AbstractFloatingView.getTopOpenViewWithType(this,
                     TYPE_ALL & ~TYPE_HIDE_BACK_BUTTON) == null;
         }
+        return shouldBackButtonBeHidden;
+    }
+
+    /**
+     * Sets the back button visibility based on the current state/window focus.
+     */
+    private void onLauncherStateOrFocusChanged() {
+        boolean shouldBackButtonBeHidden = shouldBackButtonBeHidden(getStateManager().getState());
         UiThreadHelper.setBackButtonAlphaAsync(this, SET_BACK_BUTTON_ALPHA,
                 shouldBackButtonBeHidden ? 0f : 1f, true /* animate */);
         if (getDragLayer() != null) {
diff --git a/quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java b/quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java
index 9145191..075a483 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java
@@ -61,7 +61,7 @@
 
         mBackAlpha.value = SystemUiProxy.INSTANCE.get(mLauncher).getLastBackButtonAlpha();
         animation.setFloat(mBackAlpha, VALUE,
-                toState.hasFlag(FLAG_HIDE_BACK_BUTTON) ? 0 : 1, LINEAR);
+                mLauncher.shouldBackButtonBeHidden(toState) ? 0 : 1, LINEAR);
     }
 
     private void updateBackAlpha() {
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index ef14e28..8ac15e8 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -17,6 +17,7 @@
 
 import static android.content.Intent.ACTION_USER_UNLOCKED;
 
+import static com.android.launcher3.util.DefaultDisplay.CHANGE_ALL;
 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
 import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
 import static com.android.quickstep.SysUINavigationMode.Mode.THREE_BUTTONS;
@@ -216,6 +217,7 @@
         mDefaultDisplay.removeChangeListener(this);
         if (newMode.hasGestures) {
             mDefaultDisplay.addChangeListener(this);
+            onDisplayInfoChanged(mDefaultDisplay.getInfo(), CHANGE_ALL);
         }
 
         if (newMode == NO_BUTTON) {
diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
index 5ca2095..b36c4ef 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
@@ -350,7 +350,11 @@
         } else {
             outPivot.set(fullWidth, fullHeight);
         }
-        final float scale = Math.min(outPivot.x / taskView.width(), outPivot.y / taskView.height());
+        float scale = Math.min(outPivot.x / taskView.width(), outPivot.y / taskView.height());
+        // We also scale the preview as part of fullScreenParams, so account for that as well.
+        if (fullWidth > 0) {
+            scale = scale * dp.widthPx / fullWidth;
+        }
 
         if (scale == 1) {
             outPivot.set(fullWidth / 2, fullHeight / 2);
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 74e178f..21dd141 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -132,6 +132,10 @@
 
         mAppsView.setTranslationY(shiftCurrent);
 
+        if (mPlugin != null) {
+            mPlugin.setProgress(progress);
+        }
+
         // Use a light system UI (dark icons) if all apps is behind at least half of the
         // status bar.
         boolean forceChange = Math.min(shiftCurrent, mScrimView.getVisualTop())
@@ -200,8 +204,8 @@
             // TODO: change this from toggle event to continuous transition event.
             mPlugin.setEditText(mAppsView.getSearchUiManager().setTextSearchEnabled(true));
         } else {
-            mAppsView.getSearchUiManager().setTextSearchEnabled(false);
             mPlugin.setEditText(null);
+            mAppsView.getSearchUiManager().setTextSearchEnabled(false);
         }
 
     }
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index df30f7b..ffe106f 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -117,8 +117,8 @@
             "ASSISTANT_GIVES_LAUNCHER_FOCUS", false,
             "Allow Launcher to handle nav bar gestures while Assistant is running over it");
 
-    public static final BooleanFlag ENABLE_HYBRID_HOTSEAT = new DeviceFlag(
-            "ENABLE_HYBRID_HOTSEAT", false, "Fill gaps in hotseat with predicted apps");
+    public static final BooleanFlag ENABLE_HYBRID_HOTSEAT = getDebugFlag(
+            "ENABLE_HYBRID_HOTSEAT", true, "Fill gaps in hotseat with predicted apps");
 
     public static final BooleanFlag HOTSEAT_MIGRATE_TO_FOLDER = new DeviceFlag(
             "HOTSEAT_MIGRATE_TO_FOLDER", false, "Should move hotseat items into a folder");
diff --git a/src/com/android/launcher3/touch/HomeRotatedPageHandler.java b/src/com/android/launcher3/touch/HomeRotatedPageHandler.java
index 710b676..db5c659 100644
--- a/src/com/android/launcher3/touch/HomeRotatedPageHandler.java
+++ b/src/com/android/launcher3/touch/HomeRotatedPageHandler.java
@@ -18,6 +18,7 @@
 
 import android.graphics.RectF;
 import android.view.Surface;
+import android.widget.LinearLayout;
 
 public class HomeRotatedPageHandler extends PortraitPagedViewHandler {
     @Override
@@ -46,4 +47,9 @@
             }
         } // TODO (b/149609488) handle 180 case as well
     }
+
+    @Override
+    public int getTaskMenuLayoutOrientation(LinearLayout taskMenuLayout) {
+        return taskMenuLayout.getOrientation();
+    }
 }
diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
index 86d3c61..5007ca0 100644
--- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
@@ -177,6 +177,11 @@
     }
 
     @Override
+    public int getRotation() {
+        return Surface.ROTATION_90;
+    }
+
+    @Override
     public void offsetTaskRect(RectF rect, float value, int displayRotation, int launcherRotation) {
         if (displayRotation == Surface.ROTATION_0) {
             rect.offset(0, value);
@@ -246,7 +251,7 @@
     }
 
     @Override
-    public int getTaskMenuLayoutOrientation() {
+    public int getTaskMenuLayoutOrientation(LinearLayout taskMenuLayout) {
         return LinearLayout.HORIZONTAL;
     }
 
diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java
index 02a020f..cdfe6d5 100644
--- a/src/com/android/launcher3/touch/PagedOrientationHandler.java
+++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java
@@ -81,6 +81,7 @@
     void setMaxScroll(AccessibilityEvent event, int maxScroll);
     boolean getRecentsRtlSetting(Resources resources);
     float getDegreesRotated();
+    int getRotation();
     void offsetTaskRect(RectF rect, float value, int delta, int launcherRotation);
     int getPrimaryValue(int x, int y);
     int getSecondaryValue(int x, int y);
@@ -95,7 +96,7 @@
     float getTaskMenuX(float x, View thumbnailView);
     float getTaskMenuY(float y, View thumbnailView);
     int getTaskMenuWidth(View view);
-    int getTaskMenuLayoutOrientation();
+    int getTaskMenuLayoutOrientation(LinearLayout taskMenuLayout);
     void setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp);
 
     /**
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index b253e7d..25dc1f6 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -174,6 +174,11 @@
     }
 
     @Override
+    public int getRotation() {
+        return Surface.ROTATION_0;
+    }
+
+    @Override
     public void offsetTaskRect(RectF rect, float value, int displayRotation, int launcherRotation) {
         if (displayRotation == Surface.ROTATION_0) {
             rect.offset(value, 0);
@@ -243,7 +248,7 @@
     }
 
     @Override
-    public int getTaskMenuLayoutOrientation() {
+    public int getTaskMenuLayoutOrientation(LinearLayout taskMenuLayout) {
         return LinearLayout.VERTICAL;
     }
 
diff --git a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
index e86ec3b..dde2829 100644
--- a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
@@ -55,6 +55,11 @@
     }
 
     @Override
+    public int getRotation() {
+        return Surface.ROTATION_270;
+    }
+
+    @Override
     public boolean isGoingUp(float displacement) {
         return displacement < 0;
     }
diff --git a/src/com/android/launcher3/util/DefaultDisplay.java b/src/com/android/launcher3/util/DefaultDisplay.java
index d51f777..fabdb4e 100644
--- a/src/com/android/launcher3/util/DefaultDisplay.java
+++ b/src/com/android/launcher3/util/DefaultDisplay.java
@@ -47,6 +47,8 @@
     public static final int CHANGE_ROTATION = 1 << 1;
     public static final int CHANGE_FRAME_DELAY = 1 << 2;
 
+    public static final int CHANGE_ALL = CHANGE_SIZE | CHANGE_ROTATION | CHANGE_FRAME_DELAY;
+
     private final Context mContext;
     private final int mId;
     private final ArrayList<DisplayInfoChangeListener> mListeners = new ArrayList<>();
diff --git a/src_plugins/com/android/systemui/plugins/AllAppsSearchPlugin.java b/src_plugins/com/android/systemui/plugins/AllAppsSearchPlugin.java
index cdd3b06..d458fc4 100644
--- a/src_plugins/com/android/systemui/plugins/AllAppsSearchPlugin.java
+++ b/src_plugins/com/android/systemui/plugins/AllAppsSearchPlugin.java
@@ -19,7 +19,6 @@
 import android.app.Activity;
 import android.view.ViewGroup;
 import android.widget.EditText;
-
 import com.android.systemui.plugins.annotations.ProvidesInterface;
 
 /**
@@ -32,4 +31,5 @@
 
     void setup(ViewGroup parent, Activity activity);
     void setEditText(EditText editText);
+    void setProgress(float progress);
 }
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 35cc94f..dd170c5 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -651,7 +651,7 @@
                 } else {
                     log("Hierarchy before swiping up to home:");
                     dumpViewHierarchy();
-                    log(action = "swiping up to home from " + getVisibleStateMessage());
+                    action = "swiping up to home";
 
                     try (LauncherInstrumentation.Closable c = addContextLayer(action)) {
                         swipeToState(
@@ -666,10 +666,8 @@
             } else {
                 log("Hierarchy before clicking home:");
                 dumpViewHierarchy();
-                log(action = "clicking home button from " + getVisibleStateMessage());
+                action = "clicking home button";
                 try (LauncherInstrumentation.Closable c = addContextLayer(action)) {
-                    mDevice.waitForIdle();
-
                     if (!isLauncher3() && getNavigationModel() == NavigationModel.TWO_BUTTON) {
                         expectEvent(TestProtocol.SEQUENCE_TIS, EVENT_TOUCH_DOWN_TIS);
                         expectEvent(TestProtocol.SEQUENCE_TIS, EVENT_TOUCH_UP_TIS);
@@ -681,7 +679,6 @@
                             !hasLauncherObject(WORKSPACE_RES_ID)
                                     && (hasLauncherObject(APPS_RES_ID)
                                     || hasLauncherObject(OVERVIEW_RES_ID)));
-                    mDevice.waitForIdle();
                 }
             }
             try (LauncherInstrumentation.Closable c = addContextLayer(
@@ -1283,10 +1280,10 @@
     public Closable eventsCheck() {
         Assert.assertTrue("Nested event checking", !sCheckingEvents);
         disableSensorRotation();
-        sCheckingEvents = true;
         final int initialPid = getPid();
         if (sEventChecker == null) sEventChecker = new LogEventChecker();
         sEventChecker.start();
+        sCheckingEvents = true;
 
         return () -> {
             if (initialPid != getPid()) {
diff --git a/tests/tapl/com/android/launcher3/tapl/LogEventChecker.java b/tests/tapl/com/android/launcher3/tapl/LogEventChecker.java
index 2141fab..053847c 100644
--- a/tests/tapl/com/android/launcher3/tapl/LogEventChecker.java
+++ b/tests/tapl/com/android/launcher3/tapl/LogEventChecker.java
@@ -69,8 +69,9 @@
                 mFinished.await();
             } catch (InterruptedException e) {
                 throw new RuntimeException(e);
+            } finally {
+                mFinished = null;
             }
-            mFinished = null;
         }
         mEvents.clear();
         Log.d(SKIP_EVENTS_TAG, "Cleared events");