Merge "Don't recreate taskbar in Overview" into main
diff --git a/quickstep/dagger/LauncherAppComponent.java b/quickstep/dagger/com/android/launcher3/dagger/LauncherAppComponent.java
similarity index 91%
rename from quickstep/dagger/LauncherAppComponent.java
rename to quickstep/dagger/com/android/launcher3/dagger/LauncherAppComponent.java
index 068f01c..a4cb420 100644
--- a/quickstep/dagger/LauncherAppComponent.java
+++ b/quickstep/dagger/com/android/launcher3/dagger/LauncherAppComponent.java
@@ -17,7 +17,6 @@
 package com.android.launcher3.dagger;
 
 
-import com.android.quickstep.dagger.QuickStepModule;
 import com.android.quickstep.dagger.QuickstepBaseAppComponent;
 
 import dagger.Component;
@@ -26,7 +25,7 @@
  * Root component for Dagger injection for Launcher Quickstep.
  */
 @LauncherAppSingleton
-@Component(modules = QuickStepModule.class)
+@Component(modules = LauncherAppModule.class)
 public interface LauncherAppComponent extends QuickstepBaseAppComponent {
     /** Builder for quickstep LauncherAppComponent. */
     @Component.Builder
diff --git a/quickstep/dagger/com/android/launcher3/dagger/LauncherAppModule.java b/quickstep/dagger/com/android/launcher3/dagger/LauncherAppModule.java
new file mode 100644
index 0000000..1711fc1
--- /dev/null
+++ b/quickstep/dagger/com/android/launcher3/dagger/LauncherAppModule.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.dagger;
+
+import com.android.quickstep.dagger.QuickStepModule;
+
+import dagger.Module;
+
+@Module(includes = QuickStepModule.class)
+public class LauncherAppModule {}
diff --git a/quickstep/res/layout/floating_header_content.xml b/quickstep/res/layout/floating_header_content.xml
index b21c34b..0021e22 100644
--- a/quickstep/res/layout/floating_header_content.xml
+++ b/quickstep/res/layout/floating_header_content.xml
@@ -3,8 +3,8 @@
 
     <com.android.launcher3.appprediction.PredictionRowView
         android:id="@+id/prediction_row"
-        android:accessibilityPaneTitle="@string/title_app_suggestions"
         android:layout_width="match_parent"
+        android:importantForAccessibility="yes"
         android:layout_height="wrap_content" />
 
     <com.android.launcher3.appprediction.AppsDividerView
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index 026e25c..df949c3 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -125,8 +125,6 @@
     <string name="back_gesture_intro_title">Swipe to go back</string>
     <!-- Introduction subtitle for the Back gesture tutorial. [CHAR LIMIT=200] -->
     <string name="back_gesture_intro_subtitle">To go back to the last screen, swipe from the left or right edge to the middle of the screen.</string>
-    <!-- Introduction subtitle for the Back gesture tutorial that will be spoken by screen readers. [CHAR LIMIT=200] -->
-    <string name="back_gesture_spoken_intro_subtitle">To go back to the last screen, swipe with 2 fingers from the left or right edge to the middle of the screen.</string>
     <!-- Title of the gesture tutorial section educating users on how to go back to the previous screen. [CHAR LIMIT=100] -->
     <string name="back_gesture_tutorial_title">Go back</string>
     <!-- Subtitle of the gesture tutorial section educating users on how to go to back to the previous screen [CHAR LIMIT=100] -->
@@ -145,8 +143,6 @@
     <string name="home_gesture_intro_title">Swipe to go home</string>
     <!-- Introduction subtitle for the Home gesture tutorial. [CHAR LIMIT=100] -->
     <string name="home_gesture_intro_subtitle">Swipe up from the bottom of your screen. This gesture always takes you to the Home screen.</string>
-    <!-- Introduction subtitle for the Home gesture tutorial that will be spoken by screen readers. [CHAR LIMIT=100] -->
-    <string name="home_gesture_spoken_intro_subtitle">Swipe up with 2 fingers from the bottom of the screen. This gesture always takes you to the Home screen.</string>
     <!-- Title of the gesture tutorial section educating users on how to go to the home screen. [CHAR LIMIT=100] -->
     <string name="home_gesture_tutorial_title">Go home</string>
     <!-- Subtitle of the gesture tutorial section educating users on how to go to the home screen [CHAR LIMIT=100] -->
@@ -168,8 +164,6 @@
     <string name="overview_gesture_intro_title">Swipe to switch apps</string>
     <!-- Introduction subtitle for the Overview gesture tutorial. [CHAR LIMIT=100] -->
     <string name="overview_gesture_intro_subtitle">To switch between apps, swipe up from the bottom of your screen, hold, then release.</string>
-    <!-- Introduction subtitle for the Overview gesture tutorial that will be spoken by screen readers. [CHAR LIMIT=100] -->
-    <string name="overview_gesture_spoken_intro_subtitle">To switch between apps, swipe up with 2 fingers from the bottom of your screen, hold, then release.</string>
     <!-- Title of the gesture tutorial section educating users on how to switch between apps. [CHAR LIMIT=100] -->
     <string name="overview_gesture_tutorial_title">Switch apps</string>
     <!-- Subtitle of the gesture tutorial section educating users on how to switch between apps [CHAR LIMIT=100] -->
diff --git a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
index 8e80aa5..22e491f 100644
--- a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
+++ b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
@@ -16,12 +16,16 @@
 
 package com.android.launcher3.appprediction;
 
+import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
+
 import android.content.Context;
 import android.graphics.Canvas;
+import android.os.Build;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.LinearLayout;
 
 import androidx.annotation.NonNull;
@@ -91,6 +95,14 @@
     }
 
     @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(info);
+        if (Build.VERSION.SDK_INT >= UPSIDE_DOWN_CAKE) {
+            info.setContainerTitle(mActivityContext.getString(R.string.title_app_suggestions));
+        }
+    }
+
+    @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         mActivityContext.addOnDeviceProfileChangeListener(this);
diff --git a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
index 6a908ca..d6327bc 100644
--- a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
@@ -28,7 +28,6 @@
 import com.android.launcher3.statemanager.StatefulContainer;
 import com.android.quickstep.TopTaskTracker;
 import com.android.quickstep.fallback.RecentsState;
-import com.android.quickstep.util.TISBindHelper;
 import com.android.quickstep.views.RecentsView;
 import com.android.quickstep.views.RecentsViewContainer;
 
@@ -139,12 +138,6 @@
         return topTask.isHomeTask() || topTask.isRecentsTask();
     }
 
-    @Nullable
-    @Override
-    protected TISBindHelper getTISBindHelper() {
-        return mRecentsContainer.getTISBindHelper();
-    }
-
     @Override
     protected String getTaskbarUIControllerName() {
         return "FallbackTaskbarUIController<" + mRecentsContainer.getClass().getSimpleName() + ">";
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 371a0e8..80da467 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -49,7 +49,6 @@
 import com.android.quickstep.RecentsAnimationCallbacks;
 import com.android.quickstep.SystemUiProxy;
 import com.android.quickstep.util.GroupTask;
-import com.android.quickstep.util.TISBindHelper;
 import com.android.quickstep.views.RecentsView;
 import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
 import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
@@ -486,12 +485,6 @@
         mTaskbarLauncherStateController.resetIconAlignment();
     }
 
-    @Nullable
-    @Override
-    protected TISBindHelper getTISBindHelper() {
-        return mLauncher.getTISBindHelper();
-    }
-
     @Override
     public void dumpLogs(String prefix, PrintWriter pw) {
         super.dumpLogs(prefix, pw);
diff --git a/quickstep/src/com/android/launcher3/taskbar/ManageWindowsTaskbarShortcut.kt b/quickstep/src/com/android/launcher3/taskbar/ManageWindowsTaskbarShortcut.kt
index 032eb51..75ce7c3 100644
--- a/quickstep/src/com/android/launcher3/taskbar/ManageWindowsTaskbarShortcut.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/ManageWindowsTaskbarShortcut.kt
@@ -148,11 +148,19 @@
                         FLAG_AUTOHIDE_SUSPEND_MULTI_INSTANCE_MENU_OPEN,
                         false,
                     )
+                    controllers.taskbarPopupController.cleanUpMultiInstanceMenuReference()
                 }
             }
         )
     }
 
+    /** Closes the multi-instance menu if it has been initialized. */
+    fun closeMultiInstanceMenu() {
+        if (::taskbarShortcutAllWindowsView.isInitialized) {
+            taskbarShortcutAllWindowsView.animateClose()
+        }
+    }
+
     /**
      * A view container for displaying the window of open instances of an app
      *
@@ -238,6 +246,7 @@
             )
             taskbarOverlayContext.dragLayer?.removeView(menuView.rootView)
             taskbarOverlayContext.dragLayer.removeTouchController(this)
+            controllers.taskbarPopupController.cleanUpMultiInstanceMenuReference()
         }
 
         /** TouchController implementations for closing the carousel when touched outside */
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 633806d..c769e04 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -1432,6 +1432,7 @@
             Log.e(TAG, "Unknown type clicked: " + tag);
         }
 
+        mControllers.taskbarPopupController.maybeCloseMultiInstanceMenu();
         if (shouldCloseAllOpenViews) {
             AbstractFloatingView.closeAllOpenViews(this);
         }
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index 9407e73..3e9a073 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -47,6 +47,7 @@
 import android.provider.Settings;
 import android.util.Log;
 import android.util.SparseArray;
+import android.util.SparseBooleanArray;
 import android.view.Display;
 import android.view.MotionEvent;
 import android.view.WindowManager;
@@ -116,7 +117,6 @@
     private final Context mWindowContext;
     private final @Nullable Context mNavigationBarPanelContext;
     private WindowManager mWindowManager;
-    private boolean mAddedWindow;
     private final TaskbarNavButtonController mDefaultNavButtonController;
     private final ComponentCallbacks mDefaultComponentCallbacks;
 
@@ -133,6 +133,8 @@
     private final SparseArray<TaskbarActivityContext> mTaskbars = new SparseArray<>();
     /** DisplayId - {@link FrameLayout} map for Connected Display. */
     private final SparseArray<FrameLayout> mRootLayouts = new SparseArray<>();
+    /** DisplayId - {@link Boolean} map indicating if RootLayout was added to window. */
+    private final SparseBooleanArray mAddedRootLayouts = new SparseBooleanArray();
     private StatefulActivity mActivity;
     private RecentsViewContainer mRecentsViewContainer;
 
@@ -742,23 +744,42 @@
 
     private void addTaskbarRootViewToWindow(int displayId) {
         TaskbarActivityContext taskbar = getTaskbarForDisplay(displayId);
-        if (enableTaskbarNoRecreate() && !mAddedWindow && taskbar != null) {
+        if (!enableTaskbarNoRecreate() || taskbar == null) {
+            return;
+        }
+
+        if (!isTaskbarRootLayoutAddedForDisplay(displayId)) {
             mWindowManager.addView(getTaskbarRootLayoutForDisplay(displayId),
                     taskbar.getWindowLayoutParams());
-            mAddedWindow = true;
+            mAddedRootLayouts.put(displayId, true);
         }
     }
 
     private void removeTaskbarRootViewFromWindow(int displayId) {
         FrameLayout rootLayout = getTaskbarRootLayoutForDisplay(displayId);
-        if (enableTaskbarNoRecreate() && mAddedWindow && rootLayout != null) {
+        if (!enableTaskbarNoRecreate() || rootLayout == null) {
+            return;
+        }
+
+        if (isTaskbarRootLayoutAddedForDisplay(displayId)) {
             mWindowManager.removeViewImmediate(rootLayout);
-            mAddedWindow = false;
+            mAddedRootLayouts.put(displayId, false);
             removeTaskbarRootLayoutFromMap(displayId);
         }
     }
 
     /**
+     * Retrieves whether RootLayout was added to window for specific display, or false if no
+     * such mapping has been made.
+     *
+     * @param displayId The ID of the display for which to retrieve the taskbar root layout.
+     * @return if RootLayout was added to window {@link Boolean} for a display or {@code false}.
+     */
+    private boolean isTaskbarRootLayoutAddedForDisplay(int displayId) {
+        return mAddedRootLayouts.get(displayId);
+    }
+
+    /**
      * Returns the {@link TaskbarActivityContext} associated with the given display ID.
      *
      * @param displayId The ID of the display to retrieve the taskbar for.
@@ -853,6 +874,7 @@
      */
     private void removeTaskbarRootLayoutFromMap(int displayId) {
         if (mRootLayouts.contains(displayId)) {
+            mAddedRootLayouts.delete(displayId);
             mRootLayouts.delete(displayId);
         }
     }
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
index 4881836..d1f9be0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
@@ -344,6 +344,10 @@
         mCallbacks.onToggleOverview();
     }
 
+    public void hideOverview() {
+        mCallbacks.onHideOverview();
+    }
+
     void sendBackKeyEvent(int action, boolean cancelled) {
         if (action == mLastSentBackAction) {
             // There must always be an alternating sequence of ACTION_DOWN and ACTION_UP events
@@ -411,5 +415,8 @@
 
         /** Callback invoked when the overview button is pressed. */
         default void onToggleOverview() {}
+
+        /** Callback invoken when a visible overview needs to be hidden. */
+        default void onHideOverview() { }
     }
 }
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
index b3698ad..e704691 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
@@ -87,6 +87,8 @@
     private TaskbarControllers mControllers;
     private boolean mAllowInitialSplitSelection;
     private AppInfo[] mAppInfosList;
+    private ManageWindowsTaskbarShortcut<BaseTaskbarContext> mManageWindowsTaskbarShortcut;
+
 
     public TaskbarPopupController(TaskbarActivityContext context) {
         mContext = context;
@@ -112,6 +114,19 @@
         mPopupDataProvider.setDeepShortcutMap(deepShortcutMapCopy);
     }
 
+    /** Closes the multi-instance menu if it is enabled and currently open. */
+    public void maybeCloseMultiInstanceMenu() {
+        if (Flags.enableMultiInstanceMenuTaskbar() && mManageWindowsTaskbarShortcut != null) {
+            mManageWindowsTaskbarShortcut.closeMultiInstanceMenu();
+            cleanUpMultiInstanceMenuReference();
+        }
+    }
+
+    /** Releases the reference to the Taskbar multi-instance menu */
+    public void cleanUpMultiInstanceMenuReference() {
+        mManageWindowsTaskbarShortcut = null;
+    }
+
     public void setAllowInitialSplitSelection(boolean allowInitialSplitSelection) {
         mAllowInitialSplitSelection = allowInitialSplitSelection;
     }
@@ -211,6 +226,7 @@
         if (Flags.enableMultiInstanceMenuTaskbar()
                 && DesktopModeStatus.canEnterDesktopMode(mContext)
                 && !mControllers.taskbarStashController.isInOverview()) {
+            maybeCloseMultiInstanceMenu();
             shortcuts.addAll(getMultiInstanceMenuOptions().toList());
         }
         return shortcuts.stream();
@@ -330,8 +346,9 @@
     public SystemShortcut.Factory<BaseTaskbarContext> createManageWindowsShortcutFactory() {
         return (context, itemInfo, originalView) -> {
             if (shouldShowMultiInstanceOptions(itemInfo)) {
-                return new ManageWindowsTaskbarShortcut<>(context, itemInfo, originalView,
-                        mControllers);
+                mManageWindowsTaskbarShortcut = new ManageWindowsTaskbarShortcut<>(
+                        context, itemInfo, originalView, mControllers);
+                return mManageWindowsTaskbarShortcut;
             }
             return null;
         };
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index 8b636dd..f29f95d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -39,10 +39,7 @@
 import com.android.launcher3.taskbar.bubbles.BubbleBarController;
 import com.android.launcher3.util.DisplayController;
 import com.android.launcher3.util.SplitConfigurationOptions;
-import com.android.quickstep.OverviewCommandHelper;
-import com.android.quickstep.OverviewCommandHelper.CommandType;
 import com.android.quickstep.util.GroupTask;
-import com.android.quickstep.util.TISBindHelper;
 import com.android.quickstep.views.RecentsView;
 import com.android.quickstep.views.TaskContainer;
 import com.android.quickstep.views.TaskView;
@@ -389,26 +386,13 @@
     /** Adjusts the hotseat for the bubble bar. */
     public void adjustHotseatForBubbleBar(boolean isBubbleBarVisible) {}
 
-    @Nullable
-    protected TISBindHelper getTISBindHelper() {
-        return null;
-    }
-
     /**
      * Launches the focused task in the Keyboard Quick Switch view through the OverviewCommandHelper
      * <p>
      * Use this helper method when the focused task may be the overview task.
      */
     public void launchKeyboardFocusedTask() {
-        TISBindHelper tisBindHelper = getTISBindHelper();
-        if (tisBindHelper == null) {
-            return;
-        }
-        OverviewCommandHelper overviewCommandHelper = tisBindHelper.getOverviewCommandHelper();
-        if (overviewCommandHelper == null) {
-            return;
-        }
-        overviewCommandHelper.addCommand(CommandType.HIDE);
+        mControllers.navButtonController.hideOverview();
     }
 
     /**
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
index 07d86e4..ddbf3b7 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
@@ -141,6 +141,7 @@
         if (isOpen()) {
             mSlideInView.close(true);
         } else {
+            mControllers.taskbarPopupController.maybeCloseMultiInstanceMenu();
             show(true, showKeyboard);
         }
     }
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
index 3bff58b..745c689 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
@@ -531,7 +531,7 @@
         bubbleStashController.getStashedHandlePhysicsAnimator().cancelIfRunning()
         resetBubbleBarPropertiesOnInterrupt()
         bubbleStashController.onNewBubbleAnimationInterrupted(
-            /* isStashed= */ bubbleBarView.alpha == 0f,
+            /* isStashed= */ bubbleStashController.isStashed,
             bubbleBarView.translationY,
         )
     }
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index dfbb4d7..cecd2a9 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -1434,12 +1434,6 @@
         return (mTaskbarUIController != null && mTaskbarUIController.hasBubbles());
     }
 
-    @NonNull
-    @Override
-    public TISBindHelper getTISBindHelper() {
-        return mTISBindHelper;
-    }
-
     @Override
     public boolean handleIncorrectSplitTargetSelection() {
         if (!enableSplitContextually() || !mSplitSelectStateController.isSplitSelectActive()) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
index d387794..dae63af 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -102,7 +102,7 @@
 
     @Override
     public int getTitle() {
-        return R.string.all_apps_label;
+        return R.string.all_apps_list_label;
     }
 
     @Override
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 3740a68..03394ef 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -131,7 +131,6 @@
 import com.android.launcher3.util.WindowBounds;
 import com.android.quickstep.GestureState.GestureEndTarget;
 import com.android.quickstep.RemoteTargetGluer.RemoteTargetHandle;
-import com.android.quickstep.fallback.window.RecentsWindowFactory;
 import com.android.quickstep.util.ActiveGestureErrorDetector;
 import com.android.quickstep.util.ActiveGestureLog;
 import com.android.quickstep.util.ActiveGestureProtoLogProxy;
@@ -310,7 +309,6 @@
     private static final int LOG_NO_OP_PAGE_INDEX = -1;
 
     protected final TaskAnimationManager mTaskAnimationManager;
-    protected final RecentsWindowFactory mRecentsWindowFactory;
     // Either RectFSpringAnim (if animating home) or ObjectAnimator (from mCurrentShift) otherwise
     private RunningWindowAnim[] mRunningWindowAnim;
     // Possible second animation running at the same time as mRunningWindowAnim
@@ -376,7 +374,7 @@
     public AbsSwipeUpHandler(Context context, RecentsAnimationDeviceState deviceState,
             TaskAnimationManager taskAnimationManager, GestureState gestureState,
             long touchTimeMs, boolean continuingLastGesture,
-            InputConsumerController inputConsumer, RecentsWindowFactory recentsWindowFactory,
+            InputConsumerController inputConsumer,
             MSDLPlayerWrapper msdlPlayerWrapper) {
         super(context, deviceState, gestureState);
         mContainerInterface = gestureState.getContainerInterface();
@@ -393,7 +391,6 @@
                     endLauncherTransitionController();
                 }, new InputProxyHandlerFactory(mContainerInterface, mGestureState));
         mTaskAnimationManager = taskAnimationManager;
-        mRecentsWindowFactory = recentsWindowFactory;
         mTouchTimeMs = touchTimeMs;
         mContinuingLastGesture = continuingLastGesture;
 
diff --git a/quickstep/src/com/android/quickstep/DisplayModel.kt b/quickstep/src/com/android/quickstep/DisplayModel.kt
new file mode 100644
index 0000000..cbc2f7d
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/DisplayModel.kt
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2024 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
+
+import android.content.Context
+import android.hardware.display.DisplayManager
+import android.util.Log
+import android.util.SparseArray
+import androidx.core.util.valueIterator
+import com.android.quickstep.DisplayModel.DisplayResource
+
+/** data model for managing resources with lifecycles that match that of the connected display */
+abstract class DisplayModel<RESOURCE_TYPE : DisplayResource>(val context: Context) {
+
+    companion object {
+        private const val TAG = "DisplayViewModel"
+        private const val DEBUG = false
+    }
+
+    protected val displayManager =
+        context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
+    protected val displayResourceArray = SparseArray<RESOURCE_TYPE>()
+
+    abstract fun createDisplayResource(displayId: Int)
+
+    protected val displayListener: DisplayManager.DisplayListener =
+        (object : DisplayManager.DisplayListener {
+            override fun onDisplayAdded(displayId: Int) {
+                if (DEBUG) Log.d(TAG, "onDisplayAdded: displayId=$displayId")
+                createDisplayResource(displayId)
+            }
+
+            override fun onDisplayRemoved(displayId: Int) {
+                if (DEBUG) Log.d(TAG, "onDisplayRemoved: displayId=$displayId")
+                deleteDisplayResource(displayId)
+            }
+
+            override fun onDisplayChanged(displayId: Int) {
+                if (DEBUG) Log.d(TAG, "onDisplayChanged: displayId=$displayId")
+            }
+        })
+
+    fun destroy() {
+        displayResourceArray.valueIterator().forEach { displayResource ->
+            displayResource.cleanup()
+        }
+        displayResourceArray.clear()
+        displayManager.unregisterDisplayListener(displayListener)
+    }
+
+    fun getDisplayResource(displayId: Int): RESOURCE_TYPE? {
+        if (DEBUG) Log.d(TAG, "get: displayId=$displayId")
+        return displayResourceArray[displayId]
+    }
+
+    fun deleteDisplayResource(displayId: Int) {
+        if (DEBUG) Log.d(TAG, "delete: displayId=$displayId")
+        getDisplayResource(displayId)?.cleanup()
+        displayResourceArray.remove(displayId)
+    }
+
+    abstract class DisplayResource() {
+        abstract fun cleanup()
+    }
+}
diff --git a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
index b0c69cf..1e857ca 100644
--- a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
@@ -106,7 +106,7 @@
             boolean continuingLastGesture, InputConsumerController inputConsumer,
             MSDLPlayerWrapper msdlPlayerWrapper) {
         super(context, deviceState, taskAnimationManager, gestureState, touchTimeMs,
-                continuingLastGesture, inputConsumer, null, msdlPlayerWrapper);
+                continuingLastGesture, inputConsumer, msdlPlayerWrapper);
 
         mRunningOverHome = mGestureState.getRunningTask() != null
                 && mGestureState.getRunningTask().isHomeTask();
diff --git a/quickstep/src/com/android/quickstep/FallbackWindowInterface.java b/quickstep/src/com/android/quickstep/FallbackWindowInterface.java
index a202ebd..f7836b0 100644
--- a/quickstep/src/com/android/quickstep/FallbackWindowInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackWindowInterface.java
@@ -41,8 +41,6 @@
 import com.android.quickstep.util.ContextInitListener;
 import com.android.quickstep.views.RecentsView;
 
-import java.util.HashMap;
-import java.util.Map;
 import java.util.function.Consumer;
 import java.util.function.Predicate;
 
@@ -53,35 +51,13 @@
  */
 public final class FallbackWindowInterface extends BaseWindowInterface{
 
-    static Map<Integer, FallbackWindowInterface> sWindowInterfaceMap = new HashMap<>();
-
     private final RecentsWindowManager mRecentsWindowManager;
-    /**
-     * This is only null before init() or after destroy()
-     */
-    @Nullable
-    public static FallbackWindowInterface getInstance(int displayId) {
-        return sWindowInterfaceMap.get(displayId);
-    }
 
-    /**
-     * initializing instance and mapping it to display id
-     */
-    public static void init(int displayId, RecentsWindowManager recentsWindowManager) {
-        if (!sWindowInterfaceMap.containsKey(displayId)) {
-            sWindowInterfaceMap.put(displayId, new FallbackWindowInterface(recentsWindowManager));
-        }
-    }
-
-    private FallbackWindowInterface(RecentsWindowManager recentsWindowManager) {
+    public FallbackWindowInterface(RecentsWindowManager recentsWindowManager) {
         super(DEFAULT, BACKGROUND_APP);
         mRecentsWindowManager = recentsWindowManager;
     }
 
-    public void destroy() {
-        sWindowInterfaceMap.clear();
-    }
-
     /** 2 */
     @Override
     public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect,
diff --git a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
index 76c14c0..243a577 100644
--- a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
+++ b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
@@ -71,7 +71,7 @@
             boolean continuingLastGesture, InputConsumerController inputConsumer,
             MSDLPlayerWrapper msdlPlayerWrapper) {
         super(context, deviceState, taskAnimationManager, gestureState, touchTimeMs,
-                continuingLastGesture, inputConsumer, null, msdlPlayerWrapper);
+                continuingLastGesture, inputConsumer, msdlPlayerWrapper);
     }
 
 
diff --git a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
index bac5e64..1fc0401 100644
--- a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
+++ b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
@@ -42,6 +42,7 @@
 import com.android.launcher3.Flags;
 import com.android.launcher3.R;
 import com.android.launcher3.util.SimpleBroadcastReceiver;
+import com.android.quickstep.fallback.window.RecentsDisplayModel;
 import com.android.quickstep.util.ActiveGestureProtoLogProxy;
 import com.android.systemui.shared.system.PackageManagerWrapper;
 
@@ -181,7 +182,8 @@
 
             if (Flags.enableLauncherOverviewInWindow() || Flags.enableFallbackOverviewInWindow()) {
                 mContainerInterface =
-                        FallbackWindowInterface.getInstance(mDeviceState.getDisplayId());
+                        RecentsDisplayModel.getINSTANCE().get(mContext)
+                                .getFallbackWindowInterface(mDeviceState.getDisplayId());
             } else {
                 mContainerInterface = FallbackActivityInterface.INSTANCE;
             }
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index 61a150b..17c17cc 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -554,12 +554,6 @@
         return overviewCommandHelper == null || overviewCommandHelper.canStartHomeSafely();
     }
 
-    @NonNull
-    @Override
-    public TISBindHelper getTISBindHelper() {
-        return mTISBindHelper;
-    }
-
     @Override
     public boolean isRecentsViewVisible() {
         return getStateManager().getState().isRecentsViewVisible();
diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
index 2fcfa36..e0d4ddd 100644
--- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java
+++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
@@ -47,7 +47,7 @@
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.taskbar.TaskbarUIController;
 import com.android.launcher3.util.DisplayController;
-import com.android.quickstep.fallback.window.RecentsWindowFactory;
+import com.android.quickstep.fallback.window.RecentsDisplayModel;
 import com.android.quickstep.fallback.window.RecentsWindowManager;
 import com.android.quickstep.util.ActiveGestureProtoLogProxy;
 import com.android.quickstep.util.SystemUiFlagUtils;
@@ -66,7 +66,6 @@
             SystemProperties.getBoolean("persist.wm.debug.shell_transit_rotate", false);
 
     private final Context mCtx;
-    private RecentsWindowFactory mRecentsWindowFactory;
     private RecentsAnimationController mController;
     private RecentsAnimationCallbacks mCallbacks;
     private RecentsAnimationTargets mTargets;
@@ -103,11 +102,9 @@
         }
     };
 
-    TaskAnimationManager(Context ctx, RecentsWindowFactory recentsWindowFactory,
-            RecentsAnimationDeviceState deviceState) {
+    TaskAnimationManager(Context ctx, RecentsAnimationDeviceState deviceState) {
         mCtx = ctx;
         mDeviceState = deviceState;
-        mRecentsWindowFactory = recentsWindowFactory;
     }
     SystemUiProxy getSystemUiProxy() {
         return SystemUiProxy.INSTANCE.get(mCtx);
@@ -303,7 +300,8 @@
                         || Flags.enableLauncherOverviewInWindow())) {
             mRecentsAnimationStartPending = getSystemUiProxy().startRecentsActivity(intent, options,
                     mCallbacks, gestureState.useSyntheticRecentsTransition());
-            mRecentsWindowFactory.create(mDeviceState.getDisplayId())
+            RecentsDisplayModel.getINSTANCE().get(mCtx)
+                    .getRecentsWindowManager(mDeviceState.getDisplayId())
                     .startRecentsWindow(mCallbacks);
         } else {
             options.setPendingIntentBackgroundActivityStartMode(
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 4ddbcdb..9de96c7 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -90,7 +90,6 @@
 import com.android.launcher3.util.ScreenOnTracker;
 import com.android.launcher3.util.TraceHelper;
 import com.android.quickstep.OverviewCommandHelper.CommandType;
-import com.android.quickstep.fallback.window.RecentsWindowFactory;
 import com.android.quickstep.fallback.window.RecentsWindowSwipeHandler;
 import com.android.quickstep.inputconsumers.BubbleBarInputConsumer;
 import com.android.quickstep.inputconsumers.OneHandedModeInputConsumer;
@@ -613,6 +612,11 @@
         public void onToggleOverview() {
             mOverviewCommandHelper.addCommand(CommandType.TOGGLE);
         }
+
+        @Override
+        public void onHideOverview() {
+            mOverviewCommandHelper.addCommand(CommandType.HIDE);
+        }
     };
 
     private ActivityManagerWrapper mAM;
@@ -632,7 +636,6 @@
     private InputEventReceiver mInputEventReceiver;
 
     private TaskbarManager mTaskbarManager;
-    private RecentsWindowFactory mRecentsWindowFactory;
     private Function<GestureState, AnimatedFloat> mSwipeUpProxyProvider = i -> null;
     private AllAppsActionManager mAllAppsActionManager;
     private InputManager mInputManager;
@@ -669,9 +672,6 @@
         mDesktopAppLaunchTransitionManager =
                 new DesktopAppLaunchTransitionManager(this, SystemUiProxy.INSTANCE.get(this));
         mDesktopAppLaunchTransitionManager.registerTransitions();
-        if (Flags.enableLauncherOverviewInWindow() || Flags.enableFallbackOverviewInWindow()) {
-            mRecentsWindowFactory = new RecentsWindowFactory(this);
-        }
         mInputConsumer = InputConsumerController.getRecentsAnimationInputConsumer();
 
         // Call runOnUserUnlocked() before any other callbacks to ensure everything is initialized.
@@ -723,7 +723,7 @@
     public void onUserUnlocked() {
         Log.d(TAG, "onUserUnlocked: userId=" + getUserId()
                 + " instance=" + System.identityHashCode(this));
-        mTaskAnimationManager = new TaskAnimationManager(this, mRecentsWindowFactory, mDeviceState);
+        mTaskAnimationManager = new TaskAnimationManager(this, mDeviceState);
         mOverviewComponentObserver = new OverviewComponentObserver(this, mDeviceState);
         mOverviewCommandHelper = new OverviewCommandHelper(this,
                 mOverviewComponentObserver, mTaskAnimationManager);
@@ -830,10 +830,6 @@
         mTrackpadsConnected.clear();
 
         mTaskbarManager.destroy();
-
-        if (mRecentsWindowFactory != null) {
-            mRecentsWindowFactory.destroy();
-        }
         if (mDesktopAppLaunchTransitionManager != null) {
             mDesktopAppLaunchTransitionManager.unregisterTransitions();
         }
@@ -1289,6 +1285,6 @@
             GestureState gestureState, long touchTimeMs) {
         return new RecentsWindowSwipeHandler(this, mDeviceState, mTaskAnimationManager,
                 gestureState, touchTimeMs, mTaskAnimationManager.isRecentsAnimationRunning(),
-                mInputConsumer, mRecentsWindowFactory, MSDLPlayerWrapper.INSTANCE.get(this));
+                mInputConsumer, MSDLPlayerWrapper.INSTANCE.get(this));
     }
 }
diff --git a/quickstep/src/com/android/quickstep/dagger/QuickstepBaseAppComponent.java b/quickstep/src/com/android/quickstep/dagger/QuickstepBaseAppComponent.java
index b2670e8..4255372 100644
--- a/quickstep/src/com/android/quickstep/dagger/QuickstepBaseAppComponent.java
+++ b/quickstep/src/com/android/quickstep/dagger/QuickstepBaseAppComponent.java
@@ -20,6 +20,7 @@
 import com.android.launcher3.dagger.LauncherBaseAppComponent;
 import com.android.launcher3.model.WellbeingModel;
 import com.android.quickstep.SystemUiProxy;
+import com.android.quickstep.fallback.window.RecentsDisplayModel;
 import com.android.quickstep.util.AsyncClockEventDelegate;
 
 /**
@@ -37,4 +38,6 @@
     AsyncClockEventDelegate getAsyncClockEventDelegate();
 
     SystemUiProxy getSystemUiProxy();
+
+    RecentsDisplayModel getRecentsDisplayModel();
 }
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index 980dee4..9625d29 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -43,9 +43,9 @@
 import com.android.launcher3.util.SplitConfigurationOptions.SplitSelectSource;
 import com.android.quickstep.BaseContainerInterface;
 import com.android.quickstep.FallbackActivityInterface;
-import com.android.quickstep.FallbackWindowInterface;
 import com.android.quickstep.GestureState;
 import com.android.quickstep.RotationTouchHelper;
+import com.android.quickstep.fallback.window.RecentsDisplayModel;
 import com.android.quickstep.util.GroupTask;
 import com.android.quickstep.util.SplitSelectStateController;
 import com.android.quickstep.util.TaskViewSimulator;
@@ -80,8 +80,8 @@
     @Override
     public BaseContainerInterface<RecentsState, ?> getContainerInterface(int displayId) {
         return (Flags.enableFallbackOverviewInWindow() || Flags.enableLauncherOverviewInWindow())
-                ? FallbackWindowInterface.getInstance(displayId)
-                : FallbackActivityInterface.INSTANCE;
+                ? RecentsDisplayModel.getINSTANCE().get(mContext)
+                .getFallbackWindowInterface(displayId) : FallbackActivityInterface.INSTANCE;
     }
 
     @Override
@@ -264,13 +264,13 @@
         }
 
         setFreezeViewVisibility(true);
-        if (mContainer.getDesktopVisibilityController() != null) {
-            mContainer.getDesktopVisibilityController().onLauncherStateChanged(toState);
-        }
     }
 
     @Override
     public void onStateTransitionComplete(RecentsState finalState) {
+        if (mContainer.getDesktopVisibilityController() != null) {
+            mContainer.getDesktopVisibilityController().onLauncherStateChanged(finalState);
+        }
         if (!finalState.isRecentsViewVisible()) {
             // Clean-up logic that occurs when recents is no longer in use/visible.
             reset();
diff --git a/quickstep/src/com/android/quickstep/fallback/window/RecentsDisplayModel.kt b/quickstep/src/com/android/quickstep/fallback/window/RecentsDisplayModel.kt
new file mode 100644
index 0000000..a9259d9
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/fallback/window/RecentsDisplayModel.kt
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2024 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.fallback.window
+
+import android.content.Context
+import android.os.Handler
+import android.util.Log
+import android.view.Display
+import com.android.launcher3.Flags
+import com.android.launcher3.dagger.ApplicationContext
+import com.android.launcher3.dagger.LauncherAppSingleton
+import com.android.launcher3.util.DaggerSingletonObject
+import com.android.quickstep.DisplayModel
+import com.android.quickstep.FallbackWindowInterface
+import com.android.quickstep.dagger.QuickstepBaseAppComponent
+import com.android.quickstep.fallback.window.RecentsDisplayModel.RecentsDisplayResource
+import javax.inject.Inject
+
+@LauncherAppSingleton
+class RecentsDisplayModel @Inject constructor(@ApplicationContext context: Context) :
+    DisplayModel<RecentsDisplayResource>(context) {
+
+    companion object {
+        private const val TAG = "RecentsDisplayModel"
+        private const val DEBUG = false
+
+        @JvmStatic
+        val INSTANCE: DaggerSingletonObject<RecentsDisplayModel> =
+            DaggerSingletonObject<RecentsDisplayModel>(
+                QuickstepBaseAppComponent::getRecentsDisplayModel
+            )
+    }
+
+    init {
+        if (Flags.enableFallbackOverviewInWindow() || Flags.enableLauncherOverviewInWindow()) {
+            displayManager.registerDisplayListener(displayListener, Handler.getMain())
+            createDisplayResource(Display.DEFAULT_DISPLAY)
+        }
+    }
+
+    override fun createDisplayResource(displayId: Int) {
+        if (DEBUG) Log.d(TAG, "create: displayId=$displayId")
+        getDisplayResource(displayId)?.let {
+            return
+        }
+        val display = displayManager.getDisplay(displayId)
+        displayResourceArray[displayId] =
+            RecentsDisplayResource(displayId, context.createDisplayContext(display))
+    }
+
+    fun getRecentsWindowManager(displayId: Int): RecentsWindowManager? {
+        return getDisplayResource(displayId)?.recentsWindowManager
+    }
+
+    fun getFallbackWindowInterface(displayId: Int): FallbackWindowInterface? {
+        return getDisplayResource(displayId)?.fallbackWindowInterface
+    }
+
+    data class RecentsDisplayResource(var displayId: Int, var displayContext: Context) :
+        DisplayResource() {
+        val recentsWindowManager = RecentsWindowManager(displayContext)
+        val fallbackWindowInterface: FallbackWindowInterface =
+            FallbackWindowInterface(recentsWindowManager)
+
+        override fun cleanup() {
+            recentsWindowManager.destroy()
+        }
+    }
+}
diff --git a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowFactory.kt b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowFactory.kt
deleted file mode 100644
index ac0593e..0000000
--- a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowFactory.kt
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2024 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.fallback.window
-
-import android.content.Context
-import android.hardware.display.DisplayManager
-import android.os.Handler
-import android.util.Log
-import android.util.SparseArray
-import android.view.Display
-import androidx.core.util.valueIterator
-
-
-/**
- * Factory for creating [RecentsWindowManager] instances based on context per display.
- */
-class RecentsWindowFactory(private val context: Context) {
-
-    companion object {
-        private const val TAG = "RecentsWindowFactory"
-        private const val DEBUG = false
-    }
-
-    private val displayManager = context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
-    private val managerArray = SparseArray<RecentsWindowManager>()
-
-    private val displayListener: DisplayManager.DisplayListener =
-        (object : DisplayManager.DisplayListener {
-            override fun onDisplayAdded(displayId: Int) {
-                if (DEBUG) Log.d(TAG, "onDisplayAdded: displayId=$displayId")
-                create(displayId)
-            }
-
-            override fun onDisplayRemoved(displayId: Int) {
-                if (DEBUG) Log.d(TAG, "onDisplayRemoved: displayId=$displayId")
-                delete(displayId)
-            }
-
-            override fun onDisplayChanged(displayId: Int) {
-                if (DEBUG) Log.d(TAG, "onDisplayChanged: displayId=$displayId")
-            }
-        })
-
-    init {
-        create(Display.DEFAULT_DISPLAY) // create manager for first display early.
-        displayManager.registerDisplayListener(displayListener, Handler.getMain())
-    }
-
-    fun destroy() {
-        managerArray.valueIterator().forEach { manager ->
-            manager.destroy()
-        }
-        managerArray.clear()
-        displayManager.unregisterDisplayListener(displayListener)
-    }
-
-    fun get(displayId: Int): RecentsWindowManager? {
-        if (DEBUG) Log.d(TAG, "get: displayId=$displayId")
-        return managerArray[displayId]
-    }
-
-    fun delete(displayId: Int) {
-        if (DEBUG) Log.d(TAG, "delete: displayId=$displayId")
-        get(displayId)?.destroy()
-        managerArray.remove(displayId)
-    }
-
-    fun create(displayId: Int): RecentsWindowManager {
-        if (DEBUG) Log.d(TAG, "create: displayId=$displayId")
-        get(displayId)?.let {
-            return it
-        }
-        val display = displayManager.getDisplay(displayId)
-        val displayContext = context.createDisplayContext(display)
-        val recentsWindowManager = RecentsWindowManager(displayId, displayContext)
-        managerArray[displayId] = recentsWindowManager
-        return recentsWindowManager
-    }
-}
diff --git a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt
index b3cc3e9..9bd7a19 100644
--- a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt
+++ b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt
@@ -50,7 +50,6 @@
 import com.android.launcher3.util.SystemUiController
 import com.android.launcher3.views.BaseDragLayer
 import com.android.launcher3.views.ScrimView
-import com.android.quickstep.FallbackWindowInterface
 import com.android.quickstep.OverviewComponentObserver
 import com.android.quickstep.RecentsAnimationCallbacks
 import com.android.quickstep.RecentsAnimationCallbacks.RecentsAnimationListener
@@ -89,7 +88,7 @@
  * To add new protologs, see [RecentsWindowProtoLogProxy]. To enable logging to logcat, see
  * [QuickstepProtoLogGroup.Constants.DEBUG_RECENTS_WINDOW]
  */
-class RecentsWindowManager(private val displayId: Int, context: Context) :
+class RecentsWindowManager(context: Context) :
     RecentsWindowContext(context), RecentsViewContainer, StatefulContainer<RecentsState> {
 
     companion object {
@@ -98,6 +97,9 @@
 
         class RecentsWindowTracker : ContextTracker<RecentsWindowManager?>() {
             override fun isHomeStarted(context: RecentsWindowManager?): Boolean {
+                // if we need to change this block to use context in some way, we will need to
+                // refactor RecentsWindowTracker to be an instance (instead of a singleton) managed
+                // by RecentsDisplayModel. Otherwise bad things will occur.
                 return true
             }
         }
@@ -152,14 +154,12 @@
         }
 
     init {
-        FallbackWindowInterface.init(displayId, this)
         TaskStackChangeListeners.getInstance().registerTaskStackListener(taskStackChangeListener)
     }
 
     override fun destroy() {
         super.destroy()
         cleanupRecentsWindow()
-        FallbackWindowInterface.getInstance(displayId)?.destroy()
         TaskStackChangeListeners.getInstance().unregisterTaskStackListener(taskStackChangeListener)
         callbacks?.removeListener(recentsAnimationListener)
         recentsWindowTracker.onContextDestroyed(this)
@@ -322,10 +322,6 @@
         return taskbarUIController
     }
 
-    override fun getTISBindHelper(): TISBindHelper {
-        return tisBindHelper
-    }
-
     fun registerInitListener(onInitListener: Predicate<Boolean>) {
         this.onInitListener = onInitListener
     }
diff --git a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowSwipeHandler.java b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowSwipeHandler.java
index 4a08d12..afc8879 100644
--- a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowSwipeHandler.java
@@ -101,6 +101,8 @@
     private static StaticMessageReceiver sMessageReceiver = null;
 
     private FallbackHomeAnimationFactory mActiveAnimationFactory;
+    private final RecentsDisplayModel mRecentsDisplayModel;
+
     private final boolean mRunningOverHome;
 
     private final Matrix mTmpMatrix = new Matrix();
@@ -111,10 +113,11 @@
     public RecentsWindowSwipeHandler(Context context, RecentsAnimationDeviceState deviceState,
             TaskAnimationManager taskAnimationManager, GestureState gestureState, long touchTimeMs,
             boolean continuingLastGesture, InputConsumerController inputConsumer,
-            RecentsWindowFactory recentsWindowFactory, MSDLPlayerWrapper msdlPlayerWrapper) {
+            MSDLPlayerWrapper msdlPlayerWrapper) {
         super(context, deviceState, taskAnimationManager, gestureState, touchTimeMs,
-                continuingLastGesture, inputConsumer, recentsWindowFactory, msdlPlayerWrapper);
+                continuingLastGesture, inputConsumer, msdlPlayerWrapper);
 
+        mRecentsDisplayModel = RecentsDisplayModel.getINSTANCE().get(context);
         mRunningOverHome = mGestureState.getRunningTask() != null
                 && mGestureState.getRunningTask().isHomeTask();
 
@@ -160,7 +163,8 @@
         boolean fromHomeToHome = mRunningOverHome
                 && endTarget == GestureState.GestureEndTarget.HOME;
         if (fromHomeToHome) {
-            RecentsWindowManager manager = mRecentsWindowFactory.get(mDeviceState.getDisplayId());
+            RecentsWindowManager manager =
+                    mRecentsDisplayModel.getRecentsWindowManager(mDeviceState.getDisplayId());
             if (manager != null) {
                 manager.startHome(/* finishRecentsAnimation= */ false);
             }
@@ -225,7 +229,7 @@
             recentsCallback = () -> {
                 callback.run();
                 RecentsWindowManager manager =
-                        mRecentsWindowFactory.get(mDeviceState.getDisplayId());
+                        mRecentsDisplayModel.getRecentsWindowManager(mDeviceState.getDisplayId());
                 if (manager != null) {
                     manager.startHome();
                 }
diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
index be7f8e5..7fe4278 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
@@ -65,11 +65,6 @@
     }
 
     @Override
-    public int getSpokenIntroductionSubtitle() {
-        return R.string.back_gesture_spoken_intro_subtitle;
-    }
-
-    @Override
     public int getSuccessFeedbackTitle() {
         return R.string.gesture_tutorial_nice;
     }
diff --git a/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java b/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java
index 700fbf8..72bff7f 100644
--- a/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java
+++ b/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java
@@ -29,9 +29,9 @@
 
 import androidx.annotation.Nullable;
 
+import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.testing.shared.ResourceUtils;
-import com.android.launcher3.util.DisplayController;
 
 /**
  * Utility class to handle edge swipes for back gestures.
@@ -45,6 +45,7 @@
             "gestures.back_timeout", 250);
 
     private final Context mContext;
+    private final DeviceProfile mDeviceProfile;
 
     private final Point mDisplaySize = new Point();
 
@@ -89,9 +90,10 @@
                 }
             };
 
-    EdgeBackGestureHandler(Context context) {
+    EdgeBackGestureHandler(Context context, DeviceProfile deviceProfile) {
         final Resources res = context.getResources();
         mContext = context;
+        mDeviceProfile = deviceProfile;
 
         mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
         mLongPressTimeout = Math.min(MAX_LONG_PRESS_TIMEOUT,
@@ -116,8 +118,7 @@
             // Add a nav bar panel window.
             mEdgeBackPanel = new EdgeBackGesturePanel(mContext, parent, createLayoutParams());
             mEdgeBackPanel.setBackCallback(mBackCallback);
-            Point currentSize = DisplayController.INSTANCE.get(mContext).getInfo().currentSize;
-            mDisplaySize.set(currentSize.x, currentSize.y);
+            mDisplaySize.set(mDeviceProfile.widthPx, mDeviceProfile.heightPx);
             mEdgeBackPanel.setDisplaySize(mDisplaySize);
         }
     }
diff --git a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
index bc5cc15..0365f89 100644
--- a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
+++ b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
@@ -115,22 +115,13 @@
 
     private void initWindowInsets() {
         View root = findViewById(android.R.id.content);
-        root.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
-            @Override
-            public void onLayoutChange(View v, int left, int top, int right, int bottom,
-                    int oldLeft, int oldTop, int oldRight, int oldBottom) {
-                updateExclusionRects(root);
-            }
-        });
+        root.addOnLayoutChangeListener(
+                (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
+                        updateExclusionRects(root));
 
         // Return CONSUMED if you don't want want the window insets to keep being
         // passed down to descendant views.
-        root.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
-            @Override
-            public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
-                return WindowInsets.CONSUMED;
-            }
-        });
+        root.setOnApplyWindowInsetsListener((v, insets) -> WindowInsets.CONSUMED);
     }
 
     private void updateExclusionRects(View rootView) {
diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
index bf4eaf2..b059695 100644
--- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
@@ -58,11 +58,6 @@
     }
 
     @Override
-    public int getSpokenIntroductionSubtitle() {
-        return R.string.home_gesture_spoken_intro_subtitle;
-    }
-
-    @Override
     public int getSuccessFeedbackTitle() {
         return R.string.home_gesture_tutorial_success;
     }
diff --git a/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java b/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java
index c00f508..fdbd509 100644
--- a/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java
+++ b/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java
@@ -33,6 +33,7 @@
 
 import androidx.annotation.Nullable;
 
+import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.testing.shared.ResourceUtils;
 import com.android.launcher3.util.DisplayController;
 import com.android.launcher3.util.NavigationMode;
@@ -57,15 +58,16 @@
     @Nullable
     private NavBarGestureAttemptCallback mGestureCallback;
 
-    NavBarGestureHandler(Context context) {
+    NavBarGestureHandler(Context context, DeviceProfile deviceProfile) {
         mContext = context;
-        DisplayController.Info displayInfo = DisplayController.INSTANCE.get(mContext).getInfo();
-        Point currentSize = displayInfo.currentSize;
-        mDisplaySize.set(currentSize.x, currentSize.y);
-        mSwipeUpTouchTracker =
-                new TriggerSwipeUpTouchTracker(context, true /*disableHorizontalSwipe*/,
-                        new NavBarPosition(NavigationMode.NO_BUTTON, displayInfo),
-                        this);
+        mDisplaySize.set(deviceProfile.widthPx, deviceProfile.heightPx);
+        mSwipeUpTouchTracker = new TriggerSwipeUpTouchTracker(
+                context,
+                /* disableHorizontalSwipe= */ true,
+                new NavBarPosition(
+                        NavigationMode.NO_BUTTON,
+                        DisplayController.INSTANCE.get(mContext).getInfo()),
+                /* onSwipeUp= */ this);
         mMotionPauseDetector = new MotionPauseDetector(context);
 
         final Resources resources = context.getResources();
diff --git a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
index e45f8d8..ff0d6d1 100644
--- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
@@ -73,11 +73,6 @@
     }
 
     @Override
-    public int getSpokenIntroductionSubtitle() {
-        return R.string.overview_gesture_spoken_intro_subtitle;
-    }
-
-    @Override
     public int getSuccessFeedbackTitle() {
         return R.string.overview_gesture_tutorial_success;
     }
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialController.java b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
index 9510a05..7d14a3e 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
@@ -318,11 +318,6 @@
     }
 
     @StringRes
-    public int getSpokenIntroductionSubtitle() {
-        return NO_ID;
-    }
-
-    @StringRes
     public int getSuccessFeedbackSubtitle() {
         return NO_ID;
     }
@@ -401,17 +396,13 @@
                 isGestureSuccessful
                         ? getSuccessFeedbackTitle() : R.string.gesture_tutorial_try_again,
                 subtitleResId,
-                NO_ID,
-                isGestureSuccessful,
-                false);
+                isGestureSuccessful);
     }
 
     void showFeedback(
             int titleResId,
             int subtitleResId,
-            int spokenSubtitleResId,
-            boolean isGestureSuccessful,
-            boolean useGestureAnimationDelay) {
+            boolean isGestureSuccessful) {
         mFeedbackTitleView.removeCallbacks(mTitleViewCallback);
         if (mFeedbackViewCallback != null) {
             mFeedbackView.removeCallbacks(mFeedbackViewCallback);
@@ -512,7 +503,6 @@
             if (mTutorialType == TutorialType.BACK_NAVIGATION) {
                 resetViewsForBackGesture();
             }
-
         }
 
         mGestureCompleted = false;
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
index 2ff2c83..8174e13 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
@@ -48,6 +48,7 @@
 
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.R;
 import com.android.launcher3.logging.StatsLogManager;
 import com.android.quickstep.interaction.TutorialController.TutorialType;
@@ -175,8 +176,10 @@
         Bundle args = savedInstanceState != null ? savedInstanceState : getArguments();
         mTutorialType = (TutorialType) args.getSerializable(KEY_TUTORIAL_TYPE);
         mGestureComplete = args.getBoolean(KEY_GESTURE_COMPLETE, false);
-        mEdgeBackGestureHandler = new EdgeBackGestureHandler(getContext());
-        mNavBarGestureHandler = new NavBarGestureHandler(getContext());
+        DeviceProfile deviceProfile = LauncherAppState.getInstance(getContext())
+                .getInvariantDeviceProfile().getDeviceProfile(getContext());
+        mEdgeBackGestureHandler = new EdgeBackGestureHandler(getContext(), deviceProfile);
+        mNavBarGestureHandler = new NavBarGestureHandler(getContext(), deviceProfile);
 
         mDeviceProfile = InvariantDeviceProfile.INSTANCE.get(getContext())
                 .getDeviceProfile(getContext());
@@ -212,7 +215,6 @@
     public View onCreateView(
             @NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
         super.onCreateView(inflater, container, savedInstanceState);
-
         mRootView = (RootSandboxLayout) inflater.inflate(
                 R.layout.redesigned_gesture_tutorial_fragment,
                 container,
@@ -268,9 +270,7 @@
             mTutorialController.showFeedback(
                     introTitleResId,
                     introSubtitleResId,
-                    mTutorialController.getSpokenIntroductionSubtitle(),
-                    false,
-                    true);
+                    /* isGestureSuccessful= */ false);
             mIntroductionShown = true;
         }
     }
diff --git a/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt b/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt
index 3aae760..8c26d8f 100644
--- a/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt
+++ b/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt
@@ -96,7 +96,7 @@
         taskRequests[taskId] =
             Pair(
                 task.key,
-                recentsCoroutineScope.launch {
+                recentsCoroutineScope.launch(dispatcherProvider.main) {
                     Log.i(TAG, "requestTaskData: $taskId")
                     fetchIcon(task)
                     fetchThumbnail(task)
@@ -134,7 +134,7 @@
             task.key,
             object : TaskIconChangedCallback {
                 override fun onTaskIconChanged() {
-                    recentsCoroutineScope.launch {
+                    recentsCoroutineScope.launch(dispatcherProvider.main) {
                         updateIcon(task.key.id, getIconFromDataSource(task))
                     }
                 }
@@ -152,7 +152,7 @@
                 }
 
                 override fun onHighResLoadingStateChanged() {
-                    recentsCoroutineScope.launch {
+                    recentsCoroutineScope.launch(dispatcherProvider.main) {
                         updateThumbnail(task.key.id, getThumbnailFromDataSource(task))
                     }
                 }
diff --git a/quickstep/src/com/android/quickstep/recents/di/RecentsDependencies.kt b/quickstep/src/com/android/quickstep/recents/di/RecentsDependencies.kt
index b78e214..9d8fc4f 100644
--- a/quickstep/src/com/android/quickstep/recents/di/RecentsDependencies.kt
+++ b/quickstep/src/com/android/quickstep/recents/di/RecentsDependencies.kt
@@ -39,7 +39,6 @@
 import com.android.systemui.shared.recents.model.Task
 import kotlinx.coroutines.CoroutineName
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.SupervisorJob
 
 internal typealias RecentsScopeId = String
@@ -58,10 +57,13 @@
     private fun startDefaultScope(appContext: Context) {
         createScope(DEFAULT_SCOPE_ID).apply {
             set(RecentsViewData::class.java.simpleName, RecentsViewData())
+            val dispatcherProvider: DispatcherProvider = ProductionDispatchers
             val recentsCoroutineScope =
-                CoroutineScope(SupervisorJob() + Dispatchers.Main + CoroutineName("RecentsView"))
+                CoroutineScope(
+                    SupervisorJob() + dispatcherProvider.unconfined + CoroutineName("RecentsView")
+                )
             set(CoroutineScope::class.java.simpleName, recentsCoroutineScope)
-            set(DispatcherProvider::class.java.simpleName, ProductionDispatchers)
+            set(DispatcherProvider::class.java.simpleName, dispatcherProvider)
             val recentsModel = RecentsModel.INSTANCE.get(appContext)
             val taskVisualsChangedDelegate =
                 TaskVisualsChangedDelegateImpl(
@@ -170,18 +172,6 @@
         log("linked scopes: ${getScope(scopeId).scopeIdsLinked}")
         val instance: Any =
             when (modelClass) {
-                RecentTasksRepository::class.java -> {
-                    with(RecentsModel.INSTANCE.get(appContext)) {
-                        TasksRepository(
-                            this,
-                            thumbnailCache,
-                            iconCache,
-                            get(),
-                            get(),
-                            ProductionDispatchers,
-                        )
-                    }
-                }
                 RecentsViewData::class.java -> RecentsViewData()
                 TaskContainerData::class.java -> TaskContainerData()
                 TaskThumbnailViewData::class.java -> TaskThumbnailViewData()
@@ -253,13 +243,17 @@
         private const val DEFAULT_SCOPE_ID = "RecentsDependencies::GlobalScope"
         private const val TAG = "RecentsDependencies"
         private const val DEBUG = false
+        private var activeRecentsCount = 0
 
         @Volatile private lateinit var instance: RecentsDependencies
 
         fun initialize(view: View): RecentsDependencies = initialize(view.context)
 
         fun initialize(context: Context): RecentsDependencies {
-            synchronized(this) { instance = RecentsDependencies(context.applicationContext) }
+            synchronized(this) {
+                activeRecentsCount++
+                instance = RecentsDependencies(context.applicationContext)
+            }
             return instance
         }
 
@@ -273,9 +267,29 @@
             return instance
         }
 
+        @JvmStatic
         fun destroy() {
-            instance.scopes.clear()
-            instance.startDefaultScope(instance.appContext)
+            // When Launcher Activity restarts, the old view's RecentsView.onDetachedFromWindow
+            // happens after the new view's creation. This means that destroy can be called after a
+            // new initialisation. This check prevents a newly initialised tree from being
+            // destroyed. Ideally we would have 1 instance of the dependency tree for each
+            // RecentsView.
+            //
+            // This check is sufficient to avoid a leak of the dependency tree after the Activity is
+            // destroyed while also allowing Launcher auto-restarts (production behaviour) to easily
+            // reinitialise the dependency tree.
+            //
+            // TODO(b/353917593): Better lifecycle decisions will be implemented in this bug or when
+            //  replacing with Dagger (b/371370483).
+            activeRecentsCount--
+            if (activeRecentsCount == 0) {
+                instance.scopes.clear()
+            } else {
+                instance.log(
+                    "RecentsDependencies was not destroyed. " +
+                        "There is still an active RecentsView instance."
+                )
+            }
         }
     }
 }
diff --git a/quickstep/src/com/android/quickstep/task/thumbnail/TaskThumbnailView.kt b/quickstep/src/com/android/quickstep/task/thumbnail/TaskThumbnailView.kt
index ea4602d..e334695 100644
--- a/quickstep/src/com/android/quickstep/task/thumbnail/TaskThumbnailView.kt
+++ b/quickstep/src/com/android/quickstep/task/thumbnail/TaskThumbnailView.kt
@@ -29,6 +29,7 @@
 import androidx.core.view.isInvisible
 import com.android.launcher3.R
 import com.android.launcher3.util.ViewPool
+import com.android.launcher3.util.coroutines.DispatcherProvider
 import com.android.quickstep.recents.di.RecentsDependencies
 import com.android.quickstep.recents.di.get
 import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.BackgroundOnly
@@ -45,8 +46,12 @@
 import kotlinx.coroutines.cancel
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.launch
 
 class TaskThumbnailView : FrameLayout, ViewPool.Reusable {
+    private val recentsCoroutineScope: CoroutineScope = RecentsDependencies.get()
+    private val dispatcherProvider: DispatcherProvider = RecentsDependencies.get()
+
     private lateinit var viewData: TaskThumbnailViewData
     private lateinit var viewModel: TaskThumbnailViewModel
 
@@ -119,7 +124,9 @@
 
     override fun onDetachedFromWindow() {
         super.onDetachedFromWindow()
-        viewAttachedScope.cancel("TaskThumbnailView detaching from window")
+        recentsCoroutineScope.launch(dispatcherProvider.background) {
+            viewAttachedScope.cancel("TaskThumbnailView detaching from window")
+        }
     }
 
     override fun onRecycle() {
diff --git a/quickstep/src/com/android/quickstep/task/util/TaskOverlayHelper.kt b/quickstep/src/com/android/quickstep/task/util/TaskOverlayHelper.kt
index 203177a..e6c8d27 100644
--- a/quickstep/src/com/android/quickstep/task/util/TaskOverlayHelper.kt
+++ b/quickstep/src/com/android/quickstep/task/util/TaskOverlayHelper.kt
@@ -18,6 +18,7 @@
 
 import android.util.Log
 import android.view.View.OnLayoutChangeListener
+import com.android.launcher3.util.coroutines.DispatcherProvider
 import com.android.quickstep.TaskOverlayFactory
 import com.android.quickstep.recents.di.RecentsDependencies
 import com.android.quickstep.recents.di.get
@@ -33,12 +34,15 @@
 import kotlinx.coroutines.cancel
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.launch
 
 /**
  * Helper for [TaskOverlayFactory.TaskOverlay] to interact with [TaskOverlayViewModel], this helper
  * should merge with [TaskOverlayFactory.TaskOverlay] when it's migrated to MVVM.
  */
 class TaskOverlayHelper(val task: Task, val overlay: TaskOverlayFactory.TaskOverlay<*>) {
+    private val recentsCoroutineScope: CoroutineScope = RecentsDependencies.get()
+    private val dispatcherProvider: DispatcherProvider = RecentsDependencies.get()
     private lateinit var overlayInitializedScope: CoroutineScope
     private var uiState: TaskOverlayUiState = Disabled
 
@@ -101,7 +105,9 @@
     }
 
     fun destroy() {
-        overlayInitializedScope.cancel()
+        recentsCoroutineScope.launch(dispatcherProvider.background) {
+            overlayInitializedScope.cancel("TaskOverlay being destroyed")
+        }
         uiState = Disabled
         overlay.snapshotView.removeOnLayoutChangeListener(snapshotLayoutChangeListener)
         reset()
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt b/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt
index 2e94534..3f0b520 100644
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt
@@ -38,6 +38,7 @@
 import com.android.quickstep.util.SplitSelectStateController
 import com.android.systemui.shared.recents.model.Task
 import com.android.systemui.shared.system.InteractionJankMonitorWrapper
+import com.android.wm.shell.Flags.enableFlexibleTwoAppSplit
 import com.android.wm.shell.shared.split.SplitScreenConstants.PersistentSnapPosition
 
 /**
@@ -52,6 +53,9 @@
  */
 class GroupedTaskView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
     TaskView(context, attrs, type = TaskViewType.GROUPED) {
+
+    private val MINIMUM_RATIO_TO_SHOW_ICON = 0.2f
+
     // TODO(b/336612373): Support new TTV for GroupedTaskView
     var splitBoundsConfig: SplitConfigurationOptions.SplitBounds? = null
         private set
@@ -176,14 +180,32 @@
 
     private fun updateIconPlacement() {
         val splitBoundsConfig = splitBoundsConfig ?: return
-        val taskIconHeight = container.deviceProfile.overviewTaskIconSizePx
+        val deviceProfile = container.deviceProfile
+        val taskIconHeight = deviceProfile.overviewTaskIconSizePx
         val isRtl = layoutDirection == LAYOUT_DIRECTION_RTL
         val inSplitSelection = getThisTaskCurrentlyInSplitSelection() != INVALID_TASK_ID
 
+        if (enableFlexibleTwoAppSplit()) {
+            val topLeftTaskPercent =
+                if (deviceProfile.isLeftRightSplit) splitBoundsConfig.leftTaskPercent
+                else splitBoundsConfig.topTaskPercent
+            val bottomRightTaskPercent = 1 - topLeftTaskPercent
+            taskContainers[0]
+                .iconView
+                .setFlexSplitAlpha(
+                    if (topLeftTaskPercent < MINIMUM_RATIO_TO_SHOW_ICON) 0f else 1f
+                )
+            taskContainers[1]
+                .iconView
+                .setFlexSplitAlpha(
+                    if (bottomRightTaskPercent < MINIMUM_RATIO_TO_SHOW_ICON) 0f else 1f
+                )
+        }
+
         if (enableOverviewIconMenu()) {
             val groupedTaskViewSizes =
                 pagedOrientationHandler.getGroupedTaskViewSizes(
-                    container.deviceProfile,
+                    deviceProfile,
                     splitBoundsConfig,
                     layoutParams.width,
                     layoutParams.height,
@@ -197,7 +219,7 @@
                 layoutParams.height,
                 layoutParams.width,
                 isRtl,
-                container.deviceProfile,
+                deviceProfile,
                 splitBoundsConfig,
                 inSplitSelection,
             )
@@ -211,7 +233,7 @@
                 measuredHeight,
                 measuredWidth,
                 isRtl,
-                container.deviceProfile,
+                deviceProfile,
                 splitBoundsConfig,
                 inSplitSelection,
             )
diff --git a/quickstep/src/com/android/quickstep/views/IconAppChipView.java b/quickstep/src/com/android/quickstep/views/IconAppChipView.java
index ba42594..5270477 100644
--- a/quickstep/src/com/android/quickstep/views/IconAppChipView.java
+++ b/quickstep/src/com/android/quickstep/views/IconAppChipView.java
@@ -56,10 +56,12 @@
     private static final int MENU_BACKGROUND_REVEAL_DURATION = 417;
     private static final int MENU_BACKGROUND_HIDE_DURATION = 333;
 
-    private static final int NUM_ALPHA_CHANNELS = 3;
+    private static final int NUM_ALPHA_CHANNELS = 4;
     private static final int INDEX_CONTENT_ALPHA = 0;
     private static final int INDEX_COLOR_FILTER_ALPHA = 1;
     private static final int INDEX_MODAL_ALPHA = 2;
+    /** Used to hide the app chip for 90:10 flex split. */
+    private static final int INDEX_MINIMUM_RATIO_ALPHA = 3;
 
     private final MultiValueAlpha mMultiValueAlpha;
 
@@ -349,6 +351,11 @@
     }
 
     @Override
+    public void setFlexSplitAlpha(float alpha) {
+        mMultiValueAlpha.get(INDEX_MINIMUM_RATIO_ALPHA).setValue(alpha);
+    }
+
+    @Override
     public int getDrawableWidth() {
         return mIconView == null ? 0 : mIconView.getDrawableWidth();
     }
diff --git a/quickstep/src/com/android/quickstep/views/IconView.kt b/quickstep/src/com/android/quickstep/views/IconView.kt
index 3ee12ab..2e6c4bf 100644
--- a/quickstep/src/com/android/quickstep/views/IconView.kt
+++ b/quickstep/src/com/android/quickstep/views/IconView.kt
@@ -133,6 +133,10 @@
         multiValueAlpha[INDEX_MODAL_ALPHA].setValue(alpha)
     }
 
+    override fun setFlexSplitAlpha(alpha: Float) {
+        multiValueAlpha[INDEX_FLEX_SPLIT_ALPHA].setValue(alpha)
+    }
+
     /**
      * Set the tint color of the icon, useful for scrimming or dimming.
      *
@@ -178,8 +182,9 @@
     }
 
     companion object {
-        private const val NUM_ALPHA_CHANNELS = 2
+        private const val NUM_ALPHA_CHANNELS = 3
         private const val INDEX_CONTENT_ALPHA = 0
         private const val INDEX_MODAL_ALPHA = 1
+        private const val INDEX_FLEX_SPLIT_ALPHA = 2
     }
 }
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index 4ee6ef6..b9f44fe 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -164,13 +164,14 @@
         }
 
         setFreezeViewVisibility(true);
-        if (mContainer.getDesktopVisibilityController() != null) {
-            mContainer.getDesktopVisibilityController().onLauncherStateChanged(toState);
-        }
     }
 
     @Override
     public void onStateTransitionComplete(LauncherState finalState) {
+        if (mContainer.getDesktopVisibilityController() != null) {
+            mContainer.getDesktopVisibilityController().onLauncherStateChanged(finalState);
+        }
+
         if (!finalState.isRecentsViewVisible) {
             // Clean-up logic that occurs when recents is no longer in use/visible.
             reset();
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index b432f53..b71c322 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -25,11 +25,11 @@
 import static com.android.app.animation.Interpolators.ACCELERATE_0_75;
 import static com.android.app.animation.Interpolators.ACCELERATE_DECELERATE;
 import static com.android.app.animation.Interpolators.DECELERATE_2;
+import static com.android.app.animation.Interpolators.EMPHASIZED;
 import static com.android.app.animation.Interpolators.EMPHASIZED_DECELERATE;
 import static com.android.app.animation.Interpolators.FAST_OUT_SLOW_IN;
 import static com.android.app.animation.Interpolators.FINAL_FRAME;
 import static com.android.app.animation.Interpolators.LINEAR;
-import static com.android.app.animation.Interpolators.EMPHASIZED;
 import static com.android.app.animation.Interpolators.clampToProgress;
 import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE;
 import static com.android.launcher3.AbstractFloatingView.TYPE_TASK_MENU;
@@ -179,6 +179,7 @@
 import com.android.launcher3.util.TranslateEdgeEffect;
 import com.android.launcher3.util.VibratorWrapper;
 import com.android.launcher3.util.ViewPool;
+import com.android.launcher3.util.coroutines.DispatcherProvider;
 import com.android.quickstep.BaseContainerInterface;
 import com.android.quickstep.GestureState;
 import com.android.quickstep.OverviewCommandHelper;
@@ -238,6 +239,8 @@
 import kotlin.Unit;
 import kotlin.collections.CollectionsKt;
 
+import kotlinx.coroutines.CoroutineScope;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -927,7 +930,11 @@
                     recentsDependencies.inject(RecentTasksRepository.class),
                     recentsDependencies.inject(RecentsViewData.class)
             );
-            mHelper = new RecentsViewModelHelper(mRecentsViewModel);
+            mHelper = new RecentsViewModelHelper(
+                    mRecentsViewModel,
+                    recentsDependencies.inject(CoroutineScope.class),
+                    recentsDependencies.inject(DispatcherProvider.class)
+            );
 
             recentsDependencies.provide(RecentsRotationStateRepository.class,
                     () -> new RecentsRotationStateRepositoryImpl(mOrientationState));
@@ -1264,9 +1271,6 @@
         if (FeatureFlags.enableSplitContextually()) {
             mSplitSelectStateController.registerSplitListener(mSplitSelectionListener);
         }
-        if (enableRefactorTaskThumbnail()) {
-            mHelper.onAttachedToWindow();
-        }
     }
 
     @Override
@@ -1292,6 +1296,7 @@
         reset();
         if (enableRefactorTaskThumbnail()) {
             mHelper.onDetachedFromWindow();
+            RecentsDependencies.destroy();
         }
     }
 
@@ -5833,19 +5838,19 @@
 
     @Override
     public void addChildrenForAccessibility(ArrayList<View> outChildren) {
-        // Add children in reverse order
-        for (int i = getChildCount() - 1; i >= 0; --i) {
-            outChildren.add(getChildAt(i));
-        }
+        outChildren.addAll(getAccessibilityChildren());
+    }
+
+    public List<View> getAccessibilityChildren() {
+        return mUtils.getAccessibilityChildren();
     }
 
     @Override
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfo(info);
         final AccessibilityNodeInfo.CollectionInfo
-                collectionInfo = AccessibilityNodeInfo.CollectionInfo.obtain(
-                1, getTaskViewCount(), false,
-                AccessibilityNodeInfo.CollectionInfo.SELECTION_MODE_NONE);
+                collectionInfo = new AccessibilityNodeInfo.CollectionInfo(
+                1, getAccessibilityChildren().size(), false);
         info.setCollectionInfo(collectionInfo);
     }
 
@@ -5854,14 +5859,12 @@
         super.onInitializeAccessibilityEvent(event);
         event.setScrollable(hasTaskViews());
 
-        // TODO(b/379942019): Revisit the logic below to make sure it does not rely on the
-        //  `taskViewCount` to update the indices or make it indices free.
-        final int taskViewCount = getTaskViewCount();
         if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
+            final List<View> accessibilityChildren = getAccessibilityChildren();
             final int[] visibleTasks = getVisibleChildrenRange();
-            event.setFromIndex(taskViewCount - visibleTasks[1]);
-            event.setToIndex(taskViewCount - visibleTasks[0]);
-            event.setItemCount(taskViewCount);
+            event.setFromIndex(accessibilityChildren.indexOf(getChildAt(visibleTasks[1])));
+            event.setToIndex(accessibilityChildren.indexOf(getChildAt(visibleTasks[0])));
+            event.setItemCount(accessibilityChildren.size());
         }
     }
 
diff --git a/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java b/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
index b04753b..a1d22fe 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
@@ -25,7 +25,6 @@
 import android.view.View;
 import android.view.Window;
 
-import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
 import com.android.launcher3.BaseActivity;
@@ -34,7 +33,6 @@
 import com.android.launcher3.taskbar.TaskbarUIController;
 import com.android.launcher3.views.ActivityContext;
 import com.android.launcher3.views.ScrimView;
-import com.android.quickstep.util.TISBindHelper;
 
 /**
  * Interface to be implemented by the parent view of RecentsView
@@ -217,6 +215,4 @@
     void setTaskbarUIController(@Nullable TaskbarUIController taskbarUIController);
 
     @Nullable TaskbarUIController getTaskbarUIController();
-
-    @NonNull TISBindHelper getTISBindHelper();
 }
diff --git a/quickstep/src/com/android/quickstep/views/RecentsViewModelHelper.kt b/quickstep/src/com/android/quickstep/views/RecentsViewModelHelper.kt
index 3616fbb..87771c6 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsViewModelHelper.kt
+++ b/quickstep/src/com/android/quickstep/views/RecentsViewModelHelper.kt
@@ -16,28 +16,24 @@
 
 package com.android.quickstep.views
 
+import com.android.launcher3.util.coroutines.DispatcherProvider
 import com.android.quickstep.ViewUtils
 import com.android.quickstep.recents.viewmodel.RecentsViewModel
 import com.android.systemui.shared.recents.model.ThumbnailData
-import kotlinx.coroutines.CoroutineName
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.SupervisorJob
 import kotlinx.coroutines.cancel
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
 
 /** Helper for [RecentsView] to interact with the [RecentsViewModel]. */
-class RecentsViewModelHelper(private val recentsViewModel: RecentsViewModel) {
-    private lateinit var viewAttachedScope: CoroutineScope
-
-    fun onAttachedToWindow() {
-        viewAttachedScope =
-            CoroutineScope(SupervisorJob() + Dispatchers.Default + CoroutineName("RecentsView"))
-    }
-
+class RecentsViewModelHelper(
+    private val recentsViewModel: RecentsViewModel,
+    private val recentsCoroutineScope: CoroutineScope,
+    private val dispatcherProvider: DispatcherProvider,
+) {
     fun onDetachedFromWindow() {
-        viewAttachedScope.cancel("RecentsView detaching from window")
+        recentsCoroutineScope.cancel("RecentsView detaching from window")
     }
 
     fun switchToScreenshot(
@@ -48,7 +44,7 @@
         // Update recentsViewModel and apply the thumbnailOverride ASAP, before waiting inside
         // viewAttachedScope.
         recentsViewModel.setRunningTaskShowScreenshot(true)
-        viewAttachedScope.launch {
+        recentsCoroutineScope.launch(dispatcherProvider.main) {
             recentsViewModel.waitForRunningTaskShowScreenshotToUpdate()
             recentsViewModel.waitForThumbnailsToUpdate(updatedThumbnails)
             withContext(Dispatchers.Main) { ViewUtils.postFrameDrawn(taskView, onFinishRunnable) }
diff --git a/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt b/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt
index 6eeffda..ccf22ce 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt
+++ b/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt
@@ -16,6 +16,8 @@
 
 package com.android.quickstep.views
 
+import android.view.View
+import androidx.core.view.children
 import com.android.launcher3.Flags.enableLargeDesktopWindowingTile
 import com.android.quickstep.util.GroupTask
 import com.android.quickstep.views.RecentsView.RUNNING_TASK_ATTACH_ALPHA
@@ -94,6 +96,12 @@
     /** Returns the last TaskView that should be displayed as a large tile. */
     fun getLastLargeTaskView(): TaskView? = recentsView.taskViews.lastOrNull { it.isLargeTile }
 
+    /**
+     * Gets the list of accessibility children. Currently all the children of RecentsViews are
+     * added, and in the reverse order to the list.
+     */
+    fun getAccessibilityChildren(): List<View> = recentsView.children.toList().reversed()
+
     @JvmOverloads
     /** Returns the first [TaskView], with some tasks possibly hidden in the carousel. */
     fun getFirstTaskViewInCarousel(
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.kt b/quickstep/src/com/android/quickstep/views/TaskView.kt
index 084ea4b..0dbad70 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.kt
+++ b/quickstep/src/com/android/quickstep/views/TaskView.kt
@@ -658,10 +658,10 @@
 
             recentsView?.let {
                 collectionItemInfo =
-                    AccessibilityNodeInfo.CollectionItemInfo.obtain(
+                    AccessibilityNodeInfo.CollectionItemInfo(
                         0,
                         1,
-                        it.taskViewCount - it.indexOfChild(this@TaskView) - 1,
+                        it.getAccessibilityChildren().indexOf(this@TaskView),
                         1,
                         false,
                     )
diff --git a/quickstep/src/com/android/quickstep/views/TaskViewIcon.java b/quickstep/src/com/android/quickstep/views/TaskViewIcon.java
index 94739cb..80e3a2b 100644
--- a/quickstep/src/com/android/quickstep/views/TaskViewIcon.java
+++ b/quickstep/src/com/android/quickstep/views/TaskViewIcon.java
@@ -48,6 +48,11 @@
     void setModalAlpha(float alpha);
 
     /**
+     * Sets the opacity of the view for flex split state.
+     */
+    void setFlexSplitAlpha(float alpha);
+
+    /**
      * Returns this icon view's drawable.
      */
     @Nullable Drawable getDrawable();
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
index 44070cf..5471072 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
@@ -240,6 +240,7 @@
         // verify the hide bubble animation is pending
         assertThat(animatorScheduler.delayedBlock).isNotNull()
 
+        whenever(bubbleStashController.isStashed).thenReturn(true)
         InstrumentationRegistry.getInstrumentation().runOnMainSync {
             animator.onStashStateChangingWhileAnimating()
         }
@@ -249,7 +250,7 @@
         assertThat(animator.isAnimating).isFalse()
         assertThat(bubbleBarView.scaleX).isEqualTo(1)
         assertThat(bubbleBarView.scaleY).isEqualTo(1)
-        verify(bubbleStashController).onNewBubbleAnimationInterrupted(any(), any())
+        verify(bubbleStashController).onNewBubbleAnimationInterrupted(eq(true), any())
 
         // PhysicsAnimatorTestUtils posts the cancellation to the main thread so we need to wait
         // again
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarWindowSandboxContext.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarWindowSandboxContext.kt
index 8c51216..0b94dfd 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarWindowSandboxContext.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarWindowSandboxContext.kt
@@ -25,6 +25,7 @@
 import com.android.launcher3.FakeLauncherPrefs
 import com.android.launcher3.LauncherPrefs
 import com.android.launcher3.dagger.LauncherAppComponent
+import com.android.launcher3.dagger.LauncherAppModule
 import com.android.launcher3.dagger.LauncherAppSingleton
 import com.android.launcher3.util.MainThreadInitializedObject.ObjectSandbox
 import com.android.launcher3.util.SandboxApplication
@@ -116,7 +117,7 @@
 }
 
 @LauncherAppSingleton
-@Component
+@Component(modules = [LauncherAppModule::class])
 interface TaskbarSandboxComponent : LauncherAppComponent {
     @Component.Builder
     interface Builder : LauncherAppComponent.Builder {
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/AbsSwipeUpHandlerTestCase.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/AbsSwipeUpHandlerTestCase.java
index 6dce10b..c334552 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/AbsSwipeUpHandlerTestCase.java
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/AbsSwipeUpHandlerTestCase.java
@@ -52,7 +52,6 @@
 import android.view.ViewTreeObserver;
 
 import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
 import androidx.test.platform.app.InstrumentationRegistry;
 
 import com.android.launcher3.DeviceProfile;
@@ -60,9 +59,9 @@
 import com.android.launcher3.dragndrop.DragLayer;
 import com.android.launcher3.statemanager.BaseState;
 import com.android.launcher3.statemanager.StatefulContainer;
+import com.android.launcher3.util.LauncherModelHelper;
 import com.android.launcher3.util.MSDLPlayerWrapper;
 import com.android.launcher3.util.SystemUiController;
-import com.android.quickstep.fallback.window.RecentsWindowFactory;
 import com.android.quickstep.util.ContextInitListener;
 import com.android.quickstep.util.MotionPauseDetector;
 import com.android.quickstep.views.RecentsView;
@@ -90,8 +89,9 @@
         SWIPE_HANDLER extends AbsSwipeUpHandler<RECENTS_CONTAINER, RECENTS_VIEW, STATE_TYPE>,
         CONTAINER_INTERFACE extends BaseContainerInterface<STATE_TYPE, RECENTS_CONTAINER>> {
 
-    protected final Context mContext =
-            InstrumentationRegistry.getInstrumentation().getTargetContext();
+    protected final LauncherModelHelper mLauncherModelHelper = new LauncherModelHelper();
+    protected final LauncherModelHelper.SandboxModelContext mContext =
+            mLauncherModelHelper.sandboxContext;
     protected final InputConsumerController mInputConsumerController =
             InputConsumerController.getRecentsAnimationInputConsumer();
     protected final ActivityManager.RunningTaskInfo mRunningTaskInfo =
@@ -180,8 +180,7 @@
 
     @Before
     public void setUpRecentsContainer() {
-        mTaskAnimationManager = new TaskAnimationManager(mContext, getRecentsWindowFactory(),
-                mRecentsAnimationDeviceState);
+        mTaskAnimationManager = new TaskAnimationManager(mContext, mRecentsAnimationDeviceState);
         RecentsViewContainer recentsContainer = getRecentsContainer();
         RECENTS_VIEW recentsView = getRecentsView();
 
@@ -383,11 +382,6 @@
         return createSwipeHandler(SystemClock.uptimeMillis(), false);
     }
 
-    @Nullable
-    protected RecentsWindowFactory getRecentsWindowFactory() {
-        return null;
-    }
-
     @NonNull
     protected abstract SWIPE_HANDLER createSwipeHandler(
             long touchTimeMs, boolean continuingLastGesture);
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/DisplayModelTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/DisplayModelTest.kt
new file mode 100644
index 0000000..a939e84
--- /dev/null
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/DisplayModelTest.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2024 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
+
+import android.content.Context
+import android.view.Display
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertNull
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class DisplayModelTest {
+    private val context: Context = ApplicationProvider.getApplicationContext()
+
+    class TestableResource : DisplayModel.DisplayResource() {
+        var isCleanupCalled = false
+
+        override fun cleanup() {
+            isCleanupCalled = true
+        }
+    }
+
+    private val testableDisplayModel =
+        object : DisplayModel<TestableResource>(context) {
+            override fun createDisplayResource(displayId: Int) {
+                displayResourceArray.put(displayId, TestableResource())
+            }
+        }
+
+    @Test
+    fun testCreate() {
+        testableDisplayModel.createDisplayResource(Display.DEFAULT_DISPLAY)
+        val resource = testableDisplayModel.getDisplayResource(Display.DEFAULT_DISPLAY)
+        assertNotNull(resource)
+    }
+
+    @Test
+    fun testCleanAndDelete() {
+        testableDisplayModel.createDisplayResource(Display.DEFAULT_DISPLAY)
+        val resource = testableDisplayModel.getDisplayResource(Display.DEFAULT_DISPLAY)!!
+        assertNotNull(resource)
+        testableDisplayModel.deleteDisplayResource(Display.DEFAULT_DISPLAY)
+        assert(resource.isCleanupCalled)
+        assertNull(testableDisplayModel.getDisplayResource(Display.DEFAULT_DISPLAY))
+    }
+}
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt
index 37accdb..50ba55c 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt
@@ -19,15 +19,13 @@
 import android.graphics.PointF
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.launcher3.Flags.enableLauncherOverviewInWindow
 import com.android.launcher3.R
 import com.android.launcher3.dagger.LauncherAppComponent
+import com.android.launcher3.dagger.LauncherAppModule
 import com.android.launcher3.dagger.LauncherAppSingleton
 import com.android.launcher3.util.LauncherModelHelper
 import com.android.launcher3.util.MSDLPlayerWrapper
-import com.android.quickstep.dagger.QuickStepModule
-import com.android.quickstep.fallback.window.RecentsWindowFactory
+import com.android.quickstep.fallback.window.RecentsDisplayModel
 import com.android.systemui.contextualeducation.GestureType
 import com.android.systemui.shared.system.InputConsumerController
 import dagger.BindsInstance
@@ -55,6 +53,8 @@
 
     @Mock private lateinit var systemUiProxy: SystemUiProxy
 
+    @Mock private lateinit var recentsDisplayModel: RecentsDisplayModel
+
     @Mock private lateinit var msdlPlayerWrapper: MSDLPlayerWrapper
 
     private lateinit var underTest: LauncherSwipeHandlerV2
@@ -70,20 +70,14 @@
     @Before
     fun setup() {
         sandboxContext.initDaggerComponent(
-            DaggerTestComponent.builder().bindSystemUiProxy(systemUiProxy)
+            DaggerTestComponent.builder()
+                .bindSystemUiProxy(systemUiProxy)
+                .bindRecentsDisplayModel(recentsDisplayModel)
         )
+
         val deviceState = mock(RecentsAnimationDeviceState::class.java)
         whenever(deviceState.rotationTouchHelper).thenReturn(mock(RotationTouchHelper::class.java))
 
-        if (enableLauncherOverviewInWindow()) {
-            // Initialize an instance of RecentsWindowFactory directly to simulate its
-            // initialization in TouchInteractionService#onCreate.
-            // This instance will then be used in OverviewComponentObserver.
-            InstrumentationRegistry.getInstrumentation().runOnMainSync {
-                RecentsWindowFactory(sandboxContext)
-            }
-        }
-
         gestureState = spy(GestureState(OverviewComponentObserver(sandboxContext, deviceState), 0))
 
         underTest =
@@ -123,12 +117,14 @@
 }
 
 @LauncherAppSingleton
-@Component(modules = [QuickStepModule::class])
+@Component(modules = [LauncherAppModule::class])
 interface TestComponent : LauncherAppComponent {
     @Component.Builder
     interface Builder : LauncherAppComponent.Builder {
         @BindsInstance fun bindSystemUiProxy(proxy: SystemUiProxy): Builder
 
+        @BindsInstance fun bindRecentsDisplayModel(model: RecentsDisplayModel): Builder
+
         override fun build(): TestComponent
     }
 }
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentsWindowSwipeHandlerTestCase.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentsWindowSwipeHandlerTestCase.java
index 3287fb5..40fefae 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentsWindowSwipeHandlerTestCase.java
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentsWindowSwipeHandlerTestCase.java
@@ -16,17 +16,16 @@
 
 package com.android.quickstep;
 
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.when;
-
 import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
 import androidx.test.filters.SmallTest;
 
+import com.android.launcher3.dagger.LauncherAppComponent;
+import com.android.launcher3.dagger.LauncherAppSingleton;
 import com.android.launcher3.util.LauncherMultivalentJUnit;
+import com.android.quickstep.dagger.QuickStepModule;
 import com.android.quickstep.fallback.FallbackRecentsView;
 import com.android.quickstep.fallback.RecentsState;
-import com.android.quickstep.fallback.window.RecentsWindowFactory;
+import com.android.quickstep.fallback.window.RecentsDisplayModel;
 import com.android.quickstep.fallback.window.RecentsWindowManager;
 import com.android.quickstep.fallback.window.RecentsWindowSwipeHandler;
 import com.android.quickstep.views.RecentsViewContainer;
@@ -35,6 +34,9 @@
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 
+import dagger.BindsInstance;
+import dagger.Component;
+
 @SmallTest
 @RunWith(LauncherMultivalentJUnit.class)
 public class RecentsWindowSwipeHandlerTestCase extends AbsSwipeUpHandlerTestCase<
@@ -44,13 +46,14 @@
         RecentsWindowSwipeHandler,
         FallbackWindowInterface> {
 
-    @Mock private RecentsWindowFactory mRecentsWindowFactory;
+    @Mock private RecentsDisplayModel mRecentsDisplayModel;
     @Mock private FallbackRecentsView<RecentsWindowManager> mRecentsView;
     @Mock private RecentsWindowManager mRecentsWindowManager;
 
     @Before
-    public void setupRecentsWindowFactory() {
-        when(mRecentsWindowFactory.get(anyInt())).thenReturn(mRecentsWindowManager);
+    public void setRecentsDisplayModel() {
+        mContext.initDaggerComponent(DaggerRecentsWindowSwipeHandlerTestCase_TestComponent.builder()
+                .bindRecentsDisplayModel(mRecentsDisplayModel));
     }
 
     @NonNull
@@ -65,16 +68,9 @@
                 touchTimeMs,
                 continuingLastGesture,
                 mInputConsumerController,
-                mRecentsWindowFactory,
                 mMSDLPlayerWrapper);
     }
 
-    @Nullable
-    @Override
-    protected RecentsWindowFactory getRecentsWindowFactory() {
-        return mRecentsWindowFactory;
-    }
-
     @NonNull
     @Override
     protected RecentsViewContainer getRecentsContainer() {
@@ -86,4 +82,14 @@
     protected FallbackRecentsView<RecentsWindowManager> getRecentsView() {
         return mRecentsView;
     }
+
+    @LauncherAppSingleton
+    @Component(modules = { QuickStepModule.class })
+    interface TestComponent extends LauncherAppComponent {
+        @Component.Builder
+        interface Builder extends LauncherAppComponent.Builder {
+            @BindsInstance Builder bindRecentsDisplayModel(RecentsDisplayModel model);
+            @Override LauncherAppComponent build();
+        }
+    }
 }
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/window/RecentsDisplayModelTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/window/RecentsDisplayModelTest.kt
new file mode 100644
index 0000000..d2aa6ac
--- /dev/null
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/window/RecentsDisplayModelTest.kt
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2024 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.recents.window
+
+import android.graphics.Point
+import android.hardware.display.DisplayManager
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.SetFlagsRule
+import android.view.Display
+import android.view.DisplayAdjustments
+import android.view.Surface
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.launcher3.Flags.FLAG_ENABLE_FALLBACK_OVERVIEW_IN_WINDOW
+import com.android.launcher3.Flags.FLAG_ENABLE_LAUNCHER_OVERVIEW_IN_WINDOW
+import com.android.launcher3.dagger.LauncherAppComponent
+import com.android.launcher3.dagger.LauncherAppModule
+import com.android.launcher3.dagger.LauncherAppSingleton
+import com.android.launcher3.util.LauncherModelHelper
+import com.android.launcher3.util.window.CachedDisplayInfo
+import com.android.quickstep.fallback.window.RecentsDisplayModel
+import dagger.BindsInstance
+import dagger.Component
+import org.junit.Assert
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@EnableFlags(FLAG_ENABLE_LAUNCHER_OVERVIEW_IN_WINDOW, FLAG_ENABLE_FALLBACK_OVERVIEW_IN_WINDOW)
+class RecentsDisplayModelTest {
+    @get:Rule val setFlagsRule = SetFlagsRule()
+
+    // initiate dagger components for injection
+    private val launcherModelHelper = LauncherModelHelper()
+    private val context = spy(launcherModelHelper.sandboxContext)
+    private val displayManager: DisplayManager = context.spyService(DisplayManager::class.java)
+    private val display: Display = mock()
+
+    private lateinit var recentsDisplayModel: RecentsDisplayModel
+
+    private val width = 2208
+    private val height = 1840
+
+    @Before
+    fun setup() {
+        // Mock display
+        val displayInfo = CachedDisplayInfo(Point(width, height), Surface.ROTATION_0)
+        whenever(display.rotation).thenReturn(displayInfo.rotation)
+        whenever(display.displayAdjustments).thenReturn(DisplayAdjustments())
+        whenever(context.display).thenReturn(display)
+
+        // Mock displayManager
+        whenever(displayManager.getDisplay(anyInt())).thenReturn(display)
+
+        runOnMainSync { recentsDisplayModel = RecentsDisplayModel.INSTANCE.get(context) }
+        context.initDaggerComponent(
+            DaggerRecentsDisplayModelComponent.builder()
+                .bindRecentsDisplayModel(recentsDisplayModel)
+        )
+    }
+
+    @Test
+    fun testEnsureSingleton() {
+        val recentsDisplayModel2 = RecentsDisplayModel.INSTANCE.get(context)
+        assert(recentsDisplayModel == recentsDisplayModel2)
+    }
+
+    @Test
+    fun testDefaultDisplayCreation() {
+        Assert.assertNotNull(recentsDisplayModel.getRecentsWindowManager(Display.DEFAULT_DISPLAY))
+        Assert.assertNotNull(
+            recentsDisplayModel.getFallbackWindowInterface(Display.DEFAULT_DISPLAY)
+        )
+    }
+
+    @Test
+    fun testCreateSeparateInstances() {
+        val display = Display.DEFAULT_DISPLAY + 1
+        runOnMainSync { recentsDisplayModel.createDisplayResource(display) }
+
+        val defaultManager = recentsDisplayModel.getRecentsWindowManager(Display.DEFAULT_DISPLAY)
+        val secondaryManager = recentsDisplayModel.getRecentsWindowManager(display)
+        Assert.assertNotSame(defaultManager, secondaryManager)
+
+        val defaultInterface =
+            recentsDisplayModel.getFallbackWindowInterface(Display.DEFAULT_DISPLAY)
+        val secondInterface = recentsDisplayModel.getFallbackWindowInterface(display)
+        Assert.assertNotSame(defaultInterface, secondInterface)
+    }
+
+    @Test
+    fun testDestroy() {
+        Assert.assertNotNull(recentsDisplayModel.getRecentsWindowManager(Display.DEFAULT_DISPLAY))
+        Assert.assertNotNull(
+            recentsDisplayModel.getFallbackWindowInterface(Display.DEFAULT_DISPLAY)
+        )
+        recentsDisplayModel.destroy()
+        Assert.assertNull(recentsDisplayModel.getRecentsWindowManager(Display.DEFAULT_DISPLAY))
+        Assert.assertNull(recentsDisplayModel.getFallbackWindowInterface(Display.DEFAULT_DISPLAY))
+    }
+
+    private fun runOnMainSync(f: Runnable) {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync { f.run() }
+    }
+}
+
+@LauncherAppSingleton
+@Component(modules = [LauncherAppModule::class])
+interface RecentsDisplayModelComponent : LauncherAppComponent {
+    @Component.Builder
+    interface Builder : LauncherAppComponent.Builder {
+        @BindsInstance fun bindRecentsDisplayModel(model: RecentsDisplayModel): Builder
+
+        override fun build(): RecentsDisplayModelComponent
+    }
+}
diff --git a/quickstep/tests/src/com/android/quickstep/InputConsumerUtilsTest.java b/quickstep/tests/src/com/android/quickstep/InputConsumerUtilsTest.java
index 2c6b750..f522a2c 100644
--- a/quickstep/tests/src/com/android/quickstep/InputConsumerUtilsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/InputConsumerUtilsTest.java
@@ -56,7 +56,6 @@
 import com.android.launcher3.util.LockedUserState;
 import com.android.launcher3.util.MainThreadInitializedObject;
 import com.android.launcher3.views.BaseDragLayer;
-import com.android.quickstep.fallback.window.RecentsWindowFactory;
 import com.android.quickstep.inputconsumers.AccessibilityInputConsumer;
 import com.android.quickstep.inputconsumers.BubbleBarInputConsumer;
 import com.android.quickstep.inputconsumers.DeviceLockedInputConsumer;
@@ -122,7 +121,7 @@
     @Before
     public void setupTaskAnimationManager() {
         mTaskAnimationManager = new TaskAnimationManager(
-                mContext, mock(RecentsWindowFactory.class), mDeviceState);
+                mContext, mDeviceState);
     }
 
     @Before
diff --git a/quickstep/tests/src/com/android/quickstep/TaplPrivateSpaceTest.java b/quickstep/tests/src/com/android/quickstep/TaplPrivateSpaceTest.java
index b15b78e..e065dba 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplPrivateSpaceTest.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplPrivateSpaceTest.java
@@ -23,6 +23,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assume.assumeFalse;
 
+import android.os.Process;
 import android.util.Log;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -74,8 +75,9 @@
     }
 
     private void createAndStartPrivateProfileUser() {
-        String createUserOutput = executeShellCommand("pm create-user --profileOf 0 --user-type "
-                + "android.os.usertype.profile.PRIVATE " + PRIVATE_PROFILE_NAME);
+        int myUserId = Process.myUserHandle().getIdentifier();
+        String createUserOutput = executeShellCommand("pm create-user --profileOf " + myUserId
+                + " --user-type android.os.usertype.profile.PRIVATE " + PRIVATE_PROFILE_NAME);
         updatePrivateProfileSetupSuccessful("pm create-user", createUserOutput);
         String[] tokens = createUserOutput.split("\\s+");
         mProfileUserId = Integer.parseInt(tokens[tokens.length - 1]);
diff --git a/quickstep/tests/src/com/android/quickstep/TaskAnimationManagerTest.java b/quickstep/tests/src/com/android/quickstep/TaskAnimationManagerTest.java
index 960a467..098b417 100644
--- a/quickstep/tests/src/com/android/quickstep/TaskAnimationManagerTest.java
+++ b/quickstep/tests/src/com/android/quickstep/TaskAnimationManagerTest.java
@@ -30,8 +30,6 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 
-import com.android.quickstep.fallback.window.RecentsWindowFactory;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
@@ -45,9 +43,6 @@
             InstrumentationRegistry.getInstrumentation().getTargetContext();
 
     @Mock
-    private RecentsWindowFactory mRecentsWindowFactory;
-
-    @Mock
     private SystemUiProxy mSystemUiProxy;
 
     private TaskAnimationManager mTaskAnimationManager;
@@ -62,8 +57,7 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mTaskAnimationManager = new TaskAnimationManager(mContext, mRecentsWindowFactory,
-                mRecentsAnimationDeviceState) {
+        mTaskAnimationManager = new TaskAnimationManager(mContext, mRecentsAnimationDeviceState) {
             @Override
             SystemUiProxy getSystemUiProxy() {
                 return mSystemUiProxy;
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 4dd5e1d..b9a2065 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Moenie voorstel nie"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Vasspeldvoorspelling"</string>
     <string name="bubble" msgid="3072951361014076670">"Borrel"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"installeer kortpaaie"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Laat \'n app toe om kortpaaie by te voeg sonder gebruikerinmenging."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"lees tuis-instellings en -kortpaaie"</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index c40ef69..530aa80 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"መተግበሪያውን አይጠቁሙ"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"የፒን ግምት"</string>
     <string name="bubble" msgid="3072951361014076670">"አረፋ"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"አቋራጮችን ይጭናል"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"መተግበሪያው ያለተጠቃሚ ጣልቃ ገብነት አቋራጭ እንዲያክል ያስችለዋል።"</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"የመነሻ ቅንብሮች እና አቋራጮችን ያነባል"</string>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index bbdfebd..879c0db 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -68,10 +68,8 @@
     <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"تطبيقات العمل"</string>
     <string name="widget_category_conversations" msgid="8894438636213590446">"المحادثات"</string>
     <string name="widget_category_note_taking" msgid="3469689394504266039">"تدوين الملاحظات"</string>
-    <!-- no translation found for widget_cell_tap_to_show_add_button_label (4354194214317043581) -->
-    <skip />
-    <!-- no translation found for widget_cell_tap_to_hide_add_button_label (6117805205101555997) -->
-    <skip />
+    <string name="widget_cell_tap_to_show_add_button_label" msgid="4354194214317043581">"إظهار زر الإضافة"</string>
+    <string name="widget_cell_tap_to_hide_add_button_label" msgid="6117805205101555997">"إخفاء زر الإضافة"</string>
     <string name="widget_add_button_label" msgid="2761267068711937179">"إضافة"</string>
     <string name="widget_add_button_content_description" msgid="1810530016360039643">"إضافة التطبيق المصغّر \"<xliff:g id="WIDGET_NAME">%1$s</xliff:g>\""</string>
     <string name="widgets_list_expand_button_label" msgid="7912016136574932622">"عرض الكل"</string>
@@ -102,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"عدم اقتراح التطبيق"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"تثبيت التطبيق المتوقّع"</string>
     <string name="bubble" msgid="3072951361014076670">"فقاعة"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"تثبيت اختصارات"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"للسماح لتطبيق ما بإضافة اختصارات بدون تدخل المستخدم."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"الاطلاع على الإعدادات والاختصارات على الشاشة الرئيسية"</string>
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
index acce0d2..eb20bd1 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"পৰামৰ্শ নিদিব"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"পূৰ্বানুমান কৰা এপ্‌টো পিন কৰক"</string>
     <string name="bubble" msgid="3072951361014076670">"বাবল"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"শ্বৰ্টকাট ইনষ্টল কৰিব পাৰে"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"ব্য়ৱহাৰকাৰীৰ হস্তক্ষেপ অবিহনেই কোনো এপক শ্বৰ্টকাটবোৰ যোগ কৰাৰ অনুমতি দিয়ে।"</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"গৃহ স্ক্ৰীনত ছেটিং আৰু শ্বৰ্টকাটসমূহ পঢ়া"</string>
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
index 8eda426..00850f95 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Tətbiq təklif olunmasın"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Proqnozlaşdırılan tətbiqi bərkidin"</string>
     <string name="bubble" msgid="3072951361014076670">"Qabarcıq"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"qısayolları quraşdır"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Tətbiqə istifadəçi müdaxiləsi olmadan qısayolları əlavə etməyə icazə verir."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"Əsas səhifə ayarlarını və qısayollarını oxumaq"</string>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index 33941ff..3cad215 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Ne predlaži aplikaciju"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Zakači predviđanje"</string>
     <string name="bubble" msgid="3072951361014076670">"Oblačić"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"instaliranje prečica"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Dozvoljava aplikaciji da dodaje prečice bez intervencije korisnika."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"čitanje podešavanja i prečica na početnom ekranu"</string>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index d395006..88b89c1 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Не прапаноўваць праграму"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Замацаваць прапанаваную праграму"</string>
     <string name="bubble" msgid="3072951361014076670">"Бурбалка"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"Стварэнне ярлыкоў"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Дазваляе праграмам дадаваць ярлыкі без умяшання карыстальніка."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"счытваць налады і ярлыкі на галоўным экране"</string>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index cf298c3..b919345 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Без предлагане на приложение"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Фиксиране на предвиждането"</string>
     <string name="bubble" msgid="3072951361014076670">"Балонче"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"инсталиране на преки пътища"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Разрешава на приложението да добавя преки пътища без намеса на потребителя."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"четене на настройките и преките пътища на началния екран"</string>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index f2654bb..7292342 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"অ্যাপ সাজেস্ট করবেন না"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"আপনার প্রয়োজন হতে পারে এমন অ্যাপ পিন করুন"</string>
     <string name="bubble" msgid="3072951361014076670">"বাবল"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"শর্টকাটগুলি ইনস্টল করে"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"একটি অ্যাপ্লিকেশানকে ব্যবহারকারীর হস্তক্ষেপ ছাড়াই শর্টকাটগুলি যোগ করার অনুমতি দেয়৷"</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"হোম স্ক্রিনে সেটিংস ও শর্টকাট পড়ুন"</string>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index 3277e22..a89b953 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Ne predlaži aplikaciju"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Zakači predviđanje"</string>
     <string name="bubble" msgid="3072951361014076670">"Oblačić"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"instaliraj prečice"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Dopušta aplikaciji dodavanje prečica bez posredovanja korisnika."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"čita postavke na početnom ekranu i prečice"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index f8f8e28..4d89e6d 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"No suggereixis l\'aplicació"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Fixa la predicció"</string>
     <string name="bubble" msgid="3072951361014076670">"Bombolla"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"instal·la dreceres"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Permet que una aplicació afegeixi dreceres sense la intervenció de l\'usuari."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"llegir la configuració i les dreceres de la pantalla d\'inici"</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 5fa9154..3b0895f 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Nenavrhovat aplikaci"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Připnout předpověď"</string>
     <string name="bubble" msgid="3072951361014076670">"Bublat"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"instalace zástupce"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Umožňuje aplikaci přidat zástupce bez zásahu uživatele."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"čtení nastavení a zkratek plochy"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 16e3473..ee1c7cb 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Foreslå ikke en app"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Fastgør forslaget"</string>
     <string name="bubble" msgid="3072951361014076670">"Boble"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"installere genveje"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Tillader, at en app tilføjer genveje uden brugerens indgriben."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"læs indstillinger og genveje for startskærm"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index cb64821..e3c2fdc 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"App nicht vorschlagen"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Vorgeschlagene App fixieren"</string>
     <string name="bubble" msgid="3072951361014076670">"Bubble"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"Verknüpfungen installieren"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Ermöglicht einer App das Hinzufügen von Verknüpfungen ohne Eingreifen des Nutzers"</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"Einstellungen und Verknüpfungen auf dem Startbildschirm lesen"</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 672ba05..696a0b5 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Να μην προτείνεται"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Καρφίτσωμα πρόβλεψης"</string>
     <string name="bubble" msgid="3072951361014076670">"Συννεφάκι"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"εγκατάσταση συντομεύσεων"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Επιτρέπει σε μια εφαρμογή την προσθήκη συντομεύσεων χωρίς την παρέμβαση του χρήστη."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"ανάγνωση ρυθμίσεων και συντομεύσεων αρχικής οθόνης"</string>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index a4f88de..2027683 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Don\'t suggest app"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Pin prediction"</string>
     <string name="bubble" msgid="3072951361014076670">"Bubble"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"install shortcuts"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Allows an app to add shortcuts without user intervention."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"read Home settings and shortcuts"</string>
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
index 363bb4b..0ebcd18 100644
--- a/res/values-en-rCA/strings.xml
+++ b/res/values-en-rCA/strings.xml
@@ -100,6 +100,7 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Don\'t suggest app"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Pin Prediction"</string>
     <string name="bubble" msgid="3072951361014076670">"Bubble"</string>
+    <string name="pin_to_taskbar" msgid="1281337899690299038">"Pin to taskbar"</string>
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"install shortcuts"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Allows an app to add shortcuts without user intervention."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"read home settings and shortcuts"</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index a4f88de..2027683 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Don\'t suggest app"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Pin prediction"</string>
     <string name="bubble" msgid="3072951361014076670">"Bubble"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"install shortcuts"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Allows an app to add shortcuts without user intervention."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"read Home settings and shortcuts"</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index a4f88de..2027683 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Don\'t suggest app"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Pin prediction"</string>
     <string name="bubble" msgid="3072951361014076670">"Bubble"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"install shortcuts"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Allows an app to add shortcuts without user intervention."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"read Home settings and shortcuts"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 0344113..6cafd09 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"No sugerir app"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Fijar predicción"</string>
     <string name="bubble" msgid="3072951361014076670">"Burbuja"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"instalar accesos directos"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Permite que una aplicación agregue accesos directos sin que el usuario intervenga."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"leer parámetros de configuración y accesos directos de la página principal"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index fc34acf..badd94a 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"No sugerir aplicación"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Fijar predicción"</string>
     <string name="bubble" msgid="3072951361014076670">"Burbuja"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"instalar accesos directos"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Permite que una aplicación añada accesos directos sin intervención del usuario."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"leer ajustes y accesos directos de la pantalla de inicio"</string>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 5fc3b82..169a378 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Ära soovita rakendust"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Kinnita ennustus"</string>
     <string name="bubble" msgid="3072951361014076670">"Mull"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"installi otseteed"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Võimaldab rakendusel lisada otseteid kasutaja sekkumiseta."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"avakuva seadete ja otseteede lugemine"</string>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index 99f127a..d194482 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Ez iradoki aplikazioa"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Ainguratu iragarpena"</string>
     <string name="bubble" msgid="3072951361014076670">"Burbuila"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"Instalatu lasterbideak"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Erabiltzaileak ezer egin gabe lasterbideak gehitzeko baimena ematen die aplikazioei."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"irakurri hasierako pantailako ezarpenak eta lasterbideak"</string>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 99e8718..f6e0896 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"برنامه پیشنهاد داده نشود"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"سنجاق کردن پیشنهاد"</string>
     <string name="bubble" msgid="3072951361014076670">"حبابک"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"نصب میان‌برها"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"به برنامه اجازه می‌دهد میان‌برها را بدون دخالت کاربر اضافه کند."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"خواندن تنظیمات و میان‌برهای صفحه اصلی"</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 6beb593..64d7b5e 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Älä ehdota sovellusta"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Kiinnitä sovellus"</string>
     <string name="bubble" msgid="3072951361014076670">"Kupla"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"asenna pikakuvakkeita"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Antaa sovelluksen lisätä pikakuvakkeita itsenäisesti ilman käyttäjän valintaa."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"lukea aloitusnäytön asetuksia ja pikakuvakkeita"</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index 696d8af..9f6efe2 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Ne pas suggérer d\'appli"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Épingler la prédiction"</string>
     <string name="bubble" msgid="3072951361014076670">"Bulle"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"installer des raccourcis"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Permet à une appli d\'ajouter des raccourcis sans l\'intervention de l\'utilisateur."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"lire les paramètres et les raccourcis de la page d\'accueil"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index c870afa..e91cd03 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Ne pas suggérer d\'appli"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Épingler la prédiction"</string>
     <string name="bubble" msgid="3072951361014076670">"Bulle"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"installer des raccourcis"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Permettre à une application d\'ajouter des raccourcis sans l\'intervention de l\'utilisateur"</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"Lire les paramètres et les raccourcis de la page d\'accueil"</string>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index 5bcf2fd..7bfa617 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Non suxerir app"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Fixar predición"</string>
     <string name="bubble" msgid="3072951361014076670">"Burbulla"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"instalar atallos"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Permite a unha aplicación engadir atallos sen intervención do usuario."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"ler a configuración e os atallos da pantalla de inicio"</string>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index 1480ea9..4992dd3 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"ઍપ સૂચવશો નહીં"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"પૂર્વાનુમાનને પિન કરો"</string>
     <string name="bubble" msgid="3072951361014076670">"બબલ"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"શૉર્ટકટ ઇન્સ્ટૉલ કરો"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"એપ્લિકેશનને વપરાશકર્તા હસ્તક્ષેપ વગર શોર્ટકટ્સ ઉમેરવાની મંજૂરી આપે છે."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"હોમ સેટિંગ અને શૉર્ટકટ વાંચો"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 32a2a96..0398a27 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"ऐप्लिकेशन का सुझाव न दें"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"सुझाए गए ऐप पिन करें"</string>
     <string name="bubble" msgid="3072951361014076670">"बबल"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"शॉर्टकट इंस्‍टॉल करें"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"ऐप को उपयोगकर्ता के हस्‍तक्षेप के बिना शॉर्टकट जोड़ने देती है."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"होम स्क्रीन की सेटिंग और शॉर्टकट पढ़ने की अनुमति"</string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 726efe8..ab22e7a 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Ne predlaži aplikaciju"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Prikvači predviđenu apl."</string>
     <string name="bubble" msgid="3072951361014076670">"Oblačić"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"instaliranje prečaca"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Aplikaciji omogućuje dodavanje prečaca bez intervencije korisnika."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"čitati postavke i prečace početnog zaslona"</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index b85d3df..ea72c1f 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Ne javasoljon appot"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Várható kitűzése"</string>
     <string name="bubble" msgid="3072951361014076670">"Buborék"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"parancsikonok telepítése"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Lehetővé teszi egy alkalmazás számára, hogy felhasználói beavatkozás nélkül adjon hozzá parancsikonokat."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"kezdőképernyő beállításainak és parancsikonjainak olvasása"</string>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index 36e89b4..46d4b35 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Չառաջարկել"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Ամրացնել առաջարկվող հավելվածը"</string>
     <string name="bubble" msgid="3072951361014076670">"Ամպիկ"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"Դյուրանցումների տեղադրում"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Հավելվածին թույլ է տալիս ավելացնել դյուրանցումներ՝ առանց օգտագործողի միջամտության:"</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"կարդալ հիմնական էկրանի կարգավորումներն ու դյուրանցումները"</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 0d5a819..a9cc4fe 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Jangan sarankan apl"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Pin Prediksi"</string>
     <string name="bubble" msgid="3072951361014076670">"Balon"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"memasang pintasan"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Mengizinkan aplikasi menambahkan pintasan tanpa campur tangan pengguna."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"membaca setelan dan pintasan layar utama"</string>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
index 8f3c604..764435c 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Ekki fá tillögu að forriti"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Festa tillögu"</string>
     <string name="bubble" msgid="3072951361014076670">"Blaðra"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"setja upp flýtileiðir"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Leyfir forriti að bæta við flýtileiðum án íhlutunar notanda."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"lesa stillingar og flýtileiðir heimaskjás"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index f125816..47fb620 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Non suggerire app"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Blocca previsione"</string>
     <string name="bubble" msgid="3072951361014076670">"Fumetto"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"Aggiunta di scorciatoie"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Consente a un\'app di aggiungere scorciatoie automaticamente."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"leggere le impostazioni e le scorciatoie nella schermata Home"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index f7fd83a..7aa7b1a 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"בלי להציע את האפליקציה"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"הצמדת החיזוי"</string>
     <string name="bubble" msgid="3072951361014076670">"בועה"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"התקנת קיצורי דרך"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"מאפשר לאפליקציה להוסיף קיצורי דרך ללא התערבות המשתמש."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"קריאת ההגדרות וקיצורי הדרך בדף הבית"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 9b012c5..93bfb37 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"アプリを表示しない"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"アプリの候補を固定"</string>
     <string name="bubble" msgid="3072951361014076670">"ふきだし"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"ショートカットのインストール"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"ユーザー操作なしでショートカットを追加することをアプリに許可します。"</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"ホームの設定とショートカットの読み取り"</string>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
index 955d65f..e116476 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"არ შემომთავაზო აპი"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"ჩამაგრების პროგნოზირება"</string>
     <string name="bubble" msgid="3072951361014076670">"ბუშტი"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"მალსახმობების დაყენება"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"აპისთვის მალსახმობების დამოუკიდებლად დამატების უფლების მიცემა."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"მთავარი ეკრანის პარამეტრებისა და მალსახმობების წაკითხვა"</string>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
index c50d007..6de095e 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Қолданба ұсынбау"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Болжамды бекіту"</string>
     <string name="bubble" msgid="3072951361014076670">"Қалқыма терезе"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"таңбаша орнату"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Қолданбаға пайдаланушының қатысуынсыз төте пернелерді қосу мүмкіндігін береді."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"негізгі экран параметрлері мен таңбашаларын оқу"</string>
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
index 7a73e69..2a60788 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"កុំណែនាំកម្មវិធី"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"ខ្ទាស់ការ​ព្យាករ"</string>
     <string name="bubble" msgid="3072951361014076670">"ពពុះ"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"ដំឡើង​ផ្លូវកាត់"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"អនុញ្ញាត​ឲ្យ​កម្មវិធី​បន្ថែម​ផ្លូវកាត់​ ដោយ​មិន​ចាំបាច់​​អំពើ​ពី​អ្នក​ប្រើ។"</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"អានការកំណត់ និងផ្លូវកាត់របស់អេក្រង់ដើម"</string>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index 8c988bf..31b95db 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"ಆ್ಯಪ್ ಅನ್ನು ಸೂಚಿಸಬೇಡಿ"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"ಮುನ್ನೋಟ ಪಿನ್ ಮಾಡಿ"</string>
     <string name="bubble" msgid="3072951361014076670">"ಬಬಲ್"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಸ್ಥಾಪಿಸಿ"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"ಬಳಕೆದಾರರ ಹಸ್ತಕ್ಷೇಪವಿಲ್ಲದೆ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಸೇರಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"ಹೋಮ್ ಸ್ಕ್ರೀನ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಓದಿ"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 9f7217b..38cf0db 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"앱 제안 받지 않음"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"예상 앱 고정"</string>
     <string name="bubble" msgid="3072951361014076670">"풍선"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"바로가기 설치"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"앱이 사용자의 작업 없이 바로가기를 추가할 수 있도록 합니다."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"홈 설정 및 바로가기 읽기"</string>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index b7ce9d7..407c036 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Cунушталбасын"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Божомолдонгон колдонмону кадап коюу"</string>
     <string name="bubble" msgid="3072951361014076670">"Көбүкчө"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"тез чакырмаларды орнотуу"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Колдонмого колдонуучуга кайрылбастан тез чакырма кошууга уруксат берет."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"үйдүн параметрлерин жана ыкчам баскычтарын окуу"</string>
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
index 33fff3d..cdb3eab 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"ຢ່າແນະນຳແອັບ"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"ປັກໝຸດການຄາດເດົາ"</string>
     <string name="bubble" msgid="3072951361014076670">"ຟອງ"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"ຕິດຕັ້ງທາງລັດ"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"ອະນຸຍາດໃຫ້ແອັບຯ ເພີ່ມທາງລັດໂດຍບໍ່ຕ້ອງຮັບການຢືນຢັນຈາກຜູ່ໃຊ້."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"ອ່ານການຕັ້ງຄ່າໜ້າຫຼັກ ແລະ ທາງລັດ"</string>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 0d0f5db..78322c6 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Nesiūlyti programos"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Prisegti numatymą"</string>
     <string name="bubble" msgid="3072951361014076670">"Debesėlis"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"įdiegti sparčiuosius klavišus"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Programai leidžiama pridėti sparčiuosius klavišus be naudotojo įsikišimo."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"skaityti pagrindinio ekrano nustatymus ir sparčiuosius klavišus"</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index c86c6bb..ff3e105 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Neieteikt lietotni"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Piespraust prognozēto lietotni"</string>
     <string name="bubble" msgid="3072951361014076670">"Burbulis"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"instalēt saīsnes"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Ļauj lietotnei pievienot saīsnes, nejautājot lietotājam."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"sākuma ekrāna iestatījumu un saīšņu lasīšana"</string>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index 2685c60..02de271 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -68,10 +68,8 @@
     <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Работни"</string>
     <string name="widget_category_conversations" msgid="8894438636213590446">"Разговори"</string>
     <string name="widget_category_note_taking" msgid="3469689394504266039">"Фаќање белешки"</string>
-    <!-- no translation found for widget_cell_tap_to_show_add_button_label (4354194214317043581) -->
-    <skip />
-    <!-- no translation found for widget_cell_tap_to_hide_add_button_label (6117805205101555997) -->
-    <skip />
+    <string name="widget_cell_tap_to_show_add_button_label" msgid="4354194214317043581">"Прикажи го копчето за додавање"</string>
+    <string name="widget_cell_tap_to_hide_add_button_label" msgid="6117805205101555997">"Скриј го копчето за додавање"</string>
     <string name="widget_add_button_label" msgid="2761267068711937179">"Додај"</string>
     <string name="widget_add_button_content_description" msgid="1810530016360039643">"Додај го виџетот <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
     <string name="widgets_list_expand_button_label" msgid="7912016136574932622">"Прикажи ги сите"</string>
@@ -102,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Не предлагај апл."</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Закачи го предвидувањето"</string>
     <string name="bubble" msgid="3072951361014076670">"Балонче"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"инсталирање кратенки"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Овозможува апликацијата да додава кратенки без интервенција на корисникот."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"да чита поставки и кратенки на почетна страница"</string>
@@ -203,7 +203,7 @@
     <string name="remote_action_failed" msgid="1383965239183576790">"Не успеа: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Приватен простор"</string>
     <string name="private_space_secondary_label" msgid="9203933341714508907">"Допрете за да поставите или отворите"</string>
-    <string name="ps_container_title" msgid="4391796149519594205">"Приватен простор"</string>
+    <string name="ps_container_title" msgid="4391796149519594205">"Приватен"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Поставки за „Приватен простор“"</string>
     <string name="ps_container_unlock_button_content_description" msgid="9181551784092204234">"Приватно, отклучено."</string>
     <string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Приватно, заклучено."</string>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index 2c82585..567559e 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"ആപ്പ് നിർദ്ദേശിക്കേണ്ട"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"പ്രവചനം പിൻ ചെയ്യുക"</string>
     <string name="bubble" msgid="3072951361014076670">"ബബിൾ"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"കുറുക്കുവഴികൾ ഇൻസ്റ്റാളുചെയ്യുക"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"ഉപയോക്തൃ ഇടപെടൽ ഇല്ലാതെ കുറുക്കുവഴികൾ ചേർക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"ഹോം ക്രമീകരണവും കുറുക്കുവഴികളും വായിക്കുക"</string>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index 434a731..3ff8a7b 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Апп бүү санал болго"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Таамаглалыг бэхлэх"</string>
     <string name="bubble" msgid="3072951361014076670">"Бөмбөлөг"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"товчлол суулгах"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Апп нь хэрэглэгчийн оролцоогүйгээр товчлолыг нэмэж чадна"</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"нүүрний тохиргоо болон товчлолыг унших"</string>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index c872cc6..bc29467 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"ॲप सुचवू नका"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"पूर्वानुमान पिन करा"</string>
     <string name="bubble" msgid="3072951361014076670">"बबल"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"शॉर्टकट इंस्टॉल करा"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"वापरकर्ता हस्तक्षेपाशिवाय शॉर्टकट जोडण्यास अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"होम सेटिंग्ज आणि शॉर्टकट वाचा"</string>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index f5dca93..016d4b1 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Jangan cadangkan apl"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Sematkan Ramalan"</string>
     <string name="bubble" msgid="3072951361014076670">"Gelembung"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"pasang pintasan"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Membenarkan apl menambah pintasan tanpa campur tangan pengguna."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"membaca tetapan dan pintasan skrin utama"</string>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index 24f4435..e26a4dc 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"အက်ပ်အကြံမပြုပါနှင့်"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"ခန့်မှန်းချက်ကို ပင်ထိုးရန်"</string>
     <string name="bubble" msgid="3072951361014076670">"ပူဖောင်းကွက်"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"ဖြတ်လမ်းလင့်ခ်များ ထည့်သွင်းခြင်း"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"အသုံးပြုသူ လုပ်ဆောင်မှုမရှိပဲ အပ်ပလီကေးရှင်းကို အတိုကောက်မှတ်သားမှုများ ပြုလုပ်ခွင့် ပေးခြင်း"</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"ပင်မဆက်တင်နှင့် ဖြတ်လမ်းလင့်ခ်များ ဖတ်ခြင်း"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index a79740d..069e232 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Ikke foreslå app"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Fest forslaget"</string>
     <string name="bubble" msgid="3072951361014076670">"Boble"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"installere snarveier"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Gir apper tillatelse til å legge til snarveier uten innblanding fra brukeren."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"lese startsideinnstillinger og -snarveier"</string>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index f35b943..cfa4740 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"एप सिफारिस नगर्नुहोस्"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"सिफारिस गरिएको एप पिन गर्नुहोस्"</string>
     <string name="bubble" msgid="3072951361014076670">"बबल"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"सर्टकट स्थापना गर्नेहोस्"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"प्रयोगकर्ताको हस्तक्षेप बिना एउटा एपलाई सर्टकटमा थप्नको लागि अनुमति दिनुहोस्।"</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"होम स्क्रिनका सेटिङ र सर्टकटहरू रिड गर्नुहोस्"</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 5083976..39120f9 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Geen app voorstellen"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Voorspelling vastzetten"</string>
     <string name="bubble" msgid="3072951361014076670">"Bubbel"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"Snelle links instellen"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Een app toestaan snelkoppelingen toe te voegen zonder tussenkomst van de gebruiker."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"instellingen en snelkoppelingen op startscherm lezen"</string>
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
index a26a7c5..6351de1 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"ଆପ ପରାମର୍ଶ ଦିଅନ୍ତୁ ନାହିଁ"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"ପୂର୍ବାନୁମାନକୁ ପିନ୍ କରନ୍ତୁ"</string>
     <string name="bubble" msgid="3072951361014076670">"ବବଲ"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"ସର୍ଟକଟ୍‍ ଇନଷ୍ଟଲ୍‌ କରନ୍ତୁ"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"ୟୁଜରଙ୍କ ବିନା ହସ୍ତକ୍ଷେପରେ ଶର୍ଟକଟ୍‌ ଯୋଡ଼ିବାକୁ ଆପକୁ ଅନୁମତି ଦିଏ।"</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"ହୋମ ସେଟିଂସ ଏବଂ ସର୍ଟକଟଗୁଡ଼ିକୁ ପଢ଼ନ୍ତୁ"</string>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index feda5b5..c7c6319 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"ਐਪ ਦਾ ਸੁਝਾਅ ਨਾ ਦਿਓ"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"ਪੂਰਵ-ਅਨੁਮਾਨ ਪਿੰਨ ਕਰੋ"</string>
     <string name="bubble" msgid="3072951361014076670">"ਬਬਲ"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"ਸ਼ਾਰਟਕੱਟ ਸਥਾਪਤ ਕਰੋ"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"ਇੱਕ ਐਪ ਨੂੰ ਵਰਤੋਂਕਾਰ ਦੇ ਦਖ਼ਲ ਤੋਂ ਬਿਨਾਂ ਸ਼ਾਰਟਕੱਟ ਸ਼ਾਮਲ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"ਹੋਮ ਸੈਟਿੰਗਾਂ ਅਤੇ ਸ਼ਾਰਟਕੱਟ ਪੜ੍ਹੋ"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index bf1299d..b8cc4b8 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Nie proponuj aplikacji"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Przypnij podpowiedź"</string>
     <string name="bubble" msgid="3072951361014076670">"Dymek"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"Instalowanie skrótów"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Pozwala aplikacji dodawać skróty bez interwencji użytkownika."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"Odczytuje ustawienia i skróty na ekranie głównym"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 17af437..aa6062d 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Não sugerir app"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Fixar previsão"</string>
     <string name="bubble" msgid="3072951361014076670">"Balão"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"instalar atalhos"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Permite a uma app adicionar atalhos sem a intervenção do utilizador."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"ler definições e atalhos do ecrã Principal"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 4bc8e7c..2435d8d 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Não sugerir esse app"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Fixar previsão"</string>
     <string name="bubble" msgid="3072951361014076670">"Balão"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"instalar atalhos"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Permite que um app adicione atalhos sem intervenção do usuário."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"ler configurações e atalhos da tela inicial"</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 5763edb..d1fcefa 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Nu sugera aplicația"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Fixează predicția"</string>
     <string name="bubble" msgid="3072951361014076670">"Balon"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"instalează comenzi rapide"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Permite unei aplicații să adauge comenzi rapide fără intervenția utilizatorului."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"citește setările și comenzile rapide de pe ecranul de pornire"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index d9f0b40..dd59b78 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Не рекомендовать"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Закрепить рекомендацию"</string>
     <string name="bubble" msgid="3072951361014076670">"Подсказка"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"Создание ярлыков"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Приложение сможет самостоятельно добавлять ярлыки."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"Доступ к данным о настройках и ярлыках на главном экране"</string>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
index 756d6fe..d143032 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"යෙදුම යෝජනා නොකරන්න"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"පුරෝකථනය අමුණන්න"</string>
     <string name="bubble" msgid="3072951361014076670">"බුබුළ"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"කෙටිමං ස්ථාපනය කරන්න"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"පරිශීලක මැදිහත්වීමෙන් තොරව කෙටිමං එක් කිරීමට යෙදුමකට අවසර දෙයි."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"මුල් පිටු සැකසීම් සහ කෙටි මං කියවන්න"</string>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 5fc0c41..c5b84a1 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Nenavrhovať aplikáciu"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Pripnúť predpoveď"</string>
     <string name="bubble" msgid="3072951361014076670">"Bublina"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"inštalácia odkazov"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Povoľuje aplikácii pridať odkazy bez zásahu používateľa."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"čítanie nastavení a odkazov plochy"</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 5ab0106..263a7f6 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Ne predlagaj"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Predvidevanje pripenjanja"</string>
     <string name="bubble" msgid="3072951361014076670">"Mehurček"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"namestitev bližnjic"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Aplikaciji dovoli dodajanje bližnjic brez posredovanja uporabnika."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"branje nastavitev in bližnjic na začetnem zaslonu"</string>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index 995db0f..e8fd7cb 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -68,10 +68,8 @@
     <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Puna"</string>
     <string name="widget_category_conversations" msgid="8894438636213590446">"Bisedat"</string>
     <string name="widget_category_note_taking" msgid="3469689394504266039">"Mbajtja e shënimeve"</string>
-    <!-- no translation found for widget_cell_tap_to_show_add_button_label (4354194214317043581) -->
-    <skip />
-    <!-- no translation found for widget_cell_tap_to_hide_add_button_label (6117805205101555997) -->
-    <skip />
+    <string name="widget_cell_tap_to_show_add_button_label" msgid="4354194214317043581">"Shfaq butonin e shtimit"</string>
+    <string name="widget_cell_tap_to_hide_add_button_label" msgid="6117805205101555997">"Fshih butonin e shtimit"</string>
     <string name="widget_add_button_label" msgid="2761267068711937179">"Shto"</string>
     <string name="widget_add_button_content_description" msgid="1810530016360039643">"Shto miniaplikacionin <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
     <string name="widgets_list_expand_button_label" msgid="7912016136574932622">"Shfaq të gjitha"</string>
@@ -102,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Mos sugjero aplikacion"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Gozhdo parashikimin"</string>
     <string name="bubble" msgid="3072951361014076670">"Flluskë"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"instalimi i shkurtoreve"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Lejon një aplikacion të shtojë shkurtore pa ndërhyrjen e përdoruesit."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"lexo cilësimet dhe shkurtoret e ekranit bazë"</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 2b2fac8..4ef941a 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Не предлажи апликацију"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Закачи предвиђање"</string>
     <string name="bubble" msgid="3072951361014076670">"Облачић"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"инсталирање пречица"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Дозвољава апликацији да додаје пречице без интервенције корисника."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"читање подешавања и пречица на почетном екрану"</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 74e35ac..26b1a3b 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Föreslå inte app"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Fäst förslag"</string>
     <string name="bubble" msgid="3072951361014076670">"Bubbla"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"installera genvägar"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Tillåter att en app lägger till genvägar utan åtgärd från användaren."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"läsa inställningar och genvägar på startskärmen"</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index d696410..0426cc5 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Isipendekeze programu"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Bandika Utabiri"</string>
     <string name="bubble" msgid="3072951361014076670">"Kiputo"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"kuweka njia za mkato"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Huruhusu programu kuongeza njia za mkato bila mtumiaji kuingilia kati."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"kusoma mipangilio ya skrini ya kwanza na njia za mkato"</string>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index 0b94252..90f5d80 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"பரிந்துரைக்காதே"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"கணிக்கப்பட்டதைப் பின் செய்"</string>
     <string name="bubble" msgid="3072951361014076670">"குமிழ்"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"குறுக்குவழிகளை நிறுவுதல்"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"பயனரின் அனுமதி இல்லாமல் குறுக்குவழிகளைச் சேர்க்கப் ஆப்ஸை அனுமதிக்கிறது."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"முகப்புத் திரையின் அமைப்புகளையும் ஷார்ட்கட்களையும் படித்தல்"</string>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index 90ebe1e..1fc169a 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"యాప్ సూచించకు"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"సూచనను పిన్ చేయండి"</string>
     <string name="bubble" msgid="3072951361014076670">"బబుల్"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"షార్ట్‌కట్‌లను ఇన్‌స్టాల్ చేయడం"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"వినియోగదారు ప్రమేయం లేకుండా షార్ట్‌కట్‌లను జోడించడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"హోమ్ సెట్టింగ్‌లు, షార్ట్‌కట్‌లను చదవండి"</string>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 08944ed..d8484be 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"ไม่ต้องแนะนำแอป"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"ปักหมุดแอปที่คาดการณ์ไว้"</string>
     <string name="bubble" msgid="3072951361014076670">"บับเบิล"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"ติดตั้งทางลัด"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"อนุญาตให้แอปเพิ่มทางลัดโดยไม่ต้องให้ผู้ใช้จัดการ"</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"อ่านการตั้งค่าและทางลัดในหน้าแรก"</string>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index b504adc..5596eb5 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Huwag magmungkahi"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"I-pin ang Hula"</string>
     <string name="bubble" msgid="3072951361014076670">"Bubble"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"i-install ang mga shortcut"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Pinapayagan ang isang app na magdagdag ng mga shortcut nang walang panghihimasok ng user."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"basahin ang mga setting at shortcut ng home"</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 094b597..ca96d8e 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Uygulamayı önerme"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Tahmini Sabitle"</string>
     <string name="bubble" msgid="3072951361014076670">"Balon"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"kısayolları yükle"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Uygulamaya, kullanıcı müdahalesi olmadan kısayol ekleme izni verir."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"ana ekran ayarlarını ve kısayollarını oku"</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index f90998d..9b02400 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Не пропонувати додаток"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Закріпити передбачений додаток"</string>
     <string name="bubble" msgid="3072951361014076670">"Повідомлення"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"створення ярликів"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Дозволяє програмі самостійно додавати ярлики."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"читати налаштування та ярлики головного екрана"</string>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index 1a90602..a9f7510 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"ایپ تجویز نہ کریں"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"پیشگوئی پن کریں"</string>
     <string name="bubble" msgid="3072951361014076670">"بلبلہ"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"شارٹ کٹس انسٹال کریں"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"کسی ایپ کو صارف کی مداخلت کے بغیر شارٹ کٹس شامل کرنے کی اجازت دیتا ہے۔"</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"ہوم ترتیبات اور شارٹ کٹس کو پڑھیں"</string>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index 62fede8..3c800ae 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Tavsiya qilinmasin"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Tavsiyani mahkamlash"</string>
     <string name="bubble" msgid="3072951361014076670">"Pufaklar"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"yorliqlar yaratish"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Ilovalarga foydalanuvchidan so‘ramasdan yorliqlar qo‘shishga ruxsat beradi."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"Bosh ekrandagi sozlamalar va yorliqlarni koʻrish"</string>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 8e5f75c..2daa1db 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Không gợi ý ứng dụng"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Ghim ứng dụng dự đoán"</string>
     <string name="bubble" msgid="3072951361014076670">"Bong bóng"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"cài đặt lối tắt"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Cho phép ứng dụng thêm lối tắt mà không cần sự can thiệp của người dùng."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"đọc lối tắt và các chế độ cài đặt trên màn hình chính"</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index edc5646..01426df 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"不要推荐此应用"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"固定预测的应用"</string>
     <string name="bubble" msgid="3072951361014076670">"气泡框"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"安装快捷方式"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"允许应用自行添加快捷方式。"</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"读取主屏幕设置和快捷方式"</string>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 7f4ac59..0e7a44d 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"不要提供應用程式建議"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"固定預測"</string>
     <string name="bubble" msgid="3072951361014076670">"氣泡"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"安裝捷徑"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"允許應用程式無需使用者許可也可新增捷徑。"</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"讀取主畫面設定和捷徑"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index f527a2a..56fb080 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"不要建議此應用程式"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"固定預測的應用程式"</string>
     <string name="bubble" msgid="3072951361014076670">"泡泡"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"安裝捷徑"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"允許應用程式自動新增捷徑。"</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"讀取主畫面設定和捷徑"</string>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 3c3a75c..9f479b9 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -100,6 +100,8 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Ungaphakamisi uhlelo lokusebenza"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"Ukubikezela Iphinikhodi"</string>
     <string name="bubble" msgid="3072951361014076670">"Ibhamuza"</string>
+    <!-- no translation found for pin_to_taskbar (1281337899690299038) -->
+    <skip />
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"faka izinqamuleli"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"Ivumela uhlelo lokusebenza ukufaka izinqamuleli ngaphandle kokungenelela komsebenzisi."</string>
     <string name="permlab_read_settings" msgid="5136500343007704955">"funda amasethingi wasekhaya nezinqamuleli"</string>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2fc039e..6f293b6 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -190,6 +190,8 @@
     <!-- Label for the header text of the All Apps section in All Apps view, used to separate Predicted Apps and Actions section from All Apps section. [CHAR_LIMIT=50] -->
     <string name="all_apps_label">All apps</string>
 
+    <string name="all_apps_list_label">Apps list</string>
+
     <!-- Popup items -->
     <!-- Text to display as the header above notifications. [CHAR_LIMIT=30] -->
     <string name="notifications_header">Notifications</string>
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 1fc14ec..c78666e 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -743,7 +743,7 @@
         appTitleBounds = new RectF((tmpRect.width() - titleLength) / 2.f - getCompoundPaddingLeft(),
                 0, (tmpRect.width() + titleLength) / 2.f + getCompoundPaddingRight(),
                 (int) Math.ceil(fm.bottom - fm.top));
-        appTitleBounds.inset(mRoundRectPadding * 2, 0);
+        appTitleBounds.inset((mAppTitleHorizontalPadding) * 2, 0);
 
 
         if (mIcon != null) {
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 6814ce7..94b1a2a 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -58,6 +58,7 @@
 import static com.android.launcher3.LauncherConstants.TraceEvents.ON_NEW_INTENT_EVT;
 import static com.android.launcher3.LauncherConstants.TraceEvents.ON_RESUME_EVT;
 import static com.android.launcher3.LauncherConstants.TraceEvents.ON_START_EVT;
+import static com.android.launcher3.LauncherPrefs.FIXED_LANDSCAPE_MODE;
 import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP;
 import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
 import static com.android.launcher3.LauncherState.ALL_APPS;
@@ -785,9 +786,13 @@
             return;
         }
         // When the flag oneGridSpecs is on we want to disable ALLOW_ROTATION which is replaced
-        // by FIXED_LANDSCAPE_MODE, ALLOW_ROTATION will only be used on Tablets afterwards.
-        if (getDeviceProfile().isPhone || getDeviceProfile().isTwoPanels) {
+        // by FIXED_LANDSCAPE_MODE, ALLOW_ROTATION will only be used on Tablets and foldables
+        // afterwards.
+        if (getDeviceProfile().isPhone) {
             LauncherPrefs.get(this).put(LauncherPrefs.ALLOW_ROTATION, false);
+        } else if (getDeviceProfile().isTablet) {
+            // Tablet do not use fixed landscape mode, make sure it can't be activated by mistake
+            LauncherPrefs.get(this).put(FIXED_LANDSCAPE_MODE, false);
         }
         getRotationHelper().setFixedLandscape(
                 Objects.requireNonNull(mDeviceProfile.inv).isFixedLandscape
diff --git a/src/com/android/launcher3/model/GridSizeMigrationLogic.kt b/src/com/android/launcher3/model/GridSizeMigrationLogic.kt
index 75fd31e..6f86ae0 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationLogic.kt
+++ b/src/com/android/launcher3/model/GridSizeMigrationLogic.kt
@@ -30,6 +30,7 @@
 import com.android.launcher3.LauncherSettings.Favorites.TMP_TABLE
 import com.android.launcher3.Utilities
 import com.android.launcher3.config.FeatureFlags
+import com.android.launcher3.logging.FileLog
 import com.android.launcher3.model.GridSizeMigrationDBController.DbReader
 import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction
 import com.android.launcher3.provider.LauncherDbUtils.copyTable
@@ -57,10 +58,10 @@
             return
         }
 
-        val isFirstLoad = get(context).get(LauncherPrefs.IS_FIRST_LOAD_AFTER_RESTORE)
-        Log.d(
+        val isAfterRestore = get(context).get(LauncherPrefs.IS_FIRST_LOAD_AFTER_RESTORE)
+        FileLog.d(
             TAG,
-            "Begin grid migration. First load: $isFirstLoad\n srcDeviceState: " +
+            "Begin grid migration. isAfterRestore: $isAfterRestore\nsrcDeviceState: " +
                 "$srcDeviceState\ndestDeviceState: $destDeviceState\nisDestNewDb: $isDestNewDb",
         )
 
@@ -112,7 +113,7 @@
                 t.commit()
             }
         } catch (e: Exception) {
-            Log.e(TAG, "Error during grid migration", e)
+            FileLog.e(TAG, "Error during grid migration", e)
         } finally {
             Log.v(
                 TAG,
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index 4981949..bc0d776 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -263,6 +263,9 @@
             // sanitizeData should not be invoked if the workspace is loaded from a db different
             // from the main db as defined in the invariant device profile.
             // (e.g. both grid preview and minimal device mode uses a different db)
+            // TODO(b/384731096): Write Unit Test to make sure sanitizeWidgetsShortcutsAndPackages
+            //  actually re-pins shortcuts that are in model but not in ShortcutManager, if possible
+            //  after a simulated restore.
             if (Objects.equals(mApp.getInvariantDeviceProfile().dbFile, mDbName)) {
                 verifyNotStopped();
                 sanitizeFolders(mItemsDeleted);
@@ -390,7 +393,7 @@
             }
         } catch (CancellationException e) {
             // Loader stopped, ignore
-            FileLog.w(TAG, "LoaderTask cancelled:", e);
+            FileLog.w(TAG, "LoaderTask cancelled");
         } catch (Exception e) {
             memoryLogger.printLogs();
             throw e;
@@ -399,7 +402,7 @@
     }
 
     public synchronized void stopLocked() {
-        FileLog.w(TAG, "LoaderTask#stopLocked:", new Exception());
+        FileLog.w(TAG, "stopLocked: Loader stopping");
         mStopped = true;
         this.notify();
     }
diff --git a/src/com/android/launcher3/model/ModelDbController.java b/src/com/android/launcher3/model/ModelDbController.java
index 6ff8547..e76391f 100644
--- a/src/com/android/launcher3/model/ModelDbController.java
+++ b/src/com/android/launcher3/model/ModelDbController.java
@@ -96,7 +96,7 @@
  * around it.
  */
 public class ModelDbController {
-    private static final String TAG = "LauncherProvider";
+    private static final String TAG = "ModelDbController";
 
     private static final String EMPTY_DATABASE_CREATED = "EMPTY_DATABASE_CREATED";
     public static final String EXTRA_DB_NAME = "db_name";
@@ -303,7 +303,7 @@
         if (restoreEventLogger != null) {
             sendMetricsForFailedMigration(restoreEventLogger, getDb());
         }
-        FileLog.d(TAG, "Migration failed: resetting launcher database");
+        FileLog.d(TAG, "resetLauncherDb: Migration failed: resetting launcher database");
         createEmptyDB();
         LauncherPrefs.get(mContext).putSync(
                 getEmptyDbCreatedKey(mOpenHelper.getDatabaseName()).to(true));
@@ -331,7 +331,7 @@
     private boolean isThereExistingDb() {
         if (LauncherPrefs.get(mContext).get(getEmptyDbCreatedKey())) {
             // If we already have a new DB, ignore migration
-            FileLog.d(TAG, "migrateGridIfNeeded: new DB already created, skipping migration");
+            FileLog.d(TAG, "isThereExistingDb: new DB already created, skipping migration");
             return true;
         }
         return false;
@@ -342,7 +342,7 @@
         if (GridSizeMigrationDBController.needsToMigrate(mContext, idp)) {
             return true;
         }
-        FileLog.d(TAG, "migrateGridIfNeeded: no grid migration needed");
+        FileLog.d(TAG, "isGridMigrationNecessary: no grid migration needed");
         return false;
     }
 
@@ -350,7 +350,9 @@
         InvariantDeviceProfile idp = LauncherAppState.getIDP(mContext);
         String targetDbName = new DeviceGridState(idp).getDbFile();
         if (TextUtils.equals(targetDbName, mOpenHelper.getDatabaseName())) {
-            FileLog.e(TAG, "migrateGridIfNeeded: target db is same as current: " + targetDbName);
+            FileLog.e(TAG, "isCurrentDbSameAsTarget: target db is same as current"
+                    + " current db: " + mOpenHelper.getDatabaseName()
+                    + " target db: " + targetDbName);
             return true;
         }
         return false;
@@ -385,13 +387,12 @@
             DeviceGridState destDeviceState = new DeviceGridState(idp);
 
             boolean isDestNewDb = !existingDBs.contains(destDeviceState.getDbFile());
-
             GridSizeMigrationLogic gridSizeMigrationLogic = new GridSizeMigrationLogic();
             gridSizeMigrationLogic.migrateGrid(mContext, srcDeviceState, destDeviceState,
                     mOpenHelper, oldHelper.getWritableDatabase(), isDestNewDb);
         } catch (Exception e) {
             resetLauncherDb(restoreEventLogger);
-            throw new Exception("Failed to migrate grid", e);
+            throw new Exception("attemptMigrateDb: Failed to migrate grid", e);
         } finally {
             if (mOpenHelper != oldHelper) {
                 oldHelper.close();
@@ -415,7 +416,7 @@
                     sendMetricsForFailedMigration(restoreEventLogger, getDb());
                 }
             }
-            FileLog.d(TAG, "Migration failed: resetting launcher database");
+            FileLog.d(TAG, "tryMigrateDB: Migration failed: resetting launcher database");
             createEmptyDB();
             LauncherPrefs.get(mContext).putSync(
                     getEmptyDbCreatedKey(mOpenHelper.getDatabaseName()).to(true));
@@ -447,17 +448,17 @@
         }
         String targetDbName = new DeviceGridState(idp).getDbFile();
         if (TextUtils.equals(targetDbName, mOpenHelper.getDatabaseName())) {
-            FileLog.e(TAG, "migrateGridIfNeeded: target db is same as current: " + targetDbName);
+            FileLog.e(TAG, "migrateGridIfNeeded: target db is same as current"
+                    + " current db: " + mOpenHelper.getDatabaseName()
+                    + " target db: " + targetDbName);
             return false;
         }
         DatabaseHelper oldHelper = mOpenHelper;
-
         // We save the existing db's before creating the destination db helper so we know what logic
         // to run in grid migration based on if that grid already existed before migration or not.
         List<String> existingDBs = LauncherFiles.GRID_DB_FILES.stream()
                 .filter(dbName -> mContext.getDatabasePath(dbName).exists())
                 .toList();
-
         mOpenHelper = (mContext instanceof SandboxContext) ? oldHelper
                 : createDatabaseHelper(true /* forMigration */, targetDbName);
         try {
@@ -465,13 +466,11 @@
             DeviceGridState srcDeviceState = new DeviceGridState(mContext);
             // This is the state we want to migrate to that is given by the idp
             DeviceGridState destDeviceState = new DeviceGridState(idp);
-
             boolean isDestNewDb = !existingDBs.contains(destDeviceState.getDbFile());
-
             return GridSizeMigrationDBController.migrateGridIfNeeded(mContext, srcDeviceState,
                     destDeviceState, mOpenHelper, oldHelper.getWritableDatabase(), isDestNewDb);
         } catch (Exception e) {
-            FileLog.e(TAG, "Failed to migrate grid", e);
+            FileLog.e(TAG, "migrateGridIfNeeded: Failed to migrate grid", e);
             return false;
         } finally {
             if (mOpenHelper != oldHelper) {
diff --git a/src/com/android/launcher3/model/WorkspaceItemProcessor.kt b/src/com/android/launcher3/model/WorkspaceItemProcessor.kt
index e23eba9..0272bd9 100644
--- a/src/com/android/launcher3/model/WorkspaceItemProcessor.kt
+++ b/src/com/android/launcher3/model/WorkspaceItemProcessor.kt
@@ -20,6 +20,7 @@
 import android.content.ComponentName
 import android.content.Intent
 import android.content.pm.LauncherApps
+import android.content.pm.LauncherApps.ShortcutQuery
 import android.content.pm.PackageInstaller
 import android.content.pm.ShortcutInfo
 import android.graphics.Point
@@ -45,6 +46,7 @@
 import com.android.launcher3.pm.PackageInstallInfo
 import com.android.launcher3.pm.UserCache
 import com.android.launcher3.shortcuts.ShortcutKey
+import com.android.launcher3.shortcuts.ShortcutRequest
 import com.android.launcher3.util.ApiWrapper
 import com.android.launcher3.util.ApplicationInfoWrapper
 import com.android.launcher3.util.ComponentKey
@@ -271,7 +273,8 @@
             c.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT -> {
                 val key = ShortcutKey.fromIntent(intent, c.user)
                 if (unlockedUsers[c.serialNumber]) {
-                    val pinnedShortcut = shortcutKeyToPinnedShortcuts[key]
+                    val pinnedShortcut =
+                        shortcutKeyToPinnedShortcuts[key] ?: retryDeepShortcutById(key)
                     if (pinnedShortcut == null) {
                         // The shortcut is no longer valid.
                         c.markDeleted(
@@ -377,6 +380,25 @@
     }
 
     /**
+     * It is possible that the data was cleared from ShortcutManager after it was restored. In that
+     * instance, the Launcher would have a valid Shortcut id, but ShortcutManager wouldn't recognize
+     * it as valid. Here we retry by querying ShortcutManager by package name and shortcut id.
+     */
+    private fun retryDeepShortcutById(key: ShortcutKey): ShortcutInfo? {
+        FileLog.d(TAG, "retryDeepShortcutById: package=${key.packageName}, shortcutId=${key.id}")
+        return launcherApps
+            .getShortcuts(
+                ShortcutQuery().apply {
+                    setPackage(key.packageName)
+                    setShortcutIds(listOf(key.id))
+                    setQueryFlags(ShortcutRequest.ALL)
+                },
+                key.user,
+            )
+            ?.firstOrNull()
+    }
+
+    /**
      * Loads CollectionInfo information from the database and formats it. This function runs while
      * LoaderTask is still active; some of the processing for folder content items is done after all
      * the items in the workspace have been loaded. The loaded and formatted CollectionInfo is then
diff --git a/src_no_quickstep/com/android/launcher3/dagger/LauncherAppComponent.java b/src_no_quickstep/com/android/launcher3/dagger/LauncherAppComponent.java
index 63d87e8..f4f5a08 100644
--- a/src_no_quickstep/com/android/launcher3/dagger/LauncherAppComponent.java
+++ b/src_no_quickstep/com/android/launcher3/dagger/LauncherAppComponent.java
@@ -22,7 +22,7 @@
  * Root component for Dagger injection for Launcher AOSP.
  */
 @LauncherAppSingleton
-@Component
+@Component(modules = LauncherAppModule.class)
 public interface LauncherAppComponent extends LauncherBaseAppComponent {
     /** Builder for aosp LauncherAppComponent. */
     @Component.Builder
diff --git a/src_no_quickstep/com/android/launcher3/dagger/LauncherAppModule.java b/src_no_quickstep/com/android/launcher3/dagger/LauncherAppModule.java
new file mode 100644
index 0000000..f7b8489
--- /dev/null
+++ b/src_no_quickstep/com/android/launcher3/dagger/LauncherAppModule.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.dagger;
+
+import dagger.Module;
+
+@Module
+public class LauncherAppModule { }
diff --git a/tests/multivalentTests/src/com/android/launcher3/AbstractDeviceProfileTest.kt b/tests/multivalentTests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
index c80093a..8598917 100644
--- a/tests/multivalentTests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
+++ b/tests/multivalentTests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
@@ -29,6 +29,7 @@
 import androidx.test.core.app.ApplicationProvider.getApplicationContext
 import androidx.test.platform.app.InstrumentationRegistry
 import com.android.launcher3.dagger.LauncherAppComponent
+import com.android.launcher3.dagger.LauncherAppModule
 import com.android.launcher3.dagger.LauncherAppSingleton
 import com.android.launcher3.testing.shared.ResourceUtils
 import com.android.launcher3.util.DisplayController
@@ -68,7 +69,7 @@
     protected lateinit var context: SandboxContext
     protected open val runningContext: Context = getApplicationContext()
     private val displayController: DisplayController = mock()
-    private val windowManagerProxy: WindowManagerProxy = mock()
+    private val windowManagerProxy: MyWmProxy = mock()
     private val launcherPrefs: LauncherPrefs = mock()
 
     @get:Rule val setFlagsRule = SetFlagsRule(SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT)
@@ -362,12 +363,17 @@
     }
 }
 
+class MyWmProxy : WindowManagerProxy()
+
 @LauncherAppSingleton
-@Component
+@Component(modules = [LauncherAppModule::class])
 interface AbsDPTestSandboxComponent : LauncherAppComponent {
+
+    override fun getWmProxy(): MyWmProxy
+
     @Component.Builder
     interface Builder : LauncherAppComponent.Builder {
-        @BindsInstance fun bindWMProxy(proxy: WindowManagerProxy): Builder
+        @BindsInstance fun bindWMProxy(proxy: MyWmProxy): Builder
 
         override fun build(): AbsDPTestSandboxComponent
     }
diff --git a/tests/multivalentTests/src/com/android/launcher3/AutoInstallsLayoutTest.kt b/tests/multivalentTests/src/com/android/launcher3/AutoInstallsLayoutTest.kt
index f73a9d3..fcbb94b 100644
--- a/tests/multivalentTests/src/com/android/launcher3/AutoInstallsLayoutTest.kt
+++ b/tests/multivalentTests/src/com/android/launcher3/AutoInstallsLayoutTest.kt
@@ -42,6 +42,7 @@
 import com.android.launcher3.LauncherSettings.Favorites.SPANY
 import com.android.launcher3.LauncherSettings.Favorites._ID
 import com.android.launcher3.dagger.LauncherAppComponent
+import com.android.launcher3.dagger.LauncherAppModule
 import com.android.launcher3.dagger.LauncherAppSingleton
 import com.android.launcher3.model.data.AppInfo
 import com.android.launcher3.pm.UserCache
@@ -66,7 +67,7 @@
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 import org.mockito.kotlin.doReturn
-import org.mockito.kotlin.spy
+import org.mockito.kotlin.mock
 import org.mockito.kotlin.whenever
 
 /** Tests for [AutoInstallsLayout] */
@@ -165,7 +166,9 @@
 
     @Test
     fun work_item_added_to_home() {
-        val apiWrapperMock = spy(ApiWrapper.INSTANCE[targetContext])
+        val original = ApiWrapper.INSTANCE[targetContext]
+        val apiWrapperMock =
+            mock<MyApiWrapper>(defaultAnswer = { it.method.invoke(original, *it.arguments) })
         targetContext.initDaggerComponent(
             DaggerAutoInstallsLayoutTestComponent.builder().bindApiWrapper(apiWrapperMock)
         )
@@ -221,12 +224,17 @@
     }
 }
 
+class MyApiWrapper : ApiWrapper(null) {}
+
 @LauncherAppSingleton
-@Component
+@Component(modules = [LauncherAppModule::class])
 interface AutoInstallsLayoutTestComponent : LauncherAppComponent {
+
+    override fun getApiWrapper(): MyApiWrapper
+
     @Component.Builder
     interface Builder : LauncherAppComponent.Builder {
-        @BindsInstance fun bindApiWrapper(wrapper: ApiWrapper): Builder
+        @BindsInstance fun bindApiWrapper(wrapper: MyApiWrapper): Builder
 
         override fun build(): AutoInstallsLayoutTestComponent
     }
diff --git a/tests/multivalentTests/src/com/android/launcher3/model/WorkspaceItemProcessorTest.kt b/tests/multivalentTests/src/com/android/launcher3/model/WorkspaceItemProcessorTest.kt
index 7099d38..d699eee 100644
--- a/tests/multivalentTests/src/com/android/launcher3/model/WorkspaceItemProcessorTest.kt
+++ b/tests/multivalentTests/src/com/android/launcher3/model/WorkspaceItemProcessorTest.kt
@@ -393,6 +393,39 @@
     }
 
     @Test
+    fun `When Pinned Deep Shortcut is not stored in ShortcutManager re-query by Shortcut ID`() {
+        // Given
+        mockCursor.itemType = ITEM_TYPE_DEEP_SHORTCUT
+        val si =
+            mock<ShortcutInfo>().apply {
+                whenever(id).thenReturn("")
+                whenever(`package`).thenReturn("")
+                whenever(activity).thenReturn(mock())
+                whenever(longLabel).thenReturn("")
+                whenever(isEnabled).thenReturn(true)
+                whenever(disabledMessage).thenReturn("")
+                whenever(disabledReason).thenReturn(0)
+                whenever(persons).thenReturn(EMPTY_PERSON_ARRAY)
+            }
+        whenever(mockLauncherApps.getShortcuts(any(), any())).thenReturn(listOf(si))
+        mKeyToPinnedShortcutsMap.clear()
+        mIconRequestInfos = mutableListOf()
+
+        // When
+        itemProcessorUnderTest =
+            createWorkspaceItemProcessorUnderTest(allDeepShortcuts = mAllDeepShortcuts)
+        itemProcessorUnderTest.processItem()
+
+        // Then
+        verify(mockLauncherApps).getShortcuts(any(), any())
+        assertWithMessage("item restoreFlag should be set to 0")
+            .that(mockCursor.restoreFlag)
+            .isEqualTo(0)
+        verify(mockCursor).markRestored()
+        verify(mockCursor).checkAndAddItem(any(), any(), anyOrNull())
+    }
+
+    @Test
     fun `When Pinned Deep Shortcut not found then mark deleted`() {
 
         // Given
diff --git a/tests/multivalentTests/src/com/android/launcher3/util/DisplayControllerTest.kt b/tests/multivalentTests/src/com/android/launcher3/util/DisplayControllerTest.kt
index 32df84c..d0cf610 100644
--- a/tests/multivalentTests/src/com/android/launcher3/util/DisplayControllerTest.kt
+++ b/tests/multivalentTests/src/com/android/launcher3/util/DisplayControllerTest.kt
@@ -30,6 +30,7 @@
 import com.android.launcher3.LauncherPrefs.Companion.TASKBAR_PINNING
 import com.android.launcher3.LauncherPrefs.Companion.TASKBAR_PINNING_IN_DESKTOP_MODE
 import com.android.launcher3.dagger.LauncherAppComponent
+import com.android.launcher3.dagger.LauncherAppModule
 import com.android.launcher3.dagger.LauncherAppSingleton
 import com.android.launcher3.util.DisplayController.CHANGE_DENSITY
 import com.android.launcher3.util.DisplayController.CHANGE_ROTATION
@@ -64,7 +65,7 @@
 class DisplayControllerTest {
 
     private val context = spy(SandboxModelContext())
-    private val windowManagerProxy: WindowManagerProxy = mock()
+    private val windowManagerProxy: MyWmProxy = mock()
     private val launcherPrefs: LauncherPrefs = mock()
     private lateinit var displayManager: DisplayManager
     private val display: Display = mock()
@@ -230,12 +231,17 @@
     }
 }
 
+class MyWmProxy : WindowManagerProxy()
+
 @LauncherAppSingleton
-@Component
+@Component(modules = [LauncherAppModule::class])
 interface DisplayControllerTestComponent : LauncherAppComponent {
+
+    override fun getWmProxy(): MyWmProxy
+
     @Component.Builder
     interface Builder : LauncherAppComponent.Builder {
-        @BindsInstance fun bindWMProxy(proxy: WindowManagerProxy): Builder
+        @BindsInstance fun bindWMProxy(proxy: MyWmProxy): Builder
 
         override fun build(): DisplayControllerTestComponent
     }
diff --git a/tests/src/com/android/launcher3/pm/InstallSessionHelperTest.kt b/tests/src/com/android/launcher3/pm/InstallSessionHelperTest.kt
index f381d4b..94b2c7e 100644
--- a/tests/src/com/android/launcher3/pm/InstallSessionHelperTest.kt
+++ b/tests/src/com/android/launcher3/pm/InstallSessionHelperTest.kt
@@ -104,7 +104,7 @@
             .thenReturn(listOf(expectedVerifiedSession))
         // When
         val actualSession =
-            installSessionHelper.getActiveSessionInfo(UserHandle(0), expectedAppPackage)
+            installSessionHelper.getActiveSessionInfo(myUserHandle(), expectedAppPackage)
         // Then
         assertThat(actualSession).isEqualTo(expectedVerifiedSession)
     }
diff --git a/tests/src/com/android/launcher3/popup/SystemShortcutTest.java b/tests/src/com/android/launcher3/popup/SystemShortcutTest.java
index ae54e95..075f667 100644
--- a/tests/src/com/android/launcher3/popup/SystemShortcutTest.java
+++ b/tests/src/com/android/launcher3/popup/SystemShortcutTest.java
@@ -62,15 +62,12 @@
 import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.R;
 import com.android.launcher3.allapps.PrivateProfileManager;
-import com.android.launcher3.dagger.LauncherAppComponent;
-import com.android.launcher3.dagger.LauncherAppSingleton;
 import com.android.launcher3.logging.StatsLogManager;
 import com.android.launcher3.logging.StatsLogManager.StatsLogger;
 import com.android.launcher3.model.data.AppInfo;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.pm.UserCache;
-import com.android.launcher3.util.ApiWrapper;
 import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.LauncherModelHelper.SandboxModelContext;
 import com.android.launcher3.util.LauncherMultivalentJUnit;
@@ -81,9 +78,6 @@
 import com.android.launcher3.widget.picker.model.WidgetPickerDataProvider;
 import com.android.launcher3.widget.picker.model.data.WidgetPickerData;
 
-import dagger.BindsInstance;
-import dagger.Component;
-
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -109,7 +103,6 @@
     private AppInfo mAppInfo;
 
     @Mock UserCache mUserCache;
-    @Mock ApiWrapper mApiWrapper;
     @Mock UserIconInfo mUserIconInfo;
     @Mock LauncherActivityInfo mLauncherActivityInfo;
     @Mock ApplicationInfo mApplicationInfo;
@@ -120,9 +113,6 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mSandboxContext.initDaggerComponent(
-                DaggerSystemShortcutTest_TestComponent.builder().bindApiWrapper(
-                        ApiWrapper.INSTANCE.get(mSandboxContext)));
         mSandboxContext.putObject(UserCache.INSTANCE, mUserCache);
         mTestContext = new TestSandboxModelContextWrapper(mSandboxContext) {
             @Override
@@ -412,16 +402,4 @@
         systemShortcut.onClick(mView);
         verify(mSandboxContext).startActivity(any());
     }
-
-    @LauncherAppSingleton
-    @Component
-    interface TestComponent extends LauncherAppComponent {
-        @Component.Builder
-        interface Builder extends LauncherAppComponent.Builder {
-            @BindsInstance Builder bindApiWrapper(ApiWrapper wrapper);
-
-            @Override
-            TestComponent build();
-        }
-    }
 }
diff --git a/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java b/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java
index e5c5c19..d49168f 100644
--- a/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java
+++ b/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java
@@ -1,11 +1,16 @@
 package com.android.launcher3.ui;
 
+import static com.android.launcher3.LauncherPrefs.FIXED_LANDSCAPE_MODE;
+
 import android.util.Log;
 import android.view.Surface;
 
+import com.android.launcher3.Flags;
 import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherPrefs;
 import com.android.launcher3.tapl.TestHelpers;
 import com.android.launcher3.util.rule.FailureWatcher;
+import com.android.launcher3.util.window.WindowManagerProxy;
 
 import org.junit.rules.TestRule;
 import org.junit.runner.Description;
@@ -67,9 +72,11 @@
                     Log.e(TAG, "Error", e);
                     throw e;
                 } finally {
+
                     mTest.mDevice.setOrientationNatural();
                     mTest.executeOnLauncher(launcher ->
                     {
+                        LauncherPrefs.get(launcher).put(FIXED_LANDSCAPE_MODE, false);
                         if (launcher != null) {
                             launcher.getRotationHelper().forceAllowRotationForTesting(false);
                         }
@@ -90,6 +97,13 @@
             }
 
             private void evaluateInLandscape() throws Throwable {
+                if (Flags.oneGridSpecs()
+                        && WindowManagerProxy.INSTANCE.get(mTest.mTargetContext)
+                        .isTaskbarDrawnInProcess()) {
+                    mTest.executeOnLauncher(launcher -> LauncherPrefs.get(launcher)
+                            .put(FIXED_LANDSCAPE_MODE, true)
+                    );
+                }
                 mTest.mDevice.setOrientationLeft();
                 mTest.mLauncher.setExpectedRotation(Surface.ROTATION_90);
                 AbstractLauncherUiTest.checkDetectedLeaks(mTest.mLauncher, true);