Merge "Update the position of the live tile overlay upon swipe up" into ub-launcher3-master
diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml
index 84dd06a..19a16e3 100644
--- a/AndroidManifest-common.xml
+++ b/AndroidManifest-common.xml
@@ -45,9 +45,6 @@
     <uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
     <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
     <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
-
-    <!-- TODO(b/150802536): Enabled only for ENABLE_FIXED_ROTATION_TRANSFORM feature flag -->
-    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
     
     <!--
     Permissions required for read/write access to the workspace data. These permission name
diff --git a/go/res/xml/device_profiles.xml b/go/res/xml/device_profiles.xml
index 0fd0eeb..0c7eba3 100644
--- a/go/res/xml/device_profiles.xml
+++ b/go/res/xml/device_profiles.xml
@@ -24,6 +24,7 @@
         launcher:numFolderRows="4"
         launcher:numFolderColumns="4"
         launcher:numHotseatIcons="4"
+        launcher:dbFile="launcher.db"
         launcher:defaultLayoutId="@xml/default_workspace_4x4" >
 
         <display-option
@@ -36,4 +37,4 @@
 
     </grid-option>
 
-</profiles>
\ No newline at end of file
+</profiles>
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java
index 4c7943b..e4442da 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java
@@ -69,7 +69,6 @@
 
     // Accessed only on worker thread
     private AppPredictor mHomeAppPredictor;
-    private AppPredictor mRecentsOverviewPredictor;
 
     public PredictionAppTracker(Context context) {
         mContext = context;
@@ -97,10 +96,6 @@
             mHomeAppPredictor.destroy();
             mHomeAppPredictor = null;
         }
-        if (mRecentsOverviewPredictor != null) {
-            mRecentsOverviewPredictor.destroy();
-            mRecentsOverviewPredictor = null;
-        }
     }
 
     @WorkerThread
@@ -142,7 +137,6 @@
                 // Initialize the clients
                 int count = InvariantDeviceProfile.INSTANCE.get(mContext).numAllAppsColumns;
                 mHomeAppPredictor = createPredictor(Client.HOME, count);
-                mRecentsOverviewPredictor = createPredictor(Client.OVERVIEW, count);
                 return true;
             }
             case MSG_DESTROY: {
@@ -157,12 +151,7 @@
             }
             case MSG_PREDICT: {
                 if (mHomeAppPredictor != null) {
-                    String client = (String) msg.obj;
-                    if (Client.HOME.id.equals(client)) {
-                        mHomeAppPredictor.requestPredictionUpdate();
-                    } else {
-                        mRecentsOverviewPredictor.requestPredictionUpdate();
-                    }
+                    mHomeAppPredictor.requestPredictionUpdate();
                 }
                 return true;
             }
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java
index 5e54cd2..830c103 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java
@@ -52,7 +52,6 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import java.util.Optional;
 import java.util.OptionalInt;
 import java.util.stream.IntStream;
 
@@ -76,8 +75,7 @@
 
     // TODO (b/129421797): Update the client constants
     public enum Client {
-        HOME("home"),
-        OVERVIEW("overview");
+        HOME("home");
 
         public final String id;
 
@@ -92,10 +90,9 @@
     private final Context mContext;
 
     private final DynamicItemCache mDynamicItemCache;
-    private final List[] mPredictionServicePredictions;
+    private List mPredictionServicePredictions = Collections.emptyList();
 
     private int mMaxIconsPerRow;
-    private Client mActiveClient;
 
     private AllAppsContainerView mAppsView;
 
@@ -109,16 +106,10 @@
 
         mDynamicItemCache = new DynamicItemCache(context, this::onAppsUpdated);
 
-        mActiveClient = Client.HOME;
-
         InvariantDeviceProfile idp = LauncherAppState.getIDP(context);
         mMaxIconsPerRow = idp.numColumns;
 
         idp.addOnChangeListener(this);
-        mPredictionServicePredictions = new List[Client.values().length];
-        for (int i = 0; i < mPredictionServicePredictions.length; i++) {
-            mPredictionServicePredictions[i] = Collections.emptyList();
-        }
         mGettingValidPredictionResults = Utilities.getDevicePrefs(context)
                 .getBoolean(LAST_PREDICTION_ENABLED_STATE, true);
 
@@ -131,18 +122,6 @@
         mMaxIconsPerRow = profile.numColumns;
     }
 
-    public Client getClient() {
-        return mActiveClient;
-    }
-
-    public void switchClient(Client client) {
-        if (client == mActiveClient) {
-            return;
-        }
-        mActiveClient = client;
-        dispatchOnChange(true);
-    }
-
     public void setTargetAppsView(AllAppsContainerView appsView) {
         if (mAppsView != null) {
             mAppsView.getAppsStore().removeUpdateListener(this);
@@ -196,10 +175,8 @@
     }
 
     private void updatePredictionStateAfterCallback() {
-        boolean validResults = false;
-        for (List l : mPredictionServicePredictions) {
-            validResults |= l != null && !l.isEmpty();
-        }
+        boolean validResults = mPredictionServicePredictions != null
+                && !mPredictionServicePredictions.isEmpty();
         if (validResults != mGettingValidPredictionResults) {
             mGettingValidPredictionResults = validResults;
             Utilities.getDevicePrefs(mContext).edit()
@@ -211,7 +188,7 @@
 
     public AppPredictor.Callback appPredictorCallback(Client client) {
         return targets -> {
-            mPredictionServicePredictions[client.ordinal()] = targets;
+            mPredictionServicePredictions = targets;
             updatePredictionStateAfterCallback();
         };
     }
@@ -239,7 +216,7 @@
 
         state.apps = new ArrayList<>();
 
-        List<AppTarget> appTargets = mPredictionServicePredictions[mActiveClient.ordinal()];
+        List<AppTarget> appTargets = mPredictionServicePredictions;
         if (!appTargets.isEmpty()) {
             for (AppTarget appTarget : appTargets) {
                 ComponentKey key;
@@ -315,16 +292,22 @@
      * {@link LauncherSettings.Favorites#ITEM_TYPE_DEEP_SHORTCUT}
      */
     public OptionalInt getAllAppsRank(@Nullable ItemInfo itemInfo) {
-        Optional<ComponentKey> componentKey = Optional.ofNullable(itemInfo)
-                .filter(item -> item.itemType == ITEM_TYPE_APPLICATION
-                        || item.itemType == ITEM_TYPE_SHORTCUT
-                        || item.itemType == ITEM_TYPE_DEEP_SHORTCUT)
-                .map(ItemInfo::getTargetComponent)
-                .map(componentName -> new ComponentKey(componentName, itemInfo.user));
+        if (itemInfo == null || itemInfo.getTargetComponent() == null || itemInfo.user == null) {
+            return OptionalInt.empty();
+        }
 
-        return componentKey.map(key -> IntStream.range(0, getCurrentState().apps.size())
-                .filter(index -> key.equals(getCurrentState().apps.get(index).getComponentKey()))
-                .findFirst()).orElseGet(OptionalInt::empty);
+        if (itemInfo.itemType == ITEM_TYPE_APPLICATION
+                || itemInfo.itemType == ITEM_TYPE_SHORTCUT
+                || itemInfo.itemType == ITEM_TYPE_DEEP_SHORTCUT) {
+            ComponentKey key = new ComponentKey(itemInfo.getTargetComponent(),
+                    itemInfo.user);
+            final List<ComponentKeyMapper> apps = getCurrentState().apps;
+            return IntStream.range(0, apps.size())
+                    .filter(index -> key.equals(apps.get(index).getComponentKey()))
+                    .findFirst();
+        }
+
+        return OptionalInt.empty();
     }
 
     /**
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 1dbb9e2..b94e633 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
@@ -113,8 +113,6 @@
     private AllAppsStore mAllAppsStore;
     private AnimatorSet mIconRemoveAnimators;
     private boolean mUIUpdatePaused = false;
-    private boolean mRequiresCacheUpdate = true;
-    private boolean mIsCacheEmpty;
     private boolean mIsDestroyed = false;
 
 
@@ -350,7 +348,6 @@
             fillGapsWithPrediction();
             return;
         }
-        mIsCacheEmpty = apps.isEmpty();
         int count = Math.min(ranks.size(), apps.size());
         List<WorkspaceItemInfo> items = new ArrayList<>(count);
         for (int i = 0; i < count; i++) {
@@ -393,14 +390,7 @@
         }
         updateDependencies();
         fillGapsWithPrediction();
-        cachePredictionComponentKeysIfNecessary(componentKeys);
-    }
-
-    private void cachePredictionComponentKeysIfNecessary(ArrayList<ComponentKey> componentKeys) {
-        if (!mRequiresCacheUpdate && componentKeys.isEmpty() == mIsCacheEmpty) return;
         mPredictionModel.cachePredictionComponentKeys(componentKeys);
-        mIsCacheEmpty = componentKeys.isEmpty();
-        mRequiresCacheUpdate = false;
     }
 
     private void updateDependencies() {
@@ -429,7 +419,6 @@
             notifyItemAction(mPredictionModel.wrapAppTargetWithLocation(appTarget,
                     AppTargetEvent.ACTION_PIN, workspaceItemInfo));
         }
-        mRequiresCacheUpdate = true;
     }
 
     private List<WorkspaceItemInfo> mapToWorkspaceItemInfo(
@@ -583,7 +572,6 @@
         }
         mDragObject = null;
         fillGapsWithPrediction(true, this::removeOutlineDrawings);
-        mRequiresCacheUpdate = true;
     }
 
 
@@ -655,11 +643,15 @@
                             + ",launchLocation:" + itemInfo.container);
         }
 
-        final ComponentKey k = new ComponentKey(itemInfo.getTargetComponent(), itemInfo.user);
+        if (itemInfo.getTargetComponent() == null || itemInfo.user == null) {
+            return;
+        }
+
+        final ComponentKey key = new ComponentKey(itemInfo.getTargetComponent(), itemInfo.user);
 
         final List<ComponentKeyMapper> predictedApps = new ArrayList<>(mComponentKeyMappers);
         OptionalInt rank = IntStream.range(0, predictedApps.size())
-                .filter((i) -> k.equals(predictedApps.get(i).getComponentKey()))
+                .filter(index -> key.equals(predictedApps.get(index).getComponentKey()))
                 .findFirst();
         if (!rank.isPresent()) {
             return;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
index de83caf..9310685 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
@@ -24,6 +24,7 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorSet;
+import android.app.ActivityManager.RunningTaskInfo;
 import android.util.Log;
 import android.view.animation.Interpolator;
 
@@ -52,17 +53,17 @@
 
     private final BaseActivityInterface<?, T> mActivityInterface;
     // The id of the currently running task that is transitioning to overview.
-    private final int mTargetTaskId;
+    private final RunningTaskInfo mTargetTask;
     private final RecentsAnimationDeviceState mDeviceState;
 
     private T mActivity;
     private RecentsView mRecentsView;
 
     AppToOverviewAnimationProvider(
-            BaseActivityInterface<?, T> activityInterface, int targetTaskId,
+            BaseActivityInterface<?, T> activityInterface, RunningTaskInfo targetTask,
             RecentsAnimationDeviceState deviceState) {
         mActivityInterface = activityInterface;
-        mTargetTaskId = targetTaskId;
+        mTargetTask = targetTask;
         mDeviceState = deviceState;
     }
 
@@ -73,7 +74,7 @@
      * @param wasVisible true if it was visible before
      */
     boolean onActivityReady(T activity, Boolean wasVisible) {
-        activity.<RecentsView>getOverviewPanel().showCurrentTask(mTargetTaskId);
+        activity.<RecentsView>getOverviewPanel().showCurrentTask(mTargetTask);
         AbstractFloatingView.closeAllOpenViews(activity, wasVisible);
         BaseActivityInterface.AnimationFactory factory = mActivityInterface.prepareRecentsUI(
                 mDeviceState,
@@ -122,7 +123,8 @@
                 wallpaperTargets, MODE_CLOSING);
 
         // Use the top closing app to determine the insets for the animation
-        RemoteAnimationTargetCompat runningTaskTarget = targets.findTask(mTargetTaskId);
+        RemoteAnimationTargetCompat runningTaskTarget = mTargetTask == null ? null
+                : targets.findTask(mTargetTask.taskId);
         if (runningTaskTarget == null) {
             Log.e(TAG, "No closing app");
             return pa.buildAnim();
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandlerV2.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandlerV2.java
index db8923d..01e7de3 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandlerV2.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandlerV2.java
@@ -38,7 +38,6 @@
 import static com.android.quickstep.GestureState.STATE_END_TARGET_SET;
 import static com.android.quickstep.GestureState.STATE_RECENTS_SCROLLING_FINISHED;
 import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
-import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
 import static com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState.HIDE;
 import static com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState.PEEK;
 import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
@@ -311,12 +310,6 @@
         }
 
         setupRecentsViewUi();
-
-        if (mDeviceState.getNavMode() == TWO_BUTTONS) {
-            // If the device is in two button mode, swiping up will show overview with predictions
-            // so we need to kick off switching to the overview predictions as soon as possible
-            mActivityInterface.updateOverviewPredictionState();
-        }
         linkRecentsViewScroll();
 
         return true;
@@ -421,7 +414,7 @@
     }
 
     protected void notifyGestureAnimationStartToRecents() {
-        mRecentsView.onGestureAnimationStart(mGestureState.getRunningTaskId());
+        mRecentsView.onGestureAnimationStart(mGestureState.getRunningTask());
     }
 
     private void launcherFrameDrawn() {
@@ -449,12 +442,6 @@
     @Override
     public void onMotionPauseChanged(boolean isPaused) {
         setShelfState(isPaused ? PEEK : HIDE, ShelfPeekAnim.INTERPOLATOR, ShelfPeekAnim.DURATION);
-
-        if (mDeviceState.isFullyGesturalNavMode() && isPaused) {
-            // In fully gestural nav mode, switch to overview predictions once the user has paused
-            // (this is a no-op if the predictions are already in that state)
-            mActivityInterface.updateOverviewPredictionState();
-        }
     }
 
     public void maybeUpdateRecentsAttachedState() {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java
index edefbe1..6621b41 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java
@@ -262,16 +262,6 @@
     }
 
     @Override
-    public void updateOverviewPredictionState() {
-        Launcher launcher = getCreatedActivity();
-        if (launcher == null) {
-            return;
-        }
-        PredictionUiStateManager.INSTANCE.get(launcher).switchClient(
-                PredictionUiStateManager.Client.OVERVIEW);
-    }
-
-    @Override
     public int getContainerType() {
         final Launcher launcher = getVisibleLauncher();
         return launcher != null ? launcher.getStateManager().getState().containerType
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java
index 434a929..dca3378 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java
@@ -29,7 +29,6 @@
 
 import androidx.annotation.BinderThread;
 
-import com.android.launcher3.appprediction.PredictionUiStateManager;
 import com.android.launcher3.logging.UserEventDispatcher;
 import com.android.launcher3.statemanager.StatefulActivity;
 import com.android.launcher3.userevent.nano.LauncherLogProto;
@@ -165,7 +164,7 @@
             mActivityInterface = mOverviewComponentObserver.getActivityInterface();
             mCreateTime = SystemClock.elapsedRealtime();
             mAnimationProvider = new AppToOverviewAnimationProvider<>(mActivityInterface,
-                    RecentsModel.getRunningTaskId(), mDeviceState);
+                    ActivityManagerWrapper.getInstance().getRunningTask(), mDeviceState);
 
             // Preload the plan
             mRecentsModel.getTasks(null);
@@ -227,10 +226,6 @@
                         LauncherLogProto.ContainerType.TASKSWITCHER);
                 mUserEventLogged = true;
             }
-
-            // Switch prediction client to overview
-            PredictionUiStateManager.INSTANCE.get(activity).switchClient(
-                    PredictionUiStateManager.Client.OVERVIEW);
             return mAnimationProvider.onActivityReady(activity, wasVisible);
         }
 
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java
index d20bbe9..ffe9d6a 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -76,7 +76,7 @@
      */
     public void onGestureAnimationStartOnHome(RunningTaskInfo homeTaskInfo) {
         mHomeTaskInfo = homeTaskInfo;
-        onGestureAnimationStart(homeTaskInfo == null ? -1 : homeTaskInfo.taskId);
+        onGestureAnimationStart(homeTaskInfo);
     }
 
     /**
@@ -107,14 +107,15 @@
     }
 
     @Override
-    protected boolean shouldAddDummyTaskView(int runningTaskId) {
-        if (mHomeTaskInfo != null && mHomeTaskInfo.taskId == runningTaskId
+    protected boolean shouldAddDummyTaskView(RunningTaskInfo runningTaskInfo) {
+        if (mHomeTaskInfo != null && runningTaskInfo != null &&
+                mHomeTaskInfo.taskId == runningTaskInfo.taskId
                 && getTaskViewCount() == 0) {
             // Do not add a dummy task if we are running over home with empty recents, so that we
             // show the empty recents message instead of showing a dummy task and later removing it.
             return false;
         }
-        return super.shouldAddDummyTaskView(runningTaskId);
+        return super.shouldAddDummyTaskView(runningTaskInfo);
     }
 
     @Override
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java
index 135ee63..c994aef 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -103,6 +103,7 @@
         mSizeStrategy = sizeStrategy;
 
         mOrientationState = new RecentsOrientedState(context, sizeStrategy, i -> { });
+        mOrientationState.setGestureActive(true);
 
         mCurrentFullscreenParams = new FullscreenDrawParams(context);
         mPageSpacing = context.getResources().getDimensionPixelSize(R.dimen.recents_page_spacing);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/AllAppsEduView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/AllAppsEduView.java
index 0979c07..3d44eb6 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/AllAppsEduView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/AllAppsEduView.java
@@ -16,6 +16,7 @@
 package com.android.quickstep.views;
 
 import static com.android.launcher3.LauncherState.ALL_APPS;
+import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.anim.Interpolators.ACCEL;
 import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
@@ -42,8 +43,10 @@
 import com.android.launcher3.Launcher;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.allapps.AllAppsTransitionController;
 import com.android.launcher3.anim.AnimatorPlaybackController;
 import com.android.launcher3.anim.Interpolators;
+import com.android.launcher3.anim.PendingAnimation;
 import com.android.launcher3.dragndrop.DragLayer;
 import com.android.launcher3.states.StateAnimationConfig;
 import com.android.launcher3.util.Themes;
@@ -139,7 +142,12 @@
         config.userControlled = false;
         AnimatorPlaybackController stateAnimationController =
                 mLauncher.getStateManager().createAnimationToNewWorkspace(ALL_APPS, config);
-        float maxAllAppsProgress = 0.15f;
+        float maxAllAppsProgress = mLauncher.getDeviceProfile().isLandscape ? 0.35f : 0.15f;
+
+        AllAppsTransitionController allAppsController = mLauncher.getAllAppsController();
+        PendingAnimation allAppsAlpha = new PendingAnimation(config.duration);
+        allAppsController.setAlphas(ALL_APPS, config, allAppsAlpha);
+        mAnimation.play(allAppsAlpha.buildAnim());
 
         ValueAnimator intro = ValueAnimator.ofFloat(0, 1f);
         intro.setInterpolator(LINEAR);
@@ -191,7 +199,8 @@
             @Override
             public void onAnimationEnd(Animator animation) {
                 mAnimation = null;
-                stateAnimationController.dispatchOnCancel();
+                // Handles cancelling the animation used to hint towards All Apps.
+                mLauncher.getStateManager().goToState(NORMAL, false);
                 handleClose(false);
             }
         });
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
index 846b944..59c6815 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -41,8 +41,6 @@
 import com.android.launcher3.Hotseat;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.anim.Interpolators;
-import com.android.launcher3.appprediction.PredictionUiStateManager;
-import com.android.launcher3.appprediction.PredictionUiStateManager.Client;
 import com.android.launcher3.model.AppLaunchTracker;
 import com.android.launcher3.statehandlers.DepthController;
 import com.android.launcher3.statemanager.StateManager.StateListener;
@@ -237,9 +235,6 @@
         super.reset();
 
         setLayoutRotation(Surface.ROTATION_0, Surface.ROTATION_0);
-        // We are moving to home or some other UI with no recents. Switch back to the home client,
-        // the home predictions should have been updated when the activity was resumed.
-        PredictionUiStateManager.INSTANCE.get(getContext()).switchClient(Client.HOME);
     }
 
     @Override
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
index 68b8975..9c25b24 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
@@ -56,6 +56,7 @@
 import android.animation.ValueAnimator;
 import android.annotation.TargetApi;
 import android.app.ActivityManager;
+import android.app.ActivityManager.RunningTaskInfo;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -135,6 +136,7 @@
 import com.android.systemui.plugins.ResourceProvider;
 import com.android.systemui.shared.recents.IPinnedStackAnimationListener;
 import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.recents.model.Task.TaskKey;
 import com.android.systemui.shared.recents.model.ThumbnailData;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.LauncherEventUtil;
@@ -147,7 +149,7 @@
 /**
  * A list of recent tasks.
  */
-@TargetApi(Build.VERSION_CODES.P)
+@TargetApi(Build.VERSION_CODES.R)
 public abstract class RecentsView<T extends StatefulActivity> extends PagedView implements
         Insettable, TaskThumbnailCache.HighResLoadingState.HighResLoadingStateChangedCallback,
         InvariantDeviceProfile.OnIDPChangeListener, TaskVisualsChangeListener,
@@ -1003,7 +1005,9 @@
         mDwbToastShown = false;
         mActivity.getSystemUiController().updateUiState(UI_STATE_OVERVIEW, 0);
         LayoutUtils.setViewEnabled(mActionsView, true);
-        mOrientationState.setGestureActive(false);
+        if (mOrientationState.setGestureActive(false)) {
+            updateOrientationHandler();
+        }
     }
 
     public @Nullable TaskView getRunningTaskView() {
@@ -1039,10 +1043,13 @@
     /**
      * Called when a gesture from an app is starting.
      */
-    public void onGestureAnimationStart(int runningTaskId) {
+    public void onGestureAnimationStart(RunningTaskInfo runningTaskInfo) {
         // This needs to be called before the other states are set since it can create the task view
-        mOrientationState.setGestureActive(true);
-        showCurrentTask(runningTaskId);
+        if (mOrientationState.setGestureActive(true)) {
+            updateOrientationHandler();
+        }
+
+        showCurrentTask(runningTaskInfo);
         setEnableFreeScroll(false);
         setEnableDrawingLiveTile(false);
         setRunningTaskHidden(true);
@@ -1104,7 +1111,9 @@
      * Called when a gesture from an app has finished.
      */
     public void onGestureAnimationEnd() {
-        mOrientationState.setGestureActive(false);
+        if (mOrientationState.setGestureActive(false)) {
+            updateOrientationHandler();
+        }
 
         setOnScrollChangeListener(null);
         setEnableFreeScroll(true);
@@ -1120,8 +1129,8 @@
     /**
      * Returns true if we should add a dummy taskView for the running task id
      */
-    protected boolean shouldAddDummyTaskView(int runningTaskId) {
-        return getTaskView(runningTaskId) == null;
+    protected boolean shouldAddDummyTaskView(RunningTaskInfo runningTaskInfo) {
+        return runningTaskInfo != null && getTaskView(runningTaskInfo.taskId) == null;
     }
 
     /**
@@ -1130,8 +1139,8 @@
      * All subsequent calls to reload will keep the task as the first item until {@link #reset()}
      * is called.  Also scrolls the view to this task.
      */
-    public void showCurrentTask(int runningTaskId) {
-        if (shouldAddDummyTaskView(runningTaskId)) {
+    public void showCurrentTask(RunningTaskInfo runningTaskInfo) {
+        if (shouldAddDummyTaskView(runningTaskInfo)) {
             boolean wasEmpty = getChildCount() == 0;
             // Add an empty view for now until the task plan is loaded and applied
             final TaskView taskView = mTaskViewPool.getView();
@@ -1141,10 +1150,7 @@
             }
             // The temporary running task is only used for the duration between the start of the
             // gesture and the task list is loaded and applied
-            mTmpRunningTask = new Task(new Task.TaskKey(runningTaskId, 0, new Intent(),
-                    new ComponentName(getContext(), getClass()), 0, 0), null, null, "", "", 0, 0,
-                    false, true, false, false, new ActivityManager.TaskDescription(), 0,
-                    new ComponentName("", ""), false);
+            mTmpRunningTask = Task.from(new TaskKey(runningTaskInfo), runningTaskInfo, false);
             taskView.bind(mTmpRunningTask, mOrientationState);
 
             // Measure and layout immediately so that the scroll values is updated instantly
@@ -1155,7 +1161,7 @@
         }
 
         boolean runningTaskTileHidden = mRunningTaskTileHidden;
-        setCurrentTask(runningTaskId);
+        setCurrentTask(runningTaskInfo == null ? -1 : runningTaskInfo.taskId);
         setCurrentPage(getRunningTaskIndex());
         setRunningTaskViewShowScreenshot(false);
         setRunningTaskHidden(runningTaskTileHidden);
@@ -1673,7 +1679,7 @@
                 : View.LAYOUT_DIRECTION_RTL);
         mClearAllButton.setRotation(mOrientationHandler.getDegreesRotated());
         mActivity.getDragLayer().recreateControllers();
-        boolean isInLandscape = mOrientationState.getTouchRotation() != 0
+        boolean isInLandscape = mOrientationState.getTouchRotation() != ROTATION_0
                 || mOrientationState.getRecentsActivityRotation() != ROTATION_0;
         mActionsView.updateHiddenFlags(HIDDEN_NON_ZERO_ROTATION,
                 !mOrientationState.canRecentsActivityRotate() && isInLandscape);
diff --git a/quickstep/robolectric_tests/src/com/android/quickstep/RecentsActivityTest.java b/quickstep/robolectric_tests/src/com/android/quickstep/RecentsActivityTest.java
index 93b64e6..c148a4b 100644
--- a/quickstep/robolectric_tests/src/com/android/quickstep/RecentsActivityTest.java
+++ b/quickstep/robolectric_tests/src/com/android/quickstep/RecentsActivityTest.java
@@ -17,6 +17,7 @@
 
 import static com.android.launcher3.util.LauncherUIHelper.doLayout;
 
+import android.app.ActivityManager.RunningTaskInfo;
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.Config;
 
@@ -50,7 +51,7 @@
     }
 
     @Test
-    public void testRecets_showCurrentTask() {
+    public void testRecents_showCurrentTask() {
         ActivityController<RecentsActivity> controller =
                 Robolectric.buildActivity(RecentsActivity.class);
 
@@ -58,7 +59,10 @@
         doLayout(activity);
 
         FallbackRecentsView frv = activity.getOverviewPanel();
-        frv.showCurrentTask(22);
+
+        RunningTaskInfo dummyTask = new RunningTaskInfo();
+        dummyTask.taskId = 22;
+        frv.showCurrentTask(dummyTask);
         doLayout(activity);
 
         ThumbnailData thumbnailData = new ThumbnailData();
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index 47ce320..6b941be 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -157,6 +157,12 @@
     @Override
     protected void onDeferredResumed() {
         super.onDeferredResumed();
+        handlePendingActivityRequest();
+    }
+
+    @Override
+    protected void handlePendingActivityRequest() {
+        super.handlePendingActivityRequest();
         if (mPendingActivityRequestCode != -1 && isInState(NORMAL)) {
             // Remove any active ProxyActivityStarter task and send RESULT_CANCELED to Launcher.
             onActivityResult(mPendingActivityRequestCode, RESULT_CANCELED, null);
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index 2b698bd..bdeb3a6 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -154,13 +154,6 @@
             Runnable exitRunnable);
 
     /**
-     * Updates the prediction state to the overview state.
-     */
-    public void updateOverviewPredictionState() {
-        // By public overview predictions are not supported
-    }
-
-    /**
      * Used for containerType in {@link com.android.launcher3.logging.UserEventDispatcher}
      */
     public abstract int getContainerType();
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index 517501a..6f54ba2 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -93,15 +93,6 @@
     }
 
     /**
-     * @return The task id of the running task, or -1 if there is no current running task.
-     */
-    public static int getRunningTaskId() {
-        ActivityManager.RunningTaskInfo runningTask =
-                ActivityManagerWrapper.getInstance().getRunningTask();
-        return runningTask != null ? runningTask.id : -1;
-    }
-
-    /**
      * @return Whether the provided {@param changeId} is the latest recent tasks list id.
      */
     public boolean isTaskListValid(int changeId) {
@@ -140,7 +131,9 @@
         }
 
         // Keep the cache up to date with the latest thumbnails
-        int runningTaskId = RecentsModel.getRunningTaskId();
+        ActivityManager.RunningTaskInfo runningTask =
+                ActivityManagerWrapper.getInstance().getRunningTask();
+        int runningTaskId = runningTask != null ? runningTask.id : -1;
         mTaskList.getTaskKeys(mThumbnailCache.getCacheSize(), tasks -> {
             for (Task task : tasks) {
                 if (task.key.id == runningTaskId) {
diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
index b359f0f..d822b6c 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
@@ -188,8 +188,9 @@
     /**
      * Sets if the swipe up gesture is currently running or not
      */
-    public void setGestureActive(boolean isGestureActive) {
+    public boolean setGestureActive(boolean isGestureActive) {
         setFlag(FLAG_SWIPE_UP_NOT_RUNNING, !isGestureActive);
+        return update(mTouchRotation, mDisplayRotation);
     }
 
     /**
@@ -202,27 +203,19 @@
      */
     public boolean update(
             @SurfaceRotation int touchRotation, @SurfaceRotation int displayRotation) {
-        int recentsActivityRotation = inferRecentsActivityRotation(displayRotation);
-        if (mDisplayRotation == displayRotation
-                && mTouchRotation == touchRotation
-                && mRecentsActivityRotation == recentsActivityRotation) {
-            return false;
-        }
-
-        mRecentsActivityRotation = recentsActivityRotation;
+        mRecentsActivityRotation = inferRecentsActivityRotation(displayRotation);
         mDisplayRotation = displayRotation;
         mTouchRotation = touchRotation;
         mPreviousRotation = touchRotation;
 
-        if (mRecentsActivityRotation == mTouchRotation || canRecentsActivityRotate()) {
+        PagedOrientationHandler oldHandler = mOrientationHandler;
+        if (mRecentsActivityRotation == mTouchRotation
+                || (canRecentsActivityRotate() && (mFlags & FLAG_SWIPE_UP_NOT_RUNNING) != 0)) {
             mOrientationHandler = PagedOrientationHandler.PORTRAIT;
             if (DEBUG) {
                 Log.d(TAG, "current RecentsOrientedState: " + this);
             }
-            return true;
-        }
-
-        if (mTouchRotation == ROTATION_90) {
+        } else if (mTouchRotation == ROTATION_90) {
             mOrientationHandler = PagedOrientationHandler.LANDSCAPE;
         } else if (mTouchRotation == ROTATION_270) {
             mOrientationHandler = PagedOrientationHandler.SEASCAPE;
@@ -232,7 +225,7 @@
         if (DEBUG) {
             Log.d(TAG, "current RecentsOrientedState: " + this);
         }
-        return true;
+        return oldHandler != mOrientationHandler;
     }
 
     @SurfaceRotation
diff --git a/src/com/android/launcher3/BaseRecyclerView.java b/src/com/android/launcher3/BaseRecyclerView.java
index 8eceec0..41eeb78 100644
--- a/src/com/android/launcher3/BaseRecyclerView.java
+++ b/src/com/android/launcher3/BaseRecyclerView.java
@@ -183,6 +183,10 @@
     public void onScrollStateChanged(int state) {
         super.onScrollStateChanged(state);
 
+        if (TestProtocol.sDebugTracing) {
+            Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "onScrollStateChanged: " + state);
+        }
+
         if (state == SCROLL_STATE_IDLE) {
             AccessibilityManagerCompat.sendScrollFinishedEventToTest(getContext());
         }
@@ -192,6 +196,10 @@
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfo(info);
         if (isLayoutSuppressed()) info.setScrollable(false);
+        if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+            Log.d(TestProtocol.NO_SCROLL_END_WIDGETS,
+                    "onInitializeAccessibilityNodeInfo, scrollable: " + info.isScrollable());
+        }
     }
 
     @Override
@@ -199,8 +207,12 @@
         final boolean changing = frozen != isLayoutSuppressed();
         super.setLayoutFrozen(frozen);
         if (changing) {
-            ActivityContext.lookupContext(getContext()).getDragLayer()
-                    .sendAccessibilityEvent(TYPE_WINDOW_CONTENT_CHANGED);
+            if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+                Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "setLayoutFrozen " + frozen
+                        + " @ " + Log.getStackTraceString(new Throwable()));
+                ActivityContext.lookupContext(getContext()).getDragLayer()
+                        .sendAccessibilityEvent(TYPE_WINDOW_CONTENT_CHANGED);
+            }
         }
     }
 }
\ No newline at end of file
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 0970dae..d06ae7a 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -923,6 +923,7 @@
         DiscoveryBounce.showForHomeIfNeeded(this);
     }
 
+    protected void handlePendingActivityRequest() { }
 
     private void logStopAndResume(int command) {
         int pageIndex = mWorkspace.isOverlayShown() ? -1 : mWorkspace.getCurrentPage();
@@ -1423,7 +1424,8 @@
                 if (!isInState(NORMAL)) {
                     // Only change state, if not already the same. This prevents cancelling any
                     // animations running as part of resume
-                    mStateManager.goToState(NORMAL);
+                    mStateManager.goToState(NORMAL, mStateManager.shouldAnimateStateChange(),
+                            this::handlePendingActivityRequest);
                 }
 
                 // Reset the apps view
diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java
index c78df62..39b0f2f 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -250,7 +250,8 @@
     }
 
     public PageAlphaProvider getWorkspacePageAlphaProvider(Launcher launcher) {
-        if (this != NORMAL || !launcher.getDeviceProfile().shouldFadeAdjacentWorkspaceScreens()) {
+        if ((this != NORMAL && this != HINT_STATE)
+                || !launcher.getDeviceProfile().shouldFadeAdjacentWorkspaceScreens()) {
             return DEFAULT_ALPHA_PROVIDER;
         }
         final int centerPage = launcher.getWorkspace().getNextPage();
diff --git a/src/com/android/launcher3/compat/AccessibilityManagerCompat.java b/src/com/android/launcher3/compat/AccessibilityManagerCompat.java
index 1d32d1d..d86bb17 100644
--- a/src/com/android/launcher3/compat/AccessibilityManagerCompat.java
+++ b/src/com/android/launcher3/compat/AccessibilityManagerCompat.java
@@ -75,6 +75,9 @@
     }
 
     public static void sendScrollFinishedEventToTest(Context context) {
+        if (TestProtocol.sDebugTracing) {
+            Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "sendScrollFinishedEventToTest");
+        }
         final AccessibilityManager accessibilityManager = getAccessibilityManagerForTest(context);
         if (accessibilityManager == null) return;
 
@@ -94,6 +97,9 @@
                 AccessibilityEvent.TYPE_ANNOUNCEMENT);
         e.setClassName(eventTag);
         e.setParcelableData(data);
+        if (TestProtocol.sDebugTracing) {
+            Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "sendEventToTest " + e);
+        }
         accessibilityManager.sendAccessibilityEvent(e);
     }
 
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index d01e189..1c18402 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -241,9 +241,9 @@
         mFolderName.setSelectAllOnFocus(true);
         mFolderName.setInputType(mFolderName.getInputType()
                 & ~InputType.TYPE_TEXT_FLAG_AUTO_CORRECT
-                & ~InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
+                | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
                 | InputType.TYPE_TEXT_FLAG_CAP_WORDS);
-        mFolderName.forceDisableSuggestions(!FeatureFlags.FOLDER_NAME_SUGGEST.get());
+        mFolderName.forceDisableSuggestions(true);
 
         mFooter = findViewById(R.id.folder_footer);
 
diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java
index 8165627..2644db8 100644
--- a/src/com/android/launcher3/testing/TestProtocol.java
+++ b/src/com/android/launcher3/testing/TestProtocol.java
@@ -107,4 +107,5 @@
     public static final String PAUSE_NOT_DETECTED = "b/139891609";
     public static final String OVERIEW_NOT_ALLAPPS = "b/156095088";
     public static final String NO_SWIPE_TO_HOME = "b/158017601";
+    public static final String NO_SCROLL_END_WIDGETS = "b/160238801";
 }
diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java
index b010b4b..2c75c74 100644
--- a/src/com/android/launcher3/views/BaseDragLayer.java
+++ b/src/com/android/launcher3/views/BaseDragLayer.java
@@ -292,6 +292,9 @@
 
     @Override
     public boolean dispatchTouchEvent(MotionEvent ev) {
+        if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+            Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "BaseDragLayer: " + ev);
+        }
         switch (ev.getAction()) {
             case ACTION_DOWN: {
                 if ((mTouchDispatchState & TOUCH_DISPATCHING_TO_VIEW_IN_PROGRESS) != 0) {
diff --git a/src/com/android/launcher3/widget/WidgetsFullSheet.java b/src/com/android/launcher3/widget/WidgetsFullSheet.java
index 68a3ec5..ba55f5a 100644
--- a/src/com/android/launcher3/widget/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/WidgetsFullSheet.java
@@ -24,6 +24,7 @@
 import android.content.Context;
 import android.graphics.Rect;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.util.Pair;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -38,8 +39,10 @@
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherAppWidgetHost.ProviderChangedListener;
 import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.PendingAnimation;
 import com.android.launcher3.compat.AccessibilityManagerCompat;
+import com.android.launcher3.testing.TestProtocol;
 import com.android.launcher3.views.RecyclerViewFastScroller;
 import com.android.launcher3.views.TopRoundedCornerView;
 
@@ -68,6 +71,14 @@
 
     }
 
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+            Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "WidgetsFullSheet: " + ev);
+        }
+        return super.dispatchTouchEvent(ev);
+    }
+
     public WidgetsFullSheet(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
diff --git a/src/com/android/launcher3/widget/WidgetsRecyclerView.java b/src/com/android/launcher3/widget/WidgetsRecyclerView.java
index 82d4110..17baa27 100644
--- a/src/com/android/launcher3/widget/WidgetsRecyclerView.java
+++ b/src/com/android/launcher3/widget/WidgetsRecyclerView.java
@@ -158,13 +158,23 @@
                     mScrollbar.isHitInParent(e.getX(), e.getY(), mFastScrollerOffset);
         }
         if (mTouchDownOnScroller) {
-            return mScrollbar.handleTouchEvent(e, mFastScrollerOffset);
+            final boolean result = mScrollbar.handleTouchEvent(e, mFastScrollerOffset);
+            if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+                Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "onInterceptTouchEvent 1 " + result);
+            }
+            return result;
+        }
+        if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+            Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "onInterceptTouchEvent 2 false");
         }
         return false;
     }
 
     @Override
     public void onTouchEvent(RecyclerView rv, MotionEvent e) {
+        if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+            Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "WidgetsRecyclerView.onTouchEvent");
+        }
         if (mTouchDownOnScroller) {
             mScrollbar.handleTouchEvent(e, mFastScrollerOffset);
         }
@@ -172,5 +182,31 @@
 
     @Override
     public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
+        if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+            Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "onRequestDisallowInterceptTouchEvent "
+                    + disallowIntercept);
+        }
+    }
+
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        final boolean result = super.dispatchTouchEvent(ev);
+        if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+            Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "WidgetsRecyclerView: state: "
+                    + getScrollState()
+                    + " can scroll: " + getLayoutManager().canScrollVertically()
+                    + " result: " + result
+                    + " layout suppressed: " + isLayoutSuppressed()
+                    + " event: " + ev);
+        }
+        return result;
+    }
+
+    @Override
+    public void stopNestedScroll() {
+        if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+            Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "stopNestedScroll");
+        }
+        super.stopNestedScroll();
     }
 }
\ No newline at end of file
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 5cf5d0f..0cf611a 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -635,9 +635,11 @@
     Parcelable executeAndWaitForEvent(Runnable command,
             UiAutomation.AccessibilityEventFilter eventFilter, Supplier<String> message) {
         try {
+            Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "executeAndWaitForEvent: before");
             final AccessibilityEvent event =
                     mInstrumentation.getUiAutomation().executeAndWaitForEvent(
                             command, eventFilter, WAIT_TIME_MS);
+            Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "executeAndWaitForEvent: after");
             assertNotNull("executeAndWaitForEvent returned null (this can't happen)", event);
             final Parcelable parcelableData = event.getParcelableData();
             event.recycle();
@@ -1094,7 +1096,10 @@
         executeAndWaitForEvent(
                 () -> linearGesture(
                         startX, startY, endX, endY, steps, slowDown, GestureScope.INSIDE),
-                event -> TestProtocol.SCROLL_FINISHED_MESSAGE.equals(event.getClassName()),
+                event -> {
+                    Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "scroll: received event: " + event);
+                    return TestProtocol.SCROLL_FINISHED_MESSAGE.equals(event.getClassName());
+                },
                 () -> "Didn't receive a scroll end message: " + startX + ", " + startY
                         + ", " + endX + ", " + endY);
     }