[automerger skipped] Merge "[DO NOT MERGE ANYWHERE] Add swipes left method in Background.java" into rvc-dev am: 57874e6b39 -s ours

am skip reason: subject contains skip directive

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/12793279

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I3eeabee22f4b278eb079424059eed871c8fd5f39
diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml
index dd0fc21..ff5bf0d 100644
--- a/AndroidManifest-common.xml
+++ b/AndroidManifest-common.xml
@@ -156,8 +156,7 @@
         <provider
             android:name="com.android.launcher3.graphics.GridOptionsProvider"
             android:authorities="${packageName}.grid_control"
-            android:exported="true"
-            android:enabled="false" />
+            android:exported="true" />
 
         <!--
         The settings activity. To extend point settings_fragment_name to appropriate fragment class
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 a63f3a8..aba5ab6 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
@@ -39,6 +39,7 @@
 import com.android.quickstep.RecentsAnimationCallbacks.RecentsAnimationListener;
 import com.android.quickstep.util.ActiveGestureLog;
 import com.android.quickstep.util.ActivityInitListener;
+import com.android.quickstep.util.InputConsumerProxy;
 import com.android.quickstep.util.RectFSpringAnim;
 import com.android.quickstep.util.SurfaceTransactionApplier;
 import com.android.quickstep.util.TransformParams;
@@ -61,7 +62,7 @@
     private static final String TAG = "BaseSwipeUpHandler";
 
     protected final BaseActivityInterface<?, T> mActivityInterface;
-    protected final InputConsumerController mInputConsumer;
+    protected final InputConsumerProxy mInputConsumerProxy;
 
     protected final ActivityInitListener mActivityInitListener;
 
@@ -87,7 +88,8 @@
         super(context, deviceState, gestureState, new TransformParams());
         mActivityInterface = gestureState.getActivityInterface();
         mActivityInitListener = mActivityInterface.createActivityInitListener(this::onActivityInit);
-        mInputConsumer = inputConsumer;
+        mInputConsumerProxy =
+                new InputConsumerProxy(inputConsumer, this::createNewInputProxyHandler);
     }
 
     /**
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 6c4c5d3..f0f3d0f 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandlerV2.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandlerV2.java
@@ -850,11 +850,9 @@
             }
         }
 
-        if (endTarget.isLauncher && mRecentsAnimationController != null) {
-            mRecentsAnimationController.enableInputProxy(mInputConsumer,
-                    this::createNewInputProxyHandler);
+        if (endTarget.isLauncher) {
+            mInputConsumerProxy.enable();
         }
-
         if (endTarget == HOME) {
             setShelfState(ShelfAnimState.CANCEL, LINEAR, 0);
             duration = Math.max(MIN_OVERSHOOT_DURATION, duration);
@@ -1181,6 +1179,7 @@
     }
 
     private void invalidateHandler() {
+        mInputConsumerProxy.destroy();
         endRunningWindowAnim(false /* cancel */);
 
         if (mGestureEndCallback != null) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/InputConsumerProxy.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/InputConsumerProxy.java
new file mode 100644
index 0000000..3e87f48
--- /dev/null
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/InputConsumerProxy.java
@@ -0,0 +1,118 @@
+/*
+ * 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.quickstep.util;
+
+import static android.view.MotionEvent.ACTION_CANCEL;
+import static android.view.MotionEvent.ACTION_DOWN;
+import static android.view.MotionEvent.ACTION_UP;
+
+import android.util.Log;
+import android.view.InputEvent;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+import com.android.quickstep.InputConsumer;
+import com.android.systemui.shared.system.InputConsumerController;
+
+import java.util.function.Supplier;
+
+/**
+ * Utility class which manages proxying input events from {@link InputConsumerController}
+ * to an {@link InputConsumer}
+ */
+public class InputConsumerProxy {
+
+    private static final String TAG = "InputConsumerProxy";
+
+    private final InputConsumerController mInputConsumerController;
+    private final Supplier<InputConsumer> mConsumerSupplier;
+
+    // The consumer is created lazily on demand.
+    private InputConsumer mInputConsumer;
+
+    private boolean mDestroyed = false;
+    private boolean mTouchInProgress = false;
+    private boolean mDestroyPending = false;
+
+    public InputConsumerProxy(InputConsumerController inputConsumerController,
+            Supplier<InputConsumer> consumerSupplier) {
+        mInputConsumerController = inputConsumerController;
+        mConsumerSupplier = consumerSupplier;
+    }
+
+    public void enable() {
+        if (mDestroyed) {
+            return;
+        }
+        mInputConsumerController.setInputListener(this::onInputConsumerEvent);
+    }
+
+    private boolean onInputConsumerEvent(InputEvent ev) {
+        if (ev instanceof MotionEvent) {
+            onInputConsumerMotionEvent((MotionEvent) ev);
+        } else if (ev instanceof KeyEvent) {
+            if (mInputConsumer == null) {
+                mInputConsumer = mConsumerSupplier.get();
+            }
+            mInputConsumer.onKeyEvent((KeyEvent) ev);
+            return true;
+        }
+        return false;
+    }
+
+    private boolean onInputConsumerMotionEvent(MotionEvent ev) {
+        int action = ev.getAction();
+
+        // Just to be safe, verify that ACTION_DOWN comes before any other action,
+        // and ignore any ACTION_DOWN after the first one (though that should not happen).
+        if (!mTouchInProgress && action != ACTION_DOWN) {
+            Log.w(TAG, "Received non-down motion before down motion: " + action);
+            return false;
+        }
+        if (mTouchInProgress && action == ACTION_DOWN) {
+            Log.w(TAG, "Received down motion while touch was already in progress");
+            return false;
+        }
+
+        if (action == ACTION_DOWN) {
+            mTouchInProgress = true;
+            if (mInputConsumer == null) {
+                mInputConsumer = mConsumerSupplier.get();
+            }
+        } else if (action == ACTION_CANCEL || action == ACTION_UP) {
+            // Finish any pending actions
+            mTouchInProgress = false;
+            if (mDestroyPending) {
+                destroy();
+            }
+        }
+        if (mInputConsumer != null) {
+            mInputConsumer.onMotionEvent(ev);
+        }
+
+        return true;
+    }
+
+    public void destroy() {
+        if (mTouchInProgress) {
+            mDestroyPending = true;
+            return;
+        }
+        mDestroyPending = false;
+        mDestroyed = true;
+        mInputConsumerController.setInputListener(null);
+    }
+}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationController.java b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
index 4e9aa61..51f5e5d 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationController.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
@@ -15,49 +15,30 @@
  */
 package com.android.quickstep;
 
-import static android.view.MotionEvent.ACTION_CANCEL;
-import static android.view.MotionEvent.ACTION_DOWN;
-import static android.view.MotionEvent.ACTION_UP;
-
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
 
-import android.os.SystemClock;
-import android.util.Log;
-import android.view.InputEvent;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-
 import androidx.annotation.NonNull;
 import androidx.annotation.UiThread;
 
 import com.android.launcher3.util.Preconditions;
 import com.android.systemui.shared.recents.model.ThumbnailData;
-import com.android.systemui.shared.system.InputConsumerController;
 import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
 
 import java.util.function.Consumer;
-import java.util.function.Supplier;
 
 /**
  * Wrapper around RecentsAnimationControllerCompat to help with some synchronization
  */
 public class RecentsAnimationController {
 
-    private static final String TAG = "RecentsAnimationController";
-
     private final RecentsAnimationControllerCompat mController;
     private final Consumer<RecentsAnimationController> mOnFinishedListener;
     private final boolean mAllowMinimizeSplitScreen;
 
-    private InputConsumerController mInputConsumerController;
-    private Supplier<InputConsumer> mInputProxySupplier;
-    private InputConsumer mInputConsumer;
     private boolean mUseLauncherSysBarFlags = false;
     private boolean mSplitScreenMinimized = false;
-    private boolean mTouchInProgress;
-    private boolean mDisableInputProxyPending;
 
     public RecentsAnimationController(RecentsAnimationControllerCompat controller,
             boolean allowMinimizeSplitScreen,
@@ -136,12 +117,12 @@
 
     @UiThread
     public void finishAnimationToHome() {
-        finishAndDisableInputProxy(true /* toRecents */, null, false /* sendUserLeaveHint */);
+        finishController(true /* toRecents */, null, false /* sendUserLeaveHint */);
     }
 
     @UiThread
     public void finishAnimationToApp() {
-        finishAndDisableInputProxy(false /* toRecents */, null, false /* sendUserLeaveHint */);
+        finishController(false /* toRecents */, null, false /* sendUserLeaveHint */);
     }
 
     /** See {@link #finish(boolean, Runnable, boolean)} */
@@ -160,18 +141,6 @@
     @UiThread
     public void finish(boolean toRecents, Runnable onFinishComplete, boolean sendUserLeaveHint) {
         Preconditions.assertUIThread();
-        if (toRecents && mTouchInProgress) {
-            // Finish the controller as requested, but don't disable input proxy yet.
-            mDisableInputProxyPending = true;
-            finishController(toRecents, onFinishComplete, sendUserLeaveHint);
-        } else {
-            finishAndDisableInputProxy(toRecents, onFinishComplete, sendUserLeaveHint);
-        }
-    }
-
-    private void finishAndDisableInputProxy(boolean toRecents, Runnable onFinishComplete,
-            boolean sendUserLeaveHint) {
-        disableInputProxy();
         finishController(toRecents, onFinishComplete, sendUserLeaveHint);
     }
 
@@ -179,7 +148,6 @@
     public void finishController(boolean toRecents, Runnable callback, boolean sendUserLeaveHint) {
         mOnFinishedListener.accept(this);
         UI_HELPER_EXECUTOR.execute(() -> {
-            mController.setInputConsumerEnabled(false);
             mController.finish(toRecents, sendUserLeaveHint);
             if (callback != null) {
                 MAIN_EXECUTOR.execute(callback);
@@ -197,75 +165,8 @@
         });
     }
 
-    public void enableInputProxy(InputConsumerController inputConsumerController,
-            Supplier<InputConsumer> inputProxySupplier) {
-        mInputProxySupplier = inputProxySupplier;
-        mInputConsumerController = inputConsumerController;
-        mInputConsumerController.setInputListener(this::onInputConsumerEvent);
-    }
-
     /** @return wrapper controller. */
     public RecentsAnimationControllerCompat getController() {
         return mController;
     }
-
-    private void disableInputProxy() {
-        if (mInputConsumer != null && mTouchInProgress) {
-            long now = SystemClock.uptimeMillis();
-            MotionEvent dummyCancel = MotionEvent.obtain(now,  now, ACTION_CANCEL, 0, 0, 0);
-            mInputConsumer.onMotionEvent(dummyCancel);
-            dummyCancel.recycle();
-        }
-        if (mInputConsumerController != null) {
-            mInputConsumerController.setInputListener(null);
-        }
-        mInputProxySupplier = null;
-    }
-
-    private boolean onInputConsumerEvent(InputEvent ev) {
-        if (ev instanceof MotionEvent) {
-            onInputConsumerMotionEvent((MotionEvent) ev);
-        } else if (ev instanceof KeyEvent) {
-            if (mInputConsumer == null) {
-                mInputConsumer = mInputProxySupplier.get();
-            }
-            mInputConsumer.onKeyEvent((KeyEvent) ev);
-            return true;
-        }
-        return false;
-    }
-
-    private boolean onInputConsumerMotionEvent(MotionEvent ev) {
-        int action = ev.getAction();
-
-        // Just to be safe, verify that ACTION_DOWN comes before any other action,
-        // and ignore any ACTION_DOWN after the first one (though that should not happen).
-        if (!mTouchInProgress && action != ACTION_DOWN) {
-            Log.w(TAG, "Received non-down motion before down motion: " + action);
-            return false;
-        }
-        if (mTouchInProgress && action == ACTION_DOWN) {
-            Log.w(TAG, "Received down motion while touch was already in progress");
-            return false;
-        }
-
-        if (action == ACTION_DOWN) {
-            mTouchInProgress = true;
-            if (mInputConsumer == null) {
-                mInputConsumer = mInputProxySupplier.get();
-            }
-        } else if (action == ACTION_CANCEL || action == ACTION_UP) {
-            // Finish any pending actions
-            mTouchInProgress = false;
-            if (mDisableInputProxyPending) {
-                mDisableInputProxyPending = false;
-                disableInputProxy();
-            }
-        }
-        if (mInputConsumer != null) {
-            mInputConsumer.onMotionEvent(ev);
-        }
-
-        return true;
-    }
 }
diff --git a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
index a5d4568..f60f7ad 100644
--- a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
+++ b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
@@ -276,7 +276,7 @@
         private static final int HISTORY_SIZE = 20;
 
         // Position history are stored in a circular array
-        private final float[] mHistoricTimes = new float[HISTORY_SIZE];
+        private final long[] mHistoricTimes = new long[HISTORY_SIZE];
         private final float[] mHistoricPos = new float[HISTORY_SIZE];
         private int mHistoryCount = 0;
         private int mHistoryStart = 0;
@@ -292,7 +292,7 @@
             mHistoryCount = mHistoryStart = 0;
         }
 
-        private void addPositionAndTime(float eventTime, float eventPosition) {
+        private void addPositionAndTime(long eventTime, float eventPosition) {
             mHistoricTimes[mHistoryStart] = eventTime;
             mHistoricPos[mHistoryStart] = eventPosition;
             mHistoryStart++;
@@ -322,7 +322,7 @@
          * Based on solveUnweightedLeastSquaresDeg2 in VelocityTracker.cpp
          */
         private Float solveUnweightedLeastSquaresDeg2(final int pointPos) {
-            final float eventTime = mHistoricTimes[pointPos];
+            final long eventTime = mHistoricTimes[pointPos];
 
             float sxi = 0, sxiyi = 0, syi = 0, sxi2 = 0, sxi3 = 0, sxi2yi = 0, sxi4 = 0;
             int count = 0;
@@ -332,8 +332,8 @@
                     index += HISTORY_SIZE;
                 }
 
-                float time = mHistoricTimes[index];
-                float age = eventTime - time;
+                long time = mHistoricTimes[index];
+                long age = eventTime - time;
                 if (age > HORIZON_MS) {
                     break;
                 }
@@ -358,18 +358,23 @@
 
             if (count < 3) {
                 // Too few samples
-                if (count == 2) {
-                    int endPos = pointPos - 1;
-                    if (endPos < 0) {
-                        endPos += HISTORY_SIZE;
+                switch (count) {
+                    case 2: {
+                        int endPos = pointPos - 1;
+                        if (endPos < 0) {
+                            endPos += HISTORY_SIZE;
+                        }
+                        long denominator = eventTime - mHistoricTimes[endPos];
+                        if (denominator != 0) {
+                            return (mHistoricPos[pointPos] - mHistoricPos[endPos]) / denominator;
+                        }
                     }
-                    float denominator = eventTime - mHistoricTimes[endPos];
-                    if (denominator != 0) {
-                        return (eventTime - mHistoricPos[endPos]) / denominator;
-
-                    }
+                    // fall through
+                    case 1:
+                        return 0f;
+                    default:
+                        return null;
                 }
-                return null;
             }
 
             float Sxx = sxi2 - sxi * sxi / count;
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/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
index 885fb66..458ffa3 100644
--- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
+++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
@@ -28,6 +28,7 @@
 import android.annotation.TargetApi;
 import android.app.Fragment;
 import android.appwidget.AppWidgetHostView;
+import android.appwidget.AppWidgetProviderInfo;
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.content.Intent;
@@ -56,6 +57,7 @@
 import com.android.launcher3.InsettableFrameLayout;
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherAppWidgetProviderInfo;
 import com.android.launcher3.LauncherModel;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.LauncherSettings.Favorites;
@@ -83,6 +85,7 @@
 import com.android.launcher3.pm.UserCache;
 import com.android.launcher3.uioverrides.PredictedAppIconInflater;
 import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
+import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.IntArray;
 import com.android.launcher3.util.MainThreadInitializedObject;
 import com.android.launcher3.views.ActivityContext;
@@ -339,14 +342,33 @@
             addInScreenFromBind(folderIcon, info);
         }
 
+        private void inflateAndAddWidgets(LauncherAppWidgetInfo info,
+                Map<ComponentKey, AppWidgetProviderInfo> widgetProviderInfoMap) {
+            if (widgetProviderInfoMap == null) {
+                return;
+            }
+            AppWidgetProviderInfo providerInfo = widgetProviderInfoMap.get(
+                    new ComponentKey(info.providerName, info.user));
+            if (providerInfo == null) {
+                return;
+            }
+            inflateAndAddWidgets(info, LauncherAppWidgetProviderInfo.fromProviderInfo(
+                    getApplicationContext(), providerInfo));
+        }
+
         private void inflateAndAddWidgets(LauncherAppWidgetInfo info, WidgetsModel widgetsModel) {
             WidgetItem widgetItem = widgetsModel.getWidgetProviderInfoByProviderName(
                     info.providerName);
             if (widgetItem == null) {
                 return;
             }
+            inflateAndAddWidgets(info, widgetItem.widgetInfo);
+        }
+
+        private void inflateAndAddWidgets(LauncherAppWidgetInfo info,
+                LauncherAppWidgetProviderInfo providerInfo) {
             AppWidgetHostView view = new AppWidgetHostView(mContext);
-            view.setAppWidget(-1, widgetItem.widgetInfo);
+            view.setAppWidget(-1, providerInfo);
             view.updateAppWidget(null);
             view.setTag(info);
             addInScreenFromBind(view, info);
@@ -433,8 +455,13 @@
                     switch (itemInfo.itemType) {
                         case Favorites.ITEM_TYPE_APPWIDGET:
                         case Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:
-                            inflateAndAddWidgets((LauncherAppWidgetInfo) itemInfo,
-                                    workspaceResult.mWidgetsModel);
+                            if (mMigrated) {
+                                inflateAndAddWidgets((LauncherAppWidgetInfo) itemInfo,
+                                        workspaceResult.mWidgetProvidersMap);
+                            } else {
+                                inflateAndAddWidgets((LauncherAppWidgetInfo) itemInfo,
+                                        workspaceResult.mWidgetsModel);
+                            }
                             break;
                         default:
                             break;
@@ -542,7 +569,7 @@
             }
 
             return new WorkspaceResult(mBgDataModel.workspaceItems, mBgDataModel.appWidgets,
-                    mBgDataModel.cachedPredictedItems, mBgDataModel.widgetsModel);
+                    mBgDataModel.cachedPredictedItems, mBgDataModel.widgetsModel, null);
         }
     }
 
@@ -569,9 +596,8 @@
         public WorkspaceResult call() throws Exception {
             List<ShortcutInfo> allShortcuts = new ArrayList<>();
             loadWorkspace(allShortcuts, LauncherSettings.Favorites.PREVIEW_CONTENT_URI);
-            mBgDataModel.widgetsModel.update(mApp, null);
             return new WorkspaceResult(mBgDataModel.workspaceItems, mBgDataModel.appWidgets,
-                    mBgDataModel.cachedPredictedItems, mBgDataModel.widgetsModel);
+                    mBgDataModel.cachedPredictedItems, null, mWidgetProvidersMap);
         }
     }
 
@@ -593,14 +619,17 @@
         private final ArrayList<LauncherAppWidgetInfo> mAppWidgets;
         private final ArrayList<AppInfo> mCachedPredictedItems;
         private final WidgetsModel mWidgetsModel;
+        private final Map<ComponentKey, AppWidgetProviderInfo> mWidgetProvidersMap;
 
         private WorkspaceResult(ArrayList<ItemInfo> workspaceItems,
                 ArrayList<LauncherAppWidgetInfo> appWidgets,
-                ArrayList<AppInfo> cachedPredictedItems, WidgetsModel widgetsModel) {
+                ArrayList<AppInfo> cachedPredictedItems, WidgetsModel widgetsModel,
+                Map<ComponentKey, AppWidgetProviderInfo> widgetProviderInfoMap) {
             mWorkspaceItems = workspaceItems;
             mAppWidgets = appWidgets;
             mCachedPredictedItems = cachedPredictedItems;
             mWidgetsModel = widgetsModel;
+            mWidgetProvidersMap = widgetProviderInfoMap;
         }
     }
 }
diff --git a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
index ebdfa8c..79467d3 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
@@ -406,7 +406,7 @@
          * to speed up the search.
          */
         private boolean findPlacement(DbEntry entry) {
-            for (int y = mNextStartY; y > 0; y--) {
+            for (int y = mNextStartY; y >= (mScreenId == 0 ? 1 /* smartspace */ : 0); y--) {
                 for (int x = mNextStartX; x < mTrgX; x++) {
                     boolean fits = mOccupied.isRegionVacant(x, y, entry.spanX, entry.spanY);
                     boolean minFits = mOccupied.isRegionVacant(x, y, entry.minSpanX,
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index 102ec31..4a64522 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -126,6 +126,8 @@
 
     private final UserManagerState mUserManagerState = new UserManagerState();
 
+    protected Map<ComponentKey, AppWidgetProviderInfo> mWidgetProvidersMap;
+
     private boolean mStopped;
 
     public LoaderTask(LauncherAppState app, AllAppsList bgAllAppsList, BgDataModel dataModel,
@@ -342,8 +344,6 @@
                     contentResolver.query(contentUri, null, null, null, null), contentUri, mApp,
                     mUserManagerState);
 
-            Map<ComponentKey, AppWidgetProviderInfo> widgetProvidersMap = null;
-
             try {
                 final int appWidgetIdIndex = c.getColumnIndexOrThrow(
                         LauncherSettings.Favorites.APPWIDGET_ID);
@@ -650,10 +650,11 @@
                             final boolean wasProviderReady = !c.hasRestoreFlag(
                                     LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY);
 
-                            if (widgetProvidersMap == null) {
-                                widgetProvidersMap = WidgetManagerHelper.getAllProvidersMap(context);
+                            if (mWidgetProvidersMap == null) {
+                                mWidgetProvidersMap = WidgetManagerHelper.getAllProvidersMap(
+                                        context);
                             }
-                            final AppWidgetProviderInfo provider = widgetProvidersMap.get(
+                            final AppWidgetProviderInfo provider = mWidgetProvidersMap.get(
                                     new ComponentKey(component, c.user));
 
                             final boolean isProviderReady = isValidProvider(provider);
diff --git a/src/com/android/launcher3/widget/PendingAppWidgetHostView.java b/src/com/android/launcher3/widget/PendingAppWidgetHostView.java
index 9021d9e..ca47728 100644
--- a/src/com/android/launcher3/widget/PendingAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/PendingAppWidgetHostView.java
@@ -52,7 +52,6 @@
     private static final float MIN_SATUNATION = 0.7f;
 
     private final Rect mRect = new Rect();
-    private View mDefaultView;
     private OnClickListener mClickListener;
     private final LauncherAppWidgetInfo mInfo;
     private final int mStartState;
@@ -111,12 +110,11 @@
 
     @Override
     protected View getDefaultView() {
-        if (mDefaultView == null) {
-            mDefaultView = mInflater.inflate(R.layout.appwidget_not_ready, this, false);
-            mDefaultView.setOnClickListener(this);
-            applyState();
-        }
-        return mDefaultView;
+        View defaultView = mInflater.inflate(R.layout.appwidget_not_ready, this, false);
+        defaultView.setOnClickListener(this);
+        applyState();
+        invalidate();
+        return defaultView;
     }
 
     @Override
diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java
index b3d487e..ce94a3e 100644
--- a/tests/tapl/com/android/launcher3/tapl/Background.java
+++ b/tests/tapl/com/android/launcher3/tapl/Background.java
@@ -211,65 +211,6 @@
         mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, TASK_START_EVENT);
     }
 
-    /** Swipes left to switch to the previous app. */
-    public Background quickSwitchToPreviousAppSwipeLeft() {
-        try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
-            LauncherInstrumentation.Closable c =
-                mLauncher.addContextLayer("want to quick switch to the previous app")) {
-            verifyActiveContainer();
-            quickSwitchToPreviousAppSwipeLeft(getExpectedStateForQuickSwitch());
-            return new Background(mLauncher);
-        }
-    }
-
-    protected void quickSwitchToPreviousAppSwipeLeft(int expectedState) {
-        final boolean launcherWasVisible = mLauncher.isLauncherVisible();
-        boolean transposeInLandscape = false;
-        switch (mLauncher.getNavigationModel()) {
-            case TWO_BUTTON:
-                transposeInLandscape = true;
-                // Fall through, zero button and two button modes behave the same.
-            case ZERO_BUTTON: {
-                final int startX;
-                final int startY;
-                final int endX;
-                final int endY;
-                if (mLauncher.getDevice().isNaturalOrientation() || !transposeInLandscape) {
-                    // Swipe from the bottom right to the bottom left of the screen.
-                    startX = mLauncher.getDevice().getDisplayWidth();
-                    startY = getSwipeStartY();
-                    endX = 0;
-                    endY = startY;
-                } else {
-                    // Swipe from the bottom right to the top right of the screen.
-                    startX = getSwipeStartX();
-                    startY = mLauncher.getRealDisplaySize().y - 1;
-                    endX = startX;
-                    endY = 0;
-                }
-                final boolean isZeroButton =
-                        mLauncher.getNavigationModel()
-                        == LauncherInstrumentation.NavigationModel.ZERO_BUTTON;
-                mLauncher.swipeToState(startX, startY, endX, endY, 20, expectedState,
-                        launcherWasVisible && isZeroButton
-                                ? LauncherInstrumentation.GestureScope.INSIDE_TO_OUTSIDE
-                                : LauncherInstrumentation.GestureScope.OUTSIDE);
-                break;
-            }
-
-            case THREE_BUTTON:
-                // Double press the recents button.
-                UiObject2 recentsButton = mLauncher.waitForSystemUiObject("recent_apps");
-                mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, SQUARE_BUTTON_EVENT);
-                mLauncher.runToState(() -> recentsButton.click(), OVERVIEW_STATE_ORDINAL);
-                mLauncher.getOverview();
-                mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, SQUARE_BUTTON_EVENT);
-                recentsButton.click();
-                break;
-        }
-        mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, TASK_START_EVENT);
-    }
-
     protected String getSwipeHeightRequestName() {
         return TestProtocol.REQUEST_BACKGROUND_TO_OVERVIEW_SWIPE_HEIGHT;
     }