Merge "Rename notifyGestureStartedAsync to notifyGestureStarted" into udc-dev
diff --git a/quickstep/res/layout-land/keyboard_quick_switch_taskview.xml b/quickstep/res/layout-land/keyboard_quick_switch_taskview.xml
index ebcbdcd..04e87be 100644
--- a/quickstep/res/layout-land/keyboard_quick_switch_taskview.xml
+++ b/quickstep/res/layout-land/keyboard_quick_switch_taskview.xml
@@ -25,28 +25,40 @@
     android:clipToOutline="true"
     launcher:borderColor="?androidprv:attr/materialColorOutline">
 
-    <include
-        layout="@layout/keyboard_quick_switch_thumbnail"
-        android:id="@+id/thumbnail1"
-        android:layout_width="0dp"
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/content"
+        android:layout_width="match_parent"
         android:layout_height="match_parent"
 
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toStartOf="@id/thumbnail2"/>
+        app:layout_constraintEnd_toEndOf="parent">
 
-    <include
-        layout="@layout/keyboard_quick_switch_thumbnail"
-        android:id="@+id/thumbnail2"
-        android:layout_width="0dp"
-        android:layout_height="match_parent"
-        android:visibility="gone"
-        android:layout_marginStart="@dimen/keyboard_quick_switch_split_view_spacing"
+        <include
+            layout="@layout/keyboard_quick_switch_thumbnail"
+            android:id="@+id/thumbnail1"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
 
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintStart_toEndOf="@id/thumbnail1"
-        app:layout_constraintEnd_toEndOf="parent"/>
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toStartOf="@id/thumbnail2"/>
+
+        <include
+            layout="@layout/keyboard_quick_switch_thumbnail"
+            android:id="@+id/thumbnail2"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:visibility="gone"
+            android:layout_marginStart="@dimen/keyboard_quick_switch_split_view_spacing"
+
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toEndOf="@id/thumbnail1"
+            app:layout_constraintEnd_toEndOf="parent"/>
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
 
 </com.android.launcher3.taskbar.KeyboardQuickSwitchTaskView>
diff --git a/quickstep/res/layout/keyboard_quick_switch_overview.xml b/quickstep/res/layout/keyboard_quick_switch_overview.xml
index 8c97c68..062a9c9 100644
--- a/quickstep/res/layout/keyboard_quick_switch_overview.xml
+++ b/quickstep/res/layout/keyboard_quick_switch_overview.xml
@@ -20,35 +20,47 @@
     xmlns:launcher="http://schemas.android.com/apk/res-auto"
     android:layout_width="@dimen/keyboard_quick_switch_taskview_width"
     android:layout_height="@dimen/keyboard_quick_switch_taskview_height"
-    android:background="@drawable/keyboard_quick_switch_overview_button_background"
     android:clipToOutline="true"
     android:importantForAccessibility="yes"
     launcher:borderColor="?androidprv:attr/materialColorOutline">
 
-    <ImageView
-        android:id="@+id/icon"
-        android:layout_width="@dimen/keyboard_quick_switch_recents_icon_size"
-        android:layout_height="@dimen/keyboard_quick_switch_recents_icon_size"
-        android:layout_marginBottom="8dp"
-        android:src="@drawable/ic_empty_recents"
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/content"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@drawable/keyboard_quick_switch_overview_button_background"
 
-        app:tint="?androidprv:attr/materialColorOnSurface"
-        app:layout_constraintVertical_chainStyle="packed"
         app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toTopOf="@id/text"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"/>
-
-    <TextView
-        style="@style/KeyboardQuickSwitchOverview"
-        android:id="@+id/text"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:textAlignment="center"
-
-        app:layout_constraintTop_toBottomOf="@id/icon"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"/>
+        app:layout_constraintEnd_toEndOf="parent">
+
+        <ImageView
+            android:id="@+id/icon"
+            android:layout_width="@dimen/keyboard_quick_switch_recents_icon_size"
+            android:layout_height="@dimen/keyboard_quick_switch_recents_icon_size"
+            android:layout_marginBottom="8dp"
+            android:src="@drawable/ic_empty_recents"
+
+            app:tint="?androidprv:attr/materialColorOnSurface"
+            app:layout_constraintVertical_chainStyle="packed"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toTopOf="@id/text"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"/>
+
+        <TextView
+            style="@style/KeyboardQuickSwitchOverview"
+            android:id="@+id/text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textAlignment="center"
+
+            app:layout_constraintTop_toBottomOf="@id/icon"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"/>
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
 
 </com.android.launcher3.taskbar.KeyboardQuickSwitchTaskView>
diff --git a/quickstep/res/layout/keyboard_quick_switch_taskview.xml b/quickstep/res/layout/keyboard_quick_switch_taskview.xml
index 5e2d52a..691df6e 100644
--- a/quickstep/res/layout/keyboard_quick_switch_taskview.xml
+++ b/quickstep/res/layout/keyboard_quick_switch_taskview.xml
@@ -25,6 +25,16 @@
     android:clipToOutline="true"
     launcher:borderColor="?androidprv:attr/materialColorOutline">
 
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/content"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent">
+
         <include
             layout="@layout/keyboard_quick_switch_thumbnail"
             android:id="@+id/thumbnail1"
@@ -49,4 +59,6 @@
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintEnd_toEndOf="parent"/>
 
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
 </com.android.launcher3.taskbar.KeyboardQuickSwitchTaskView>
diff --git a/quickstep/res/layout/keyboard_quick_switch_view.xml b/quickstep/res/layout/keyboard_quick_switch_view.xml
index 64d3f67..58c0c40 100644
--- a/quickstep/res/layout/keyboard_quick_switch_view.xml
+++ b/quickstep/res/layout/keyboard_quick_switch_view.xml
@@ -18,7 +18,6 @@
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:paddingVertical="@dimen/keyboard_quick_switch_view_spacing"
     android:layout_marginTop="@dimen/keyboard_quick_switch_margin_top"
     android:layout_marginHorizontal="@dimen/keyboard_quick_switch_margin_ends"
     android:background="@drawable/keyboard_quick_switch_view_background"
@@ -44,7 +43,9 @@
         <androidx.constraintlayout.widget.ConstraintLayout
             android:id="@+id/content"
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content"/>
+            android:layout_height="wrap_content"
+            android:paddingVertical="@dimen/keyboard_quick_switch_view_spacing"
+            android:clipToPadding="false"/>
 
     </HorizontalScrollView>
 
diff --git a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
index 3510fbe..34316db 100644
--- a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
+++ b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
@@ -36,6 +36,7 @@
 import com.android.launcher3.allapps.FloatingHeaderRow;
 import com.android.launcher3.allapps.FloatingHeaderView;
 import com.android.launcher3.anim.AlphaUpdateListener;
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.keyboard.FocusIndicatorHelper;
 import com.android.launcher3.keyboard.FocusIndicatorHelper.SimpleFocusIndicatorHelper;
 import com.android.launcher3.model.data.ItemInfo;
@@ -105,12 +106,22 @@
                 mActivityContext.getAppsView().getAppsStore().unregisterIconContainer(this);
             }
         }
+
+        // Set the predicted row in All Apps' text line to 1.
+        if (FeatureFlags.ENABLE_TWOLINE_ALLAPPS.get()
+                || FeatureFlags.ENABLE_TWOLINE_DEVICESEARCH.get()) {
+            for (int i = 0; i < getChildCount(); i++) {
+                BubbleTextView icon = (BubbleTextView) getChildAt(i);
+                icon.setMaxLines(1);
+            }
+        }
     }
 
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(getExpectedHeight(),
                 MeasureSpec.EXACTLY));
+        updateVisibility();
     }
 
     @Override
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
index 867e168..d8458c9 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
@@ -166,5 +166,6 @@
         writer.println(prefix + "\tmInEarlyWakeUp=" + mInEarlyWakeUp);
         writer.println(prefix + "\tmIgnoreStateChangesDuringMultiWindowAnimation="
                 + mIgnoreStateChangesDuringMultiWindowAnimation);
+        writer.println(prefix + "\tmPauseBlurs=" + mPauseBlurs);
     }
 }
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java
index 84129fd..926ede1 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java
@@ -23,6 +23,7 @@
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.util.AttributeSet;
+import android.view.View;
 import android.widget.ImageView;
 
 import androidx.annotation.NonNull;
@@ -45,6 +46,7 @@
 
     @Nullable private ImageView mThumbnailView1;
     @Nullable private ImageView mThumbnailView2;
+    @Nullable private View mContent;
 
     public KeyboardQuickSwitchTaskView(@NonNull Context context) {
         this(context, null);
@@ -84,7 +86,20 @@
                                 .getColor(
                                         R.styleable.TaskView_borderColor,
                                         DEFAULT_BORDER_COLOR),
-                /* invalidateViewCallback= */ KeyboardQuickSwitchTaskView.this::invalidate);
+                /* invalidateViewCallback= */ KeyboardQuickSwitchTaskView.this::invalidate,
+                /* viewScaleTargetProvider= */ new BorderAnimator.ViewScaleTargetProvider() {
+                    @NonNull
+                    @Override
+                    public View getContainerView() {
+                        return KeyboardQuickSwitchTaskView.this;
+                    }
+
+                    @NonNull
+                    @Override
+                    public View getContentView() {
+                        return mContent;
+                    }
+                });
     }
 
     @Override
@@ -93,6 +108,7 @@
 
         mThumbnailView1 = findViewById(R.id.thumbnail1);
         mThumbnailView2 = findViewById(R.id.thumbnail2);
+        mContent = findViewById(R.id.content);
     }
 
     @NonNull
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index b2b0623..613e0f1 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -1179,6 +1179,11 @@
     }
 
     @Override
+    public void tryClearAccessibilityFocus(View view) {
+        view.clearAccessibilityFocus();
+    }
+
+    @Override
     protected void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
 
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java
index 683f4ea..395833f 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java
@@ -21,7 +21,6 @@
 import static android.view.MotionEvent.ACTION_UP;
 import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY;
 
-import static com.android.launcher3.MotionEventsUtils.isTrackpadMotionEvent;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SWIPE_DOWN_WORKSPACE_NOTISHADE_OPEN;
 
 import android.graphics.PointF;
@@ -106,8 +105,7 @@
             // Currently input dispatcher will not do touch transfer if there are more than
             // one touch pointer. Hence, even if slope passed, only set the slippery flag
             // when there is single touch event. (context: InputDispatcher.cpp line 1445)
-            if (dy > mTouchSlop && dy > Math.abs(dx) && (isTrackpadMotionEvent(ev)
-                    || ev.getPointerCount() == 1)) {
+            if (dy > mTouchSlop && dy > Math.abs(dx) && ev.getPointerCount() == 1) {
                 ev.setAction(ACTION_DOWN);
                 dispatchTouchEvent(ev);
                 setWindowSlippery(true);
@@ -161,8 +159,7 @@
         } else {
             // For NORMAL state, only listen if the event originated above the navbar height
             DeviceProfile dp = mLauncher.getDeviceProfile();
-            if (!isTrackpadMotionEvent(ev) && ev.getY() > (mLauncher.getDragLayer().getHeight()
-                    - dp.getInsets().bottom)) {
+            if (ev.getY() > (mLauncher.getDragLayer().getHeight() - dp.getInsets().bottom)) {
                 return false;
             }
         }
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index a470fd0..49c7d5b 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -105,6 +105,7 @@
 import com.android.launcher3.taskbar.TaskbarUIController;
 import com.android.launcher3.tracing.InputConsumerProto;
 import com.android.launcher3.tracing.SwipeHandlerProto;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
 import com.android.launcher3.util.ActivityLifecycleCallbacksAdapter;
 import com.android.launcher3.util.DisplayController;
 import com.android.launcher3.util.TraceHelper;
@@ -2168,7 +2169,7 @@
                 ActiveGestureLog.INSTANCE.addLog("Unexpected task appeared"
                         + " id=" + taskInfo.taskId
                         + " pkg=" + taskInfo.baseIntent.getComponent().getPackageName());
-                finishRecentsAnimationOnTasksAppeared();
+                finishRecentsAnimationOnTasksAppeared(null /* onFinishComplete */);
             } else if (handleTaskAppeared(appearedTaskTargets)) {
                 Optional<RemoteAnimationTarget> taskTargetOptional =
                         Arrays.stream(appearedTaskTargets)
@@ -2176,17 +2177,22 @@
                                         targetCompat.taskId == mGestureState.getLastStartedTaskId())
                                 .findFirst();
                 if (!taskTargetOptional.isPresent()) {
-                    finishRecentsAnimationOnTasksAppeared();
+                    finishRecentsAnimationOnTasksAppeared(null /* onFinishComplete */);
                     return;
                 }
                 RemoteAnimationTarget taskTarget = taskTargetOptional.get();
                 TaskView taskView = mRecentsView.getTaskViewByTaskId(taskTarget.taskId);
                 if (taskView == null || !taskView.getThumbnail().shouldShowSplashView()) {
-                    finishRecentsAnimationOnTasksAppeared();
+                    finishRecentsAnimationOnTasksAppeared(null /* onFinishComplete */);
                     return;
                 }
 
                 ViewGroup splashView = mActivity.getDragLayer();
+                final QuickstepLauncher quickstepLauncher = mActivity instanceof QuickstepLauncher
+                        ? (QuickstepLauncher) mActivity : null;
+                if (quickstepLauncher != null) {
+                    quickstepLauncher.getDepthController().pauseBlursOnWindows(true);
+                }
 
                 // When revealing the app with launcher splash screen, make the app visible
                 // and behind the splash view before the splash is animated away.
@@ -2194,7 +2200,7 @@
                         new SurfaceTransactionApplier(splashView);
                 SurfaceTransaction transaction = new SurfaceTransaction();
                 for (RemoteAnimationTarget target : appearedTaskTargets) {
-                    transaction.forSurface(target.leash).setAlpha(1).setLayer(-1);
+                    transaction.forSurface(target.leash).setAlpha(1).setLayer(-1).setShow();
                 }
                 surfaceApplier.scheduleApply(transaction);
 
@@ -2206,16 +2212,25 @@
                         new AnimatorListenerAdapter() {
                             @Override
                             public void onAnimationEnd(Animator animation) {
-                                finishRecentsAnimationOnTasksAppeared();
+                                // Hiding launcher which shows the app surface behind, then
+                                // finishing recents to the app. After transition finish, showing
+                                // the views on launcher again, so it can be visible when next
+                                // animation starts.
+                                splashView.setAlpha(0);
+                                if (quickstepLauncher != null) {
+                                    quickstepLauncher.getDepthController()
+                                            .pauseBlursOnWindows(false);
+                                }
+                                finishRecentsAnimationOnTasksAppeared(() -> splashView.setAlpha(1));
                             }
                         });
             }
         }
     }
 
-    private void finishRecentsAnimationOnTasksAppeared() {
+    private void finishRecentsAnimationOnTasksAppeared(Runnable onFinishComplete) {
         if (mRecentsAnimationController != null) {
-            mRecentsAnimationController.finish(false /* toRecents */, null /* onFinishComplete */);
+            mRecentsAnimationController.finish(false /* toRecents */, onFinishComplete);
         }
         ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimationOnTasksAppeared");
     }
diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java
index f0d0bdb..499a260 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -243,7 +243,17 @@
                     TOUCH_RESPONSE_INTERPOLATOR);
             out.setFloat(tvsLocal.recentsViewScroll, AnimatedFloat.VALUE, 0,
                     TOUCH_RESPONSE_INTERPOLATOR);
-
+            out.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationStart(Animator animation) {
+                    super.onAnimationStart(animation);
+                    final SurfaceTransaction showTransaction = new SurfaceTransaction();
+                    for (int i = targets.apps.length - 1; i >= 0; --i) {
+                        showTransaction.getTransaction().show(targets.apps[i].leash);
+                    }
+                    applier.scheduleApply(showTransaction);
+                }
+            });
             out.addOnFrameCallback(() -> {
                 for (RemoteTargetHandle handle : remoteTargetHandles) {
                     handle.getTaskViewSimulator().apply(handle.getTransformParams());
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index fdf0c6a..0531b47 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -871,7 +871,6 @@
             }
 
             if (ENABLE_TRACKPAD_GESTURE.get() && mGestureState.isTrackpadGesture()
-                    && mGestureState.getActivityInterface().isResumed()
                     && !previousGestureState.isRecentsAnimationRunning()) {
                 reasonString = newCompoundString(reasonPrefix)
                         .append(SUBSTRING_PREFIX)
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index 601533d..a8963f6 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -294,8 +294,14 @@
                 boolean haveNotPassedSlopOnContinuedGesture =
                         !mPassedSlopOnThisGesture && mPassedPilferInputSlop;
                 double degrees = Math.toDegrees(Math.atan(upDist / horizontalDist));
-                boolean isLikelyToStartNewTask = haveNotPassedSlopOnContinuedGesture
-                        || degrees <= OVERVIEW_MIN_DEGREES;
+
+                // Regarding degrees >= -OVERVIEW_MIN_DEGREES - Trackpad gestures can start anywhere
+                // on the screen, allowing downward swipes. We want to impose the same angle in that
+                // scenario.
+                boolean swipeWithinQuickSwitchRange = degrees <= OVERVIEW_MIN_DEGREES
+                        && (!mGestureState.isTrackpadGesture() || degrees >= -OVERVIEW_MIN_DEGREES);
+                boolean isLikelyToStartNewTask =
+                        haveNotPassedSlopOnContinuedGesture || swipeWithinQuickSwitchRange;
 
                 if (!mPassedPilferInputSlop) {
                     if (passedSlop) {
diff --git a/quickstep/src/com/android/quickstep/util/BaseDepthController.java b/quickstep/src/com/android/quickstep/util/BaseDepthController.java
index cecf58d..b5c582a 100644
--- a/quickstep/src/com/android/quickstep/util/BaseDepthController.java
+++ b/quickstep/src/com/android/quickstep/util/BaseDepthController.java
@@ -74,6 +74,10 @@
     // Hints that there is potentially content behind Launcher and that we shouldn't optimize by
     // marking the launcher surface as opaque.  Only used in certain Launcher states.
     private boolean mHasContentBehindLauncher;
+
+    /** Pause applying depth and blur, can be used when something behind the Launcher. */
+    protected boolean mPauseBlurs;
+
     /**
      * Last blur value, in pixels, that was applied.
      * For debugging purposes.
@@ -104,6 +108,13 @@
         mHasContentBehindLauncher = hasContentBehindLauncher;
     }
 
+    public void pauseBlursOnWindows(boolean pause) {
+        if (pause != mPauseBlurs) {
+            mPauseBlurs = pause;
+            applyDepthAndBlur();
+        }
+    }
+
     protected void applyDepthAndBlur() {
         float depth = mDepth;
         IBinder windowToken = mLauncher.getRootView().getWindowToken();
@@ -121,9 +132,9 @@
             return;
         }
         boolean hasOpaqueBg = mLauncher.getScrimView().isFullyOpaque();
-        boolean isSurfaceOpaque = !mHasContentBehindLauncher && hasOpaqueBg;
+        boolean isSurfaceOpaque = mPauseBlurs || (!mHasContentBehindLauncher && hasOpaqueBg);
 
-        mCurrentBlur = !mCrossWindowBlursEnabled || hasOpaqueBg
+        mCurrentBlur = !mCrossWindowBlursEnabled || hasOpaqueBg || mPauseBlurs
                 ? 0 : (int) (depth * mMaxBlurRadius);
         SurfaceControl.Transaction transaction = new SurfaceControl.Transaction()
                 .setBackgroundBlurRadius(mSurface, mCurrentBlur)
diff --git a/quickstep/src/com/android/quickstep/util/BorderAnimator.java b/quickstep/src/com/android/quickstep/util/BorderAnimator.java
index c30661c..c43fb27 100644
--- a/quickstep/src/com/android/quickstep/util/BorderAnimator.java
+++ b/quickstep/src/com/android/quickstep/util/BorderAnimator.java
@@ -16,11 +16,13 @@
 package com.android.quickstep.util;
 
 import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.annotation.ColorInt;
 import android.annotation.Nullable;
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.Rect;
+import android.view.View;
 import android.view.animation.Interpolator;
 
 import androidx.annotation.NonNull;
@@ -34,7 +36,9 @@
  * Utility class for drawing a rounded-rect border around a view.
  * <p>
  * To use this class:
- * 1. Create an instance in the target view.
+ * 1. Create an instance in the target view. NOTE: The border will animate outwards from the
+ *      provided border bounds. If the border will not be visible outside of those bounds, then a
+ *      {@link ViewScaleTargetProvider} must be provided in the constructor.
  * 2. Override the target view's {@link android.view.View#draw(Canvas)} method and call
  *      {@link BorderAnimator#drawBorder(Canvas)} after {@code super.draw(canvas)}.
  * 3. Call {@link BorderAnimator#buildAnimator(boolean)} and start the animation or call
@@ -55,6 +59,7 @@
     @Px private final int mBorderWidthPx;
     @Px private final int mBorderRadiusPx;
     @NonNull private final Runnable mInvalidateViewCallback;
+    @Nullable private final ViewScaleTargetProvider mViewScaleTargetProvider;
     private final long mAppearanceDurationMs;
     private final long mDisappearanceDurationMs;
     @NonNull private final Interpolator mInterpolator;
@@ -75,6 +80,22 @@
                 borderRadiusPx,
                 borderColor,
                 invalidateViewCallback,
+                /* viewScaleTargetProvider= */ null);
+    }
+
+    public BorderAnimator(
+            @NonNull BorderBoundsBuilder borderBoundsBuilder,
+            int borderWidthPx,
+            int borderRadiusPx,
+            @ColorInt int borderColor,
+            @NonNull Runnable invalidateViewCallback,
+            @Nullable ViewScaleTargetProvider viewScaleTargetProvider) {
+        this(borderBoundsBuilder,
+                borderWidthPx,
+                borderRadiusPx,
+                borderColor,
+                invalidateViewCallback,
+                viewScaleTargetProvider,
                 DEFAULT_APPEARANCE_ANIMATION_DURATION_MS,
                 DEFAULT_DISAPPEARANCE_ANIMATION_DURATION_MS,
                 DEFAULT_INTERPOLATOR);
@@ -86,6 +107,7 @@
             int borderRadiusPx,
             @ColorInt int borderColor,
             @NonNull Runnable invalidateViewCallback,
+            @Nullable ViewScaleTargetProvider viewScaleTargetProvider,
             long appearanceDurationMs,
             long disappearanceDurationMs,
             @NonNull Interpolator interpolator) {
@@ -93,6 +115,7 @@
         mBorderWidthPx = borderWidthPx;
         mBorderRadiusPx = borderRadiusPx;
         mInvalidateViewCallback = invalidateViewCallback;
+        mViewScaleTargetProvider = viewScaleTargetProvider;
         mAppearanceDurationMs = appearanceDurationMs;
         mDisappearanceDurationMs = disappearanceDurationMs;
         mInterpolator = interpolator;
@@ -106,8 +129,10 @@
         float interpolatedProgress = mInterpolator.getInterpolation(
                 mBorderAnimationProgress.value);
         float borderWidth = mBorderWidthPx * interpolatedProgress;
-        // Inset the border by half the width to create an inwards-growth animation
-        mAlignmentAdjustment = borderWidth / 2f;
+        // Outset the border by half the width to create an outwards-growth animation
+        mAlignmentAdjustment = (-borderWidth / 2f)
+                // Inset the border if we are scaling the container up
+                + (mViewScaleTargetProvider == null ? 0 : mBorderWidthPx);
 
         mBorderPaint.setAlpha(Math.round(255 * interpolatedProgress));
         mBorderPaint.setStrokeWidth(borderWidth);
@@ -121,13 +146,16 @@
      * calling super.
      */
     public void drawBorder(Canvas canvas) {
+        // Increase the radius if we are scaling the container up
+        float radiusAdjustment = mViewScaleTargetProvider == null
+                ? -mAlignmentAdjustment : mAlignmentAdjustment;
         canvas.drawRoundRect(
                 /* left= */ mBorderBounds.left + mAlignmentAdjustment,
                 /* top= */ mBorderBounds.top + mAlignmentAdjustment,
                 /* right= */ mBorderBounds.right - mAlignmentAdjustment,
                 /* bottom= */ mBorderBounds.bottom - mAlignmentAdjustment,
-                /* rx= */ mBorderRadiusPx - mAlignmentAdjustment,
-                /* ry= */ mBorderRadiusPx - mAlignmentAdjustment,
+                /* rx= */ mBorderRadiusPx + radiusAdjustment,
+                /* ry= */ mBorderRadiusPx + radiusAdjustment,
                 /* paint= */ mBorderPaint);
     }
 
@@ -141,22 +169,81 @@
         mRunningBorderAnimation.setDuration(
                 isAppearing ? mAppearanceDurationMs : mDisappearanceDurationMs);
 
+        mRunningBorderAnimation.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationStart(Animator animation) {
+                setViewScales();
+            }
+        });
         mRunningBorderAnimation.addListener(
-                AnimatorListeners.forEndCallback(() -> mRunningBorderAnimation = null));
+                AnimatorListeners.forEndCallback(() -> {
+                    mRunningBorderAnimation = null;
+                    if (isAppearing) {
+                        return;
+                    }
+                    resetViewScales();
+                }));
 
         return mRunningBorderAnimation;
     }
 
     /**
      * Immediately shows/hides the border without an animation.
-     *
+     * <p>
      * To animate the appearance/disappearance, see {@link BorderAnimator#buildAnimator(boolean)}
      */
     public void setBorderVisible(boolean visible) {
         if (mRunningBorderAnimation != null) {
             mRunningBorderAnimation.end();
         }
+        mBorderBoundsBuilder.updateBorderBounds(mBorderBounds);
+        if (visible) {
+            setViewScales();
+        }
         mBorderAnimationProgress.updateValue(visible ? 1f : 0f);
+        if (!visible) {
+            resetViewScales();
+        }
+    }
+
+    private void setViewScales() {
+        if (mViewScaleTargetProvider == null) {
+            return;
+        }
+        View container = mViewScaleTargetProvider.getContainerView();
+        float width = container.getWidth();
+        float height = container.getHeight();
+        // scale up just enough to make room for the border
+        float scaleX = 1f + ((2 * mBorderWidthPx) / width);
+        float scaleY = 1f + ((2 * mBorderWidthPx) / height);
+
+        container.setPivotX(width / 2);
+        container.setPivotY(height / 2);
+        container.setScaleX(scaleX);
+        container.setScaleY(scaleY);
+
+        View contentView = mViewScaleTargetProvider.getContentView();
+        contentView.setPivotX(contentView.getWidth() / 2f);
+        contentView.setPivotY(contentView.getHeight() / 2f);
+        contentView.setScaleX(1f / scaleX);
+        contentView.setScaleY(1f / scaleY);
+    }
+
+    private void resetViewScales() {
+        if (mViewScaleTargetProvider == null) {
+            return;
+        }
+        View container = mViewScaleTargetProvider.getContainerView();
+        container.setPivotX(container.getWidth());
+        container.setPivotY(container.getHeight());
+        container.setScaleX(1f);
+        container.setScaleY(1f);
+
+        View contentView = mViewScaleTargetProvider.getContentView();
+        contentView.setPivotX(contentView.getWidth() / 2f);
+        contentView.setPivotY(contentView.getHeight() / 2f);
+        contentView.setScaleX(1f);
+        contentView.setScaleY(1f);
     }
 
     /**
@@ -169,4 +256,25 @@
          */
         void updateBorderBounds(Rect rect);
     }
+
+    /**
+     * Provider for scaling target views for the beginning and end of this animation.
+     */
+    public interface ViewScaleTargetProvider {
+
+        /**
+         * Returns the content view's container. This view will be scaled up to make room for the
+         * border.
+         */
+        @NonNull
+        View getContainerView();
+
+        /**
+         * Returns the content view. This view will be scaled down reciprocally to the container's
+         * up-scaling to maintain its original size. This should be the view containing all of the
+         * content being surrounded by the border.
+         */
+        @NonNull
+        View getContentView();
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/util/SurfaceTransaction.java b/quickstep/src/com/android/quickstep/util/SurfaceTransaction.java
index 7ab285d..441f88d 100644
--- a/quickstep/src/com/android/quickstep/util/SurfaceTransaction.java
+++ b/quickstep/src/com/android/quickstep/util/SurfaceTransaction.java
@@ -106,6 +106,15 @@
             mTransaction.setShadowRadius(mSurface, radius);
             return this;
         }
+
+        /**
+         * Requests to show the given surface.
+         * @return this Builder
+         */
+        public SurfaceProperties setShow() {
+            mTransaction.show(mSurface);
+            return this;
+        }
     }
 
     /**
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index cf6ee2d..f0afa69 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -1192,6 +1192,17 @@
                         .setMatrix(matrix);
                 surfaceApplier.scheduleApply(transaction);
             });
+            appAnimator.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationStart(Animator animation) {
+                    super.onAnimationStart(animation);
+                    final SurfaceTransaction showTransaction = new SurfaceTransaction();
+                    for (int i = apps.length - 1; i >= 0; --i) {
+                        showTransaction.getTransaction().show(apps[i].leash);
+                    }
+                    surfaceApplier.scheduleApply(showTransaction);
+                }
+            });
             anim.play(appAnimator);
             anim.addListener(new AnimatorListenerAdapter() {
                 @Override
diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java
index 855983f..05a6452 100644
--- a/src/com/android/launcher3/BaseActivity.java
+++ b/src/com/android/launcher3/BaseActivity.java
@@ -29,6 +29,7 @@
 import android.content.res.Configuration;
 import android.os.Bundle;
 import android.util.Log;
+import android.view.View;
 import android.window.OnBackInvokedDispatcher;
 
 import androidx.annotation.IntDef;
@@ -362,6 +363,12 @@
         return (mForceInvisible & mask) != 0;
     }
 
+    /**
+     * Attempts to clear accessibility focus on {@param view}.
+     */
+    public void tryClearAccessibilityFocus(View view) {
+    }
+
     public interface MultiWindowModeChangedListener {
         void onMultiWindowModeChanged(boolean isInMultiWindowMode);
     }
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 961c254..450a9f0 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -398,6 +398,15 @@
                 || mDisplay == DISPLAY_TASKBAR;
     }
 
+    /**
+     *  Only if actual text can be displayed in two line, the {@code true} value will be effective.
+     */
+    protected boolean shouldUseTwoLine() {
+        return (FeatureFlags.ENABLE_TWOLINE_ALLAPPS.get() && mDisplay == DISPLAY_ALL_APPS)
+                || (FeatureFlags.ENABLE_TWOLINE_DEVICESEARCH.get()
+                && mDisplay == DISPLAY_SEARCH_RESULT);
+    }
+
     @UiThread
     @VisibleForTesting
     public void applyLabel(ItemInfoWithIcon info) {
@@ -667,10 +676,8 @@
             setPadding(getPaddingLeft(), (height - cellHeightPx) / 2, getPaddingRight(),
                     getPaddingBottom());
         }
-        // only apply two line for all_apps
-        if (((FeatureFlags.ENABLE_TWOLINE_ALLAPPS.get() && mDisplay == DISPLAY_ALL_APPS)
-                || (FeatureFlags.ENABLE_TWOLINE_DEVICESEARCH.get()
-                && mDisplay == DISPLAY_SEARCH_RESULT)) && (mLastOriginalText != null)) {
+        // Only apply two line for all_apps and device search only if necessary.
+        if (shouldUseTwoLine() && (mLastOriginalText != null)) {
             CharSequence modifiedString = modifyTitleToSupportMultiLine(
                     MeasureSpec.getSize(widthMeasureSpec) - getCompoundPaddingLeft()
                             - getCompoundPaddingRight(),
diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java
index e653283..fc7f614 100644
--- a/src/com/android/launcher3/ButtonDropTarget.java
+++ b/src/com/android/launcher3/ButtonDropTarget.java
@@ -18,8 +18,6 @@
 
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 
-import static com.android.launcher3.LauncherState.NORMAL;
-
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Rect;
@@ -34,12 +32,15 @@
 import android.widget.PopupWindow;
 import android.widget.TextView;
 
+import androidx.annotation.VisibleForTesting;
+
 import com.android.launcher3.anim.Interpolators;
 import com.android.launcher3.dragndrop.DragController;
 import com.android.launcher3.dragndrop.DragLayer;
 import com.android.launcher3.dragndrop.DragOptions;
 import com.android.launcher3.dragndrop.DragView;
 import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.views.ActivityContext;
 
 /**
  * Implements a DropTarget.
@@ -59,8 +60,8 @@
 
     private final Rect mTempRect = new Rect();
 
-    protected final Launcher mLauncher;
-
+    protected final ActivityContext mActivityContext;
+    protected final DropTargetHandler mDropTargetHandler;
     protected DropTargetBar mDropTargetBar;
 
     /** Whether this drop target is active for the current drag */
@@ -83,13 +84,17 @@
     private PopupWindow mToolTip;
     private int mToolTipLocation;
 
+    public ButtonDropTarget(Context context) {
+        this(context, null, 0);
+    }
     public ButtonDropTarget(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
 
     public ButtonDropTarget(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
-        mLauncher = Launcher.getLauncher(context);
+        mActivityContext = ActivityContext.lookupContext(context);
+        mDropTargetHandler = mActivityContext.getDropTargetHandler();
 
         Resources resources = getResources();
         mDragDistanceThreshold = resources.getDimensionPixelSize(R.dimen.drag_distanceThreshold);
@@ -210,7 +215,8 @@
     @Override
     public boolean isDropEnabled() {
         return mActive && (mAccessibleDrag ||
-                mLauncher.getDragController().getDistanceDragged() >= mDragDistanceThreshold);
+                mActivityContext.getDragController().getDistanceDragged()
+                        >= mDragDistanceThreshold);
     }
 
     @Override
@@ -229,7 +235,8 @@
             // FlingAnimation handles the animation and then calls completeDrop().
             return;
         }
-        final DragLayer dragLayer = mLauncher.getDragLayer();
+
+        final DragLayer dragLayer = mDropTargetHandler.getDragLayer();
         final DragView dragView = d.dragView;
         final Rect to = getIconRect(d);
         final float scale = (float) to.width() / dragView.getMeasuredWidth();
@@ -240,9 +247,10 @@
         Runnable onAnimationEndRunnable = () -> {
             completeDrop(d);
             mDropTargetBar.onDragEnd();
-            mLauncher.getStateManager().goToState(NORMAL);
+            mDropTargetHandler.onDropAnimationComplete();
         };
 
+
         dragLayer.animateView(d.dragView, to, scale, 0.1f, 0.1f,
                 DRAG_VIEW_DROP_DURATION,
                 Interpolators.DEACCEL_2, onAnimationEndRunnable,
@@ -261,10 +269,10 @@
     @Override
     public void getHitRectRelativeToDragLayer(android.graphics.Rect outRect) {
         super.getHitRect(outRect);
-        outRect.bottom += mLauncher.getDeviceProfile().dropTargetDragPaddingPx;
+        outRect.bottom += mActivityContext.getDeviceProfile().dropTargetDragPaddingPx;
 
         sTempCords[0] = sTempCords[1] = 0;
-        mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(this, sTempCords);
+        mActivityContext.getDragLayer().getDescendantCoordRelativeToSelf(this, sTempCords);
         outRect.offsetTo(sTempCords[0], sTempCords[1]);
     }
 
@@ -273,7 +281,7 @@
         int viewHeight = dragObject.dragView.getMeasuredHeight();
         int drawableWidth = mDrawable.getIntrinsicWidth();
         int drawableHeight = mDrawable.getIntrinsicHeight();
-        DragLayer dragLayer = mLauncher.getDragLayer();
+        DragLayer dragLayer = mDropTargetHandler.getDragLayer();
 
         // Find the rect to animate to (the view is center aligned)
         Rect to = new Rect();
@@ -314,7 +322,7 @@
 
     @Override
     public void onClick(View v) {
-        mLauncher.getAccessibilityDelegate().handleAccessibleDrop(this, null, null);
+        mDropTargetHandler.onClick(this);
     }
 
     public void setTextVisible(boolean isVisible) {
@@ -407,7 +415,8 @@
     /**
      * Returns if the text will be clipped vertically within the provided availableHeight.
      */
-    private boolean isTextClippedVertically(int availableHeight) {
+    @VisibleForTesting
+    protected boolean isTextClippedVertically(int availableHeight) {
         availableHeight -= getPaddingTop() + getPaddingBottom();
         if (availableHeight <= 0) {
             return true;
diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java
index 9ef9320..9a5627a 100644
--- a/src/com/android/launcher3/DeleteDropTarget.java
+++ b/src/com/android/launcher3/DeleteDropTarget.java
@@ -18,24 +18,19 @@
 
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROPPED_ON_CANCEL;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROPPED_ON_REMOVE;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_UNDO;
 
 import android.content.Context;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.View;
 
-import com.android.launcher3.LauncherSettings.Favorites;
 import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
 import com.android.launcher3.dragndrop.DragOptions;
 import com.android.launcher3.logging.StatsLogManager;
-import com.android.launcher3.model.ModelWriter;
 import com.android.launcher3.model.data.FolderInfo;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.util.IntSet;
-import com.android.launcher3.views.Snackbar;
 
 public class DeleteDropTarget extends ButtonDropTarget {
 
@@ -43,6 +38,10 @@
 
     private StatsLogManager.LauncherEvent mLauncherEvent;
 
+    public DeleteDropTarget(Context context) {
+        this(context, null, 0);
+    }
+
     public DeleteDropTarget(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
@@ -120,7 +119,7 @@
     @Override
     public void onDrop(DragObject d, DragOptions options) {
         if (canRemove(d.dragInfo)) {
-            mLauncher.getModelWriter().prepareToUndoDelete();
+            mDropTargetHandler.prepareToUndoDelete();
         }
         super.onDrop(d, options);
         mStatsLogManager.logger().withInstanceId(d.logInstanceId)
@@ -131,26 +130,8 @@
     public void completeDrop(DragObject d) {
         ItemInfo item = d.dragInfo;
         if (canRemove(item)) {
-            ItemInfo pageItem = item;
-            if (item.container <= 0) {
-                View v = mLauncher.getWorkspace().getHomescreenIconByItemId(item.container);
-                if (v != null) {
-                    pageItem = (ItemInfo) v.getTag();
-                }
-            }
-            IntSet pageIds = pageItem.container == Favorites.CONTAINER_DESKTOP
-                    ? IntSet.wrap(pageItem.screenId)
-                    : mLauncher.getWorkspace().getCurrentPageScreenIds();
-
             onAccessibilityDrop(null, item);
-            ModelWriter modelWriter = mLauncher.getModelWriter();
-            Runnable onUndoClicked = () -> {
-                mLauncher.setPagesToBindSynchronously(pageIds);
-                modelWriter.abortDelete();
-                mLauncher.getStatsLogManager().logger().log(LAUNCHER_UNDO);
-            };
-            Snackbar.show(mLauncher, R.string.item_removed, R.string.undo,
-                    modelWriter::commitDelete, onUndoClicked);
+            mDropTargetHandler.onDeleteComplete(item);
         }
     }
 
@@ -162,9 +143,7 @@
         // Remove the item from launcher and the db, we can ignore the containerInfo in this call
         // because we already remove the drag view from the folder (if the drag originated from
         // a folder) in Folder.beginDrag()
-        mLauncher.removeItem(view, item, true /* deleteFromDb */, "removed by accessibility drop");
-        mLauncher.getWorkspace().stripEmptyScreens();
-        mLauncher.getDragLayer()
-                .announceForAccessibility(getContext().getString(R.string.item_removed));
+        CharSequence announcement = getContext().getString(R.string.item_removed);
+        mDropTargetHandler.onAccessibilityDelete(view, item, announcement);
     }
 }
diff --git a/src/com/android/launcher3/DropTargetHandler.kt b/src/com/android/launcher3/DropTargetHandler.kt
new file mode 100644
index 0000000..277f8b3
--- /dev/null
+++ b/src/com/android/launcher3/DropTargetHandler.kt
@@ -0,0 +1,119 @@
+package com.android.launcher3
+
+import android.content.ComponentName
+import android.view.View
+import com.android.launcher3.DropTarget.DragObject
+import com.android.launcher3.SecondaryDropTarget.DeferredOnComplete
+import com.android.launcher3.dragndrop.DragLayer
+import com.android.launcher3.logging.StatsLogManager.LauncherEvent
+import com.android.launcher3.model.ModelWriter
+import com.android.launcher3.model.data.ItemInfo
+import com.android.launcher3.model.data.LauncherAppWidgetInfo
+import com.android.launcher3.util.IntSet
+import com.android.launcher3.util.PendingRequestArgs
+import com.android.launcher3.views.Snackbar
+
+/**
+ * Handler class for drop target actions that require modifying or interacting with launcher.
+ *
+ * This class is created by Launcher and provided the instance of launcher when created, which
+ * allows us to decouple drop target controllers from Launcher to enable easier testing.
+ */
+class DropTargetHandler(launcher: Launcher) {
+    val mLauncher: Launcher = launcher
+
+    val modelWriter: ModelWriter = mLauncher.modelWriter
+
+    fun onDropAnimationComplete() {
+        mLauncher.stateManager.goToState(LauncherState.NORMAL)
+    }
+
+    fun onSecondaryTargetCompleteDrop(target: ComponentName?, d: DragObject) {
+        when (val dragSource = d.dragSource) {
+            is DeferredOnComplete -> {
+                val deferred: DeferredOnComplete = dragSource
+                if (d.dragSource is SecondaryDropTarget.DeferredOnComplete) {
+                    target?.let {
+                        deferred.mPackageName = it.packageName
+                        mLauncher.addOnResumeCallback { deferred.onLauncherResume() }
+                    }
+                        ?: deferred.sendFailure()
+                }
+            }
+        }
+    }
+
+    fun reconfigureWidget(widgetId: Int, info: ItemInfo) {
+        mLauncher.setWaitingForResult(PendingRequestArgs.forWidgetInfo(widgetId, null, info))
+        mLauncher.appWidgetHolder.startConfigActivity(
+            mLauncher,
+            widgetId,
+            Launcher.REQUEST_RECONFIGURE_APPWIDGET
+        )
+    }
+
+    fun dismissPrediction(
+        announcement: CharSequence,
+        onActionClicked: Runnable,
+        onDismiss: Runnable?
+    ) {
+        mLauncher.dragLayer.announceForAccessibility(announcement)
+        Snackbar.show(mLauncher, R.string.item_removed, R.string.undo, onDismiss, onActionClicked)
+    }
+
+    fun getViewUnderDrag(info: ItemInfo): View? {
+        return if (
+            info is LauncherAppWidgetInfo &&
+                info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP &&
+                mLauncher.workspace.dragInfo != null
+        ) {
+            mLauncher.workspace.dragInfo.cell
+        } else null
+    }
+
+    fun prepareToUndoDelete() {
+        mLauncher.modelWriter.prepareToUndoDelete()
+    }
+
+    fun onDeleteComplete(item: ItemInfo) {
+        var pageItem: ItemInfo = item
+        if (item.container <= 0) {
+            val v = mLauncher.workspace.getHomescreenIconByItemId(item.container)
+            v?.let { pageItem = v.tag as ItemInfo }
+        }
+        val pageIds =
+            if (pageItem.container == LauncherSettings.Favorites.CONTAINER_DESKTOP)
+                IntSet.wrap(pageItem.screenId)
+            else mLauncher.workspace.currentPageScreenIds
+        val onUndoClicked = Runnable {
+            mLauncher.setPagesToBindSynchronously(pageIds)
+            modelWriter.abortDelete()
+            mLauncher.statsLogManager.logger().log(LauncherEvent.LAUNCHER_UNDO)
+        }
+
+        Snackbar.show(
+            mLauncher,
+            R.string.item_removed,
+            R.string.undo,
+            modelWriter::commitDelete,
+            onUndoClicked
+        )
+    }
+
+    fun onAccessibilityDelete(view: View?, item: ItemInfo, announcement: CharSequence) {
+        // Remove the item from launcher and the db, we can ignore the containerInfo in this call
+        // because we already remove the drag view from the folder (if the drag originated from
+        // a folder) in Folder.beginDrag()
+        mLauncher.removeItem(view, item, true /* deleteFromDb */, "removed by accessibility drop")
+        mLauncher.workspace.stripEmptyScreens()
+        mLauncher.dragLayer.announceForAccessibility(announcement)
+    }
+
+    fun getDragLayer(): DragLayer {
+        return mLauncher.dragLayer
+    }
+
+    fun onClick(buttonDropTarget: ButtonDropTarget) {
+        mLauncher.accessibilityDelegate.handleAccessibleDrop(buttonDropTarget, null, null)
+    }
+}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 59f56ff..b8bb305 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -1771,6 +1771,11 @@
     }
 
     @Override
+    public DropTargetHandler getDropTargetHandler() {
+        return new DropTargetHandler(this);
+    }
+
+    @Override
     public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
         if (requestCode != -1) {
             mPendingActivityRequestCode = requestCode;
diff --git a/src/com/android/launcher3/SecondaryDropTarget.java b/src/com/android/launcher3/SecondaryDropTarget.java
index 791cfff..2dd610cb 100644
--- a/src/com/android/launcher3/SecondaryDropTarget.java
+++ b/src/com/android/launcher3/SecondaryDropTarget.java
@@ -3,8 +3,6 @@
 import static android.appwidget.AppWidgetManager.INVALID_APPWIDGET_ID;
 import static android.appwidget.AppWidgetProviderInfo.WIDGET_FEATURE_RECONFIGURABLE;
 
-import static com.android.launcher3.Launcher.REQUEST_RECONFIGURE_APPWIDGET;
-import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP;
 import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.DISMISS_PREDICTION;
 import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.INVALID;
 import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.RECONFIGURE;
@@ -45,10 +43,7 @@
 import com.android.launcher3.logging.StatsLogManager.StatsLogger;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.ItemInfoWithIcon;
-import com.android.launcher3.model.data.LauncherAppWidgetInfo;
 import com.android.launcher3.util.PackageManagerHelper;
-import com.android.launcher3.util.PendingRequestArgs;
-import com.android.launcher3.views.Snackbar;
 import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
 
 import java.net.URISyntaxException;
@@ -204,7 +199,7 @@
             user = item.user;
         }
         if (intent != null) {
-            LauncherActivityInfo info = mLauncher.getSystemService(LauncherApps.class)
+            LauncherActivityInfo info = getContext().getSystemService(LauncherApps.class)
                     .resolveActivity(intent, user);
             if (info != null
                     && (info.getApplicationInfo().flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
@@ -239,23 +234,11 @@
     public void completeDrop(final DragObject d) {
         ComponentName target = performDropAction(getViewUnderDrag(d.dragInfo), d.dragInfo,
                 d.logInstanceId);
-        if (d.dragSource instanceof DeferredOnComplete) {
-            DeferredOnComplete deferred = (DeferredOnComplete) d.dragSource;
-            if (target != null) {
-                deferred.mPackageName = target.getPackageName();
-                mLauncher.addOnResumeCallback(deferred::onLauncherResume);
-            } else {
-                deferred.sendFailure();
-            }
-        }
+        mDropTargetHandler.onSecondaryTargetCompleteDrop(target, d);
     }
 
     private View getViewUnderDrag(ItemInfo info) {
-        if (info instanceof LauncherAppWidgetInfo && info.container == CONTAINER_DESKTOP &&
-                mLauncher.getWorkspace().getDragInfo() != null) {
-            return mLauncher.getWorkspace().getDragInfo().cell;
-        }
-        return null;
+        return mDropTargetHandler.getViewUnderDrag(info);
     }
 
     /**
@@ -286,18 +269,15 @@
         if (mCurrentAccessibilityAction == RECONFIGURE) {
             int widgetId = getReconfigurableWidgetId(view);
             if (widgetId != INVALID_APPWIDGET_ID) {
-                mLauncher.setWaitingForResult(
-                        PendingRequestArgs.forWidgetInfo(widgetId, null, info));
-                mLauncher.getAppWidgetHolder().startConfigActivity(mLauncher, widgetId,
-                        REQUEST_RECONFIGURE_APPWIDGET);
+                mDropTargetHandler.reconfigureWidget(widgetId, info);
             }
             return null;
         }
         if (mCurrentAccessibilityAction == DISMISS_PREDICTION) {
             if (FeatureFlags.ENABLE_DISMISS_PREDICTION_UNDO.get()) {
-                mLauncher.getDragLayer()
-                        .announceForAccessibility(getContext().getString(R.string.item_removed));
-                Snackbar.show(mLauncher, R.string.item_removed, R.string.undo, () -> { }, () -> {
+                CharSequence announcement = getContext().getString(R.string.item_removed);
+                mDropTargetHandler
+                        .dismissPrediction(announcement, () -> {}, () -> {
                     mStatsLogManager.logger()
                             .withInstanceId(instanceId)
                             .withItemInfo(info)
@@ -306,20 +286,23 @@
             }
             return null;
         }
-        // else: mCurrentAccessibilityAction == UNINSTALL
 
         ComponentName cn = getUninstallTarget(info);
         if (cn == null) {
             // System applications cannot be installed. For now, show a toast explaining that.
             // We may give them the option of disabling apps this way.
-            Toast.makeText(mLauncher, R.string.uninstall_system_app_text, Toast.LENGTH_SHORT).show();
+            Toast.makeText(
+                    getContext(),
+                    R.string.uninstall_system_app_text,
+                    Toast.LENGTH_SHORT
+                ).show();
             return null;
         }
         try {
-            Intent i = Intent.parseUri(mLauncher.getString(R.string.delete_package_intent), 0)
+            Intent i = Intent.parseUri(getContext().getString(R.string.delete_package_intent), 0)
                     .setData(Uri.fromParts("package", cn.getPackageName(), cn.getClassName()))
                     .putExtra(Intent.EXTRA_USER, info.user);
-            mLauncher.startActivity(i);
+            getContext().startActivity(i);
             FileLog.d(TAG, "start uninstall activity " + cn.getPackageName());
             return cn;
         } catch (URISyntaxException e) {
@@ -339,12 +322,12 @@
      * A wrapper around {@link DragSource} which delays the {@link #onDropCompleted} action until
      * {@link #onLauncherResume}
      */
-    private class DeferredOnComplete implements DragSource {
+    protected class DeferredOnComplete implements DragSource {
 
         private final DragSource mOriginal;
         private final Context mContext;
 
-        private String mPackageName;
+        protected String mPackageName;
         private DragObject mDragObject;
 
         public DeferredOnComplete(DragSource original, Context context) {
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index bedb41c..cdebe44 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -73,7 +73,157 @@
      * <p>
      * Declare a new ToggleableFlag below. Give it a unique key (e.g. "QSB_ON_FIRST_SCREEN"),
      * and set a default value for the flag. This will be the default value on Debug builds.
+     * <p>
+     * Please only add flags to your assigned block to prevent merge conflicts. If you do not have
+     * a block, please update the current empty block and add a new empty block below to prevent
+     * merge conflicts with the previous block.
      */
+    // TODO(Block 1): Clean up flags
+    public static final BooleanFlag ENABLE_ONE_SEARCH_MOTION = getReleaseFlag(270394223,
+            "ENABLE_ONE_SEARCH_MOTION", ENABLED, "Enables animations in OneSearch.");
+
+    public static final BooleanFlag ENABLE_SEARCH_RESULT_BACKGROUND_DRAWABLES = getReleaseFlag(
+            270394041, "ENABLE_SEARCH_RESULT_BACKGROUND_DRAWABLES", DISABLED,
+            "Enable option to replace decorator-based search result backgrounds with drawables");
+
+    public static final BooleanFlag ENABLE_SEARCH_RESULT_LAUNCH_TRANSITION = getReleaseFlag(
+            270394392, "ENABLE_SEARCH_RESULT_LAUNCH_TRANSITION", DISABLED,
+            "Enable option to launch search results using the new view container transitions");
+
+    // TODO(Block 2): Clean up flags
+    public static final BooleanFlag ENABLE_MULTI_DISPLAY_PARTIAL_DEPTH = getDebugFlag(270395073,
+            "ENABLE_MULTI_DISPLAY_PARTIAL_DEPTH", DISABLED,
+            "Allow bottom sheet depth to be smaller than 1 for multi-display devices.");
+
+    // TODO(Block 3): Clean up flags
+    public static final BooleanFlag ENABLE_DISMISS_PREDICTION_UNDO = getDebugFlag(270394476,
+            "ENABLE_DISMISS_PREDICTION_UNDO", DISABLED,
+            "Show an 'Undo' snackbar when users dismiss a predicted hotseat item");
+
+    public static final BooleanFlag CONTINUOUS_VIEW_TREE_CAPTURE = getDebugFlag(270395171,
+            "CONTINUOUS_VIEW_TREE_CAPTURE", ENABLED, "Capture View tree every frame");
+
+    public static final BooleanFlag ENABLE_WORKSPACE_LOADING_OPTIMIZATION = getDebugFlag(251502424,
+            "ENABLE_WORKSPACE_LOADING_OPTIMIZATION", DISABLED,
+            "load the current workspace screen visible to the user before the rest rather than "
+                    + "loading all of them at once.");
+
+    public static final BooleanFlag CHANGE_MODEL_DELEGATE_LOADING_ORDER = getDebugFlag(251502424,
+            "CHANGE_MODEL_DELEGATE_LOADING_ORDER", DISABLED,
+            "changes the timing of the loading and binding of delegate items during "
+                    + "data preparation for loading the home screen");
+
+    // TODO(Block 4): Cleanup flags
+    public static final BooleanFlag ENABLE_FLOATING_SEARCH_BAR =
+            getReleaseFlag(270390286, "ENABLE_FLOATING_SEARCH_BAR", DISABLED,
+                    "Keep All Apps search bar at the bottom (but above keyboard if open)");
+
+    public static final BooleanFlag ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS = getReleaseFlag(
+            270394468, "ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS", ENABLED,
+            "Enable option to show keyboard when going to all-apps");
+
+    // TODO(Block 5): Clean up flags
+    public static final BooleanFlag ENABLE_TWOLINE_DEVICESEARCH = getDebugFlag(201388851,
+            "ENABLE_TWOLINE_DEVICESEARCH", TEAMFOOD,
+            "Enable two line label for icons with labels on device search.");
+
+    public static final BooleanFlag ENABLE_ICON_IN_TEXT_HEADER = getDebugFlag(270395143,
+            "ENABLE_ICON_IN_TEXT_HEADER", DISABLED, "Show icon in textheader");
+
+    public static final BooleanFlag ENABLE_PREMIUM_HAPTICS_ALL_APPS = getDebugFlag(270396358,
+            "ENABLE_PREMIUM_HAPTICS_ALL_APPS", DISABLED,
+            "Enables haptics opening/closing All apps");
+
+    // TODO(Block 6): Clean up flags
+    public static final BooleanFlag WIDGETS_IN_LAUNCHER_PREVIEW = getDebugFlag(270393268,
+            "WIDGETS_IN_LAUNCHER_PREVIEW", ENABLED,
+            "Enables widgets in Launcher preview for the Wallpaper app.");
+
+    public static final BooleanFlag ENABLE_ALL_APPS_SEARCH_IN_TASKBAR = getDebugFlag(270393900,
+            "ENABLE_ALL_APPS_SEARCH_IN_TASKBAR", DISABLED,
+            "Enables Search box in Taskbar All Apps.");
+
+    public static final BooleanFlag SECONDARY_DRAG_N_DROP_TO_PIN = getDebugFlag(270395140,
+            "SECONDARY_DRAG_N_DROP_TO_PIN", DISABLED,
+            "Enable dragging and dropping to pin apps within secondary display");
+
+    // TODO(Block 7): Clean up flags
+    public static final BooleanFlag ENABLE_FORCED_MONO_ICON = getDebugFlag(270396209,
+            "ENABLE_FORCED_MONO_ICON", DISABLED,
+            "Enable the ability to generate monochromatic icons, if it is not provided by the app");
+
+    // TODO(Block 8): Clean up flags
+    public static final BooleanFlag ENABLE_MATERIAL_U_POPUP = getDebugFlag(270395516,
+            "ENABLE_MATERIAL_U_POPUP", ENABLED, "Switch popup UX to use material U");
+
+    // TODO(Block 9): Clean up flags
+    public static final BooleanFlag ENABLE_DOWNLOAD_APP_UX_V2 = getReleaseFlag(270395134,
+            "ENABLE_DOWNLOAD_APP_UX_V2", ENABLED, "Updates the download app UX"
+                    + " to have better visuals");
+
+    public static final BooleanFlag ENABLE_DOWNLOAD_APP_UX_V3 = getDebugFlag(270395186,
+            "ENABLE_DOWNLOAD_APP_UX_V3", ENABLED, "Updates the download app UX"
+                    + " to have better visuals, improve contrast, and color");
+
+    public static final BooleanFlag SHOW_DOT_PAGINATION = getDebugFlag(270395278,
+            "SHOW_DOT_PAGINATION", ENABLED, "Enable showing dot pagination in workspace");
+
+    public static final BooleanFlag LARGE_SCREEN_WIDGET_PICKER = getDebugFlag(270395809,
+            "LARGE_SCREEN_WIDGET_PICKER", ENABLED, "Enable new widget picker that takes "
+                    + "advantage of large screen format");
+
+    public static final BooleanFlag MULTI_SELECT_EDIT_MODE = getDebugFlag(270709220,
+            "MULTI_SELECT_EDIT_MODE", DISABLED, "Enable new multi-select edit mode "
+                    + "for home screen");
+
+    // TODO(Block 10): Clean up flags
+    public static final BooleanFlag ENABLE_BACK_SWIPE_LAUNCHER_ANIMATION = getDebugFlag(270614790,
+            "ENABLE_BACK_SWIPE_LAUNCHER_ANIMATION", DISABLED,
+            "Enables predictive back aniamtion from all apps and widgets to home");
+
+    // TODO(Block 11): Clean up flags
+    public static final BooleanFlag ENABLE_TWO_PANEL_HOME = getDebugFlag(270392643,
+            "ENABLE_TWO_PANEL_HOME", ENABLED,
+            "Uses two panel on home screen. Only applicable on large screen devices.");
+
+    public static final BooleanFlag FOLDABLE_WORKSPACE_REORDER = getDebugFlag(270395070,
+            "FOLDABLE_WORKSPACE_REORDER", DISABLED,
+            "In foldables, when reordering the icons and widgets, is now going to use both sides");
+
+    public static final BooleanFlag FOLDABLE_SINGLE_PAGE = getDebugFlag(270395274,
+            "FOLDABLE_SINGLE_PAGE", ENABLED, "Use a single page for the workspace");
+
+    // TODO(Block 12): Clean up flags
+    public static final BooleanFlag ENABLE_MULTI_INSTANCE = getDebugFlag(270396680,
+            "ENABLE_MULTI_INSTANCE", DISABLED,
+            "Enables creation and filtering of multiple task instances in overview");
+
+    // TODO(Block 13): Clean up flags
+    public static final BooleanFlag ENABLE_DEVICE_SEARCH_PERFORMANCE_LOGGING = getReleaseFlag(
+            270391397, "ENABLE_DEVICE_SEARCH_PERFORMANCE_LOGGING", DISABLED,
+            "Allows on device search in all apps logging");
+
+    // TODO(Block 14): Cleanup flags
+    public static final BooleanFlag ASSISTANT_GIVES_LAUNCHER_FOCUS = getDebugFlag(270391641,
+            "ASSISTANT_GIVES_LAUNCHER_FOCUS", DISABLED,
+            "Allow Launcher to handle nav bar gestures while Assistant is running over it");
+
+    public static final BooleanFlag NOTIFY_CRASHES = getDebugFlag(270393108, "NOTIFY_CRASHES",
+            DISABLED, "Sends a notification whenever launcher encounters an uncaught exception.");
+
+    public static final BooleanFlag FORCE_PERSISTENT_TASKBAR = getDebugFlag(270395077,
+            "FORCE_PERSISTENT_TASKBAR", DISABLED, "Forces taskbar to be persistent, even in gesture"
+                    + " nav mode and when transient taskbar is enabled.");
+
+    public static final BooleanFlag ENABLE_TRANSIENT_TASKBAR = getDebugFlag(270395798,
+            "ENABLE_TRANSIENT_TASKBAR", ENABLED, "Enables transient taskbar.");
+
+    // TODO(Block 15): Clean up flags
+    public static final BooleanFlag ENABLE_APP_CLONING_CHANGES_IN_LAUNCHER = getDebugFlag(266177840,
+            "ENABLE_APP_CLONING_CHANGES_IN_LAUNCHER", DISABLED,
+            "Removes clone apps from the work profile tab.");
+
+    // TODO(Block 16): Clean up flags
     // When enabled the promise icon is visible in all apps while installation an app.
     public static final BooleanFlag PROMISE_APPS_IN_ALL_APPS = getDebugFlag(270390012,
             "PROMISE_APPS_IN_ALL_APPS", DISABLED, "Add promise icon in all-apps");
@@ -85,10 +235,6 @@
     public static final BooleanFlag ENABLE_DEVICE_SEARCH = getReleaseFlag(270390907,
             "ENABLE_DEVICE_SEARCH", ENABLED, "Allows on device search in all apps");
 
-    public static final BooleanFlag ENABLE_FLOATING_SEARCH_BAR =
-            getReleaseFlag(270390286, "ENABLE_FLOATING_SEARCH_BAR", DISABLED,
-            "Keep All Apps search bar at the bottom (but above keyboard if open)");
-
     public static final BooleanFlag ENABLE_HIDE_HEADER = getReleaseFlag(270390930,
             "ENABLE_HIDE_HEADER", ENABLED, "Hide header on keyboard before typing in all apps");
 
@@ -102,14 +248,6 @@
     public static final BooleanFlag ENABLE_TWOLINE_ALLAPPS = getDebugFlag(270390937,
             "ENABLE_TWOLINE_ALLAPPS", DISABLED, "Enables two line label inside all apps.");
 
-    public static final BooleanFlag ENABLE_TWOLINE_DEVICESEARCH = getDebugFlag(201388851,
-            "ENABLE_TWOLINE_DEVICESEARCH", TEAMFOOD,
-            "Enable two line label for icons with labels on device search.");
-
-    public static final BooleanFlag ENABLE_DEVICE_SEARCH_PERFORMANCE_LOGGING = getReleaseFlag(
-            270391397, "ENABLE_DEVICE_SEARCH_PERFORMANCE_LOGGING", DISABLED,
-            "Allows on device search in all apps logging");
-
     public static final BooleanFlag IME_STICKY_SNACKBAR_EDU = getDebugFlag(270391693,
             "IME_STICKY_SNACKBAR_EDU", ENABLED, "Show sticky IME edu in AllApps");
 
@@ -125,10 +263,75 @@
             "INJECT_FALLBACK_APP_CORPUS_RESULTS", DISABLED,
             "Inject fallback app corpus result when AiAi fails to return it.");
 
-    public static final BooleanFlag ASSISTANT_GIVES_LAUNCHER_FOCUS = getDebugFlag(270391641,
-            "ASSISTANT_GIVES_LAUNCHER_FOCUS", DISABLED,
-            "Allow Launcher to handle nav bar gestures while Assistant is running over it");
+    // TODO(Block 17): Clean up flags
+    public static final BooleanFlag ENABLE_TASKBAR_PINNING = getDebugFlag(270396583,
+            "ENABLE_TASKBAR_PINNING", DISABLED,
+            "Enables taskbar pinning to allow user to switch between transient and persistent "
+                    + "taskbar flavors");
 
+    // TODO(Block 18): Clean up flags
+    public static final BooleanFlag ENABLE_LAUNCH_FROM_STAGED_APP = getDebugFlag(270395567,
+            "ENABLE_LAUNCH_FROM_STAGED_APP", ENABLED,
+            "Enable the ability to tap a staged app during split select to launch it in full "
+                    + "screen");
+
+    public static final BooleanFlag ENABLE_APP_PAIRS = getDebugFlag(274189428,
+            "ENABLE_APP_PAIRS", DISABLED,
+            "Enables the ability to create and save app pairs on the Home screen for easy"
+                    + " split screen launching.");
+
+    // TODO(Block 19): Clean up flags
+    public static final BooleanFlag SCROLL_TOP_TO_RESET = getReleaseFlag(270395177,
+            "SCROLL_TOP_TO_RESET", ENABLED,
+            "Bring up IME and focus on input when scroll to top if 'Always show keyboard'"
+                    + " is enabled or in prefix state");
+
+    public static final BooleanFlag ENABLE_SEARCH_UNINSTALLED_APPS = getReleaseFlag(270395269,
+            "ENABLE_SEARCH_UNINSTALLED_APPS", DISABLED, "Search uninstalled app results.");
+
+    // TODO(Block 20): Clean up flags
+    public static final BooleanFlag ENABLE_SCRIM_FOR_APP_LAUNCH = getDebugFlag(270393276,
+            "ENABLE_SCRIM_FOR_APP_LAUNCH", DISABLED, "Enables scrim during app launch animation.");
+
+    public static final BooleanFlag ENABLE_BACK_SWIPE_HOME_ANIMATION = getDebugFlag(270393426,
+            "ENABLE_BACK_SWIPE_HOME_ANIMATION", ENABLED,
+            "Enables home animation to icon when user swipes back.");
+
+    // TODO(Block 21): Clean up flags
+    public static final BooleanFlag ENABLE_APP_ICON_FOR_INLINE_SHORTCUTS = getDebugFlag(270395087,
+            "ENABLE_APP_ICON_IN_INLINE_SHORTCUTS", DISABLED, "Show app icon for inline shortcut");
+
+    // TODO(Block 22): Clean up flags
+    public static final BooleanFlag RECEIVE_UNFOLD_EVENTS_FROM_SYSUI = getDebugFlag(270397209,
+            "RECEIVE_UNFOLD_EVENTS_FROM_SYSUI", ENABLED,
+            "Enables receiving unfold animation events from sysui instead of calculating "
+                    + "them in launcher process using hinge sensor values.");
+
+    // TODO(Block 23): Clean up flags
+    public static final BooleanFlag ENABLE_GRID_ONLY_OVERVIEW = getDebugFlag(270397206,
+            "ENABLE_GRID_ONLY_OVERVIEW", DISABLED,
+            "Enable a grid-only overview without a focused task.");
+
+    // TODO(Block 24): Clean up flags
+    public static final BooleanFlag ENABLE_NEW_MIGRATION_LOGIC = getDebugFlag(270393455,
+            "ENABLE_NEW_MIGRATION_LOGIC", ENABLED,
+            "Enable the new grid migration logic, keeping pages when src < dest");
+
+    public static final BooleanFlag ENABLE_CACHED_WIDGET = getDebugFlag(270395008,
+            "ENABLE_CACHED_WIDGET", ENABLED,
+            "Show previously cached widgets as opposed to deferred widget where available");
+
+    // TODO(Block 25): Clean up flags
+    public static final BooleanFlag ENABLE_NEW_GESTURE_NAV_TUTORIAL = getDebugFlag(270396257,
+            "ENABLE_NEW_GESTURE_NAV_TUTORIAL", ENABLED,
+            "Enable the redesigned gesture navigation tutorial");
+
+    // TODO(Block 26): Clean up flags
+    public static final BooleanFlag ENABLE_WIDGET_HOST_IN_BACKGROUND = getDebugFlag(270394384,
+            "ENABLE_WIDGET_HOST_IN_BACKGROUND", ENABLED,
+            "Enable background widget updates listening for widget holder");
+
+    // TODO(Block 27): Clean up flags
     public static final BooleanFlag ENABLE_OVERLAY_CONNECTION_OPTIM = getDebugFlag(270392629,
             "ENABLE_OVERLAY_CONNECTION_OPTIM", DISABLED,
             "Enable optimizing overlay service connection");
@@ -148,219 +351,52 @@
             "SEPARATE_RECENTS_ACTIVITY", DISABLED,
             "Uses a separate recents activity instead of using the integrated recents+Launcher UI");
 
-    public static final BooleanFlag ENABLE_TWO_PANEL_HOME = getDebugFlag(270392643,
-            "ENABLE_TWO_PANEL_HOME", ENABLED,
-            "Uses two panel on home screen. Only applicable on large screen devices.");
-
-    public static final BooleanFlag ENABLE_SCRIM_FOR_APP_LAUNCH = getDebugFlag(270393276,
-            "ENABLE_SCRIM_FOR_APP_LAUNCH", DISABLED, "Enables scrim during app launch animation.");
-
     public static final BooleanFlag ENABLE_ENFORCED_ROUNDED_CORNERS = getReleaseFlag(270393258,
             "ENABLE_ENFORCED_ROUNDED_CORNERS", ENABLED,
             "Enforce rounded corners on all App Widgets");
 
-    public static final BooleanFlag NOTIFY_CRASHES = getDebugFlag(270393108, "NOTIFY_CRASHES",
-            DISABLED, "Sends a notification whenever launcher encounters an uncaught exception.");
-
     public static final BooleanFlag ENABLE_WALLPAPER_SCRIM = getDebugFlag(270393604,
             "ENABLE_WALLPAPER_SCRIM", DISABLED,
             "Enables scrim over wallpaper for text protection.");
 
-    public static final BooleanFlag WIDGETS_IN_LAUNCHER_PREVIEW = getDebugFlag(270393268,
-            "WIDGETS_IN_LAUNCHER_PREVIEW", ENABLED,
-            "Enables widgets in Launcher preview for the Wallpaper app.");
-
-    public static final BooleanFlag ENABLE_BACK_SWIPE_HOME_ANIMATION = getDebugFlag(270393426,
-            "ENABLE_BACK_SWIPE_HOME_ANIMATION", ENABLED,
-            "Enables home animation to icon when user swipes back.");
-
-    public static final BooleanFlag ENABLE_BACK_SWIPE_LAUNCHER_ANIMATION = getDebugFlag(270614790,
-            "ENABLE_BACK_SWIPE_LAUNCHER_ANIMATION", DISABLED,
-            "Enables predictive back aniamtion from all apps and widgets to home");
-
     public static final BooleanFlag ENABLE_ICON_LABEL_AUTO_SCALING = getDebugFlag(270393294,
             "ENABLE_ICON_LABEL_AUTO_SCALING", ENABLED,
             "Enables scaling/spacing for icon labels to make more characters visible");
 
-    public static final BooleanFlag ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT = getDebugFlag(270393897,
-            "ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT", DISABLED,
-            "Enables displaying the all apps button in the hotseat.");
+    public static final BooleanFlag USE_LOCAL_ICON_OVERRIDES = getDebugFlag(270394973,
+            "USE_LOCAL_ICON_OVERRIDES", ENABLED,
+            "Use inbuilt monochrome icons if app doesn't provide one");
 
-    public static final BooleanFlag ENABLE_ALL_APPS_SEARCH_IN_TASKBAR = getDebugFlag(270393900,
-            "ENABLE_ALL_APPS_SEARCH_IN_TASKBAR", DISABLED,
-            "Enables Search box in Taskbar All Apps.");
-
+    // TODO(Block 28): Clean up flags
     public static final BooleanFlag ENABLE_SPLIT_FROM_WORKSPACE = getDebugFlag(270393906,
             "ENABLE_SPLIT_FROM_WORKSPACE", ENABLED,
             "Enable initiating split screen from workspace.");
 
     public static final BooleanFlag ENABLE_SPLIT_FROM_FULLSCREEN_WITH_KEYBOARD_SHORTCUTS =
             getDebugFlag(270394122, "ENABLE_SPLIT_FROM_FULLSCREEN_SHORTCUT", DISABLED,
-            "Enable splitting from fullscreen app with keyboard shortcuts");
+                    "Enable splitting from fullscreen app with keyboard shortcuts");
 
     public static final BooleanFlag ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE = getDebugFlag(
             270393453, "ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE", DISABLED,
             "Enable initiating split screen from workspace to workspace.");
 
-    public static final BooleanFlag ENABLE_NEW_MIGRATION_LOGIC = getDebugFlag(270393455,
-            "ENABLE_NEW_MIGRATION_LOGIC", ENABLED,
-            "Enable the new grid migration logic, keeping pages when src < dest");
-
-    public static final BooleanFlag ENABLE_WIDGET_HOST_IN_BACKGROUND = getDebugFlag(270394384,
-            "ENABLE_WIDGET_HOST_IN_BACKGROUND", ENABLED,
-            "Enable background widget updates listening for widget holder");
-
-    public static final BooleanFlag ENABLE_ONE_SEARCH_MOTION = getReleaseFlag(270394223,
-            "ENABLE_ONE_SEARCH_MOTION", ENABLED, "Enables animations in OneSearch.");
-
-    public static final BooleanFlag ENABLE_SEARCH_RESULT_BACKGROUND_DRAWABLES = getReleaseFlag(
-            270394041, "ENABLE_SEARCH_RESULT_BACKGROUND_DRAWABLES", DISABLED,
-            "Enable option to replace decorator-based search result backgrounds with drawables");
-
-    public static final BooleanFlag ENABLE_SEARCH_RESULT_LAUNCH_TRANSITION = getReleaseFlag(
-            270394392, "ENABLE_SEARCH_RESULT_LAUNCH_TRANSITION", DISABLED,
-            "Enable option to launch search results using the new view container transitions");
-
-    public static final BooleanFlag ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS = getReleaseFlag(
-            270394468, "ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS", ENABLED,
-            "Enable option to show keyboard when going to all-apps");
-
-    public static final BooleanFlag USE_LOCAL_ICON_OVERRIDES = getDebugFlag(270394973,
-            "USE_LOCAL_ICON_OVERRIDES", ENABLED,
-            "Use inbuilt monochrome icons if app doesn't provide one");
-
-    public static final BooleanFlag ENABLE_DISMISS_PREDICTION_UNDO = getDebugFlag(270394476,
-            "ENABLE_DISMISS_PREDICTION_UNDO", DISABLED,
-            "Show an 'Undo' snackbar when users dismiss a predicted hotseat item");
-
-    public static final BooleanFlag ENABLE_CACHED_WIDGET = getDebugFlag(270395008,
-            "ENABLE_CACHED_WIDGET", ENABLED,
-            "Show previously cached widgets as opposed to deferred widget where available");
-
-    public static final BooleanFlag USE_SEARCH_REQUEST_TIMEOUT_OVERRIDES = getDebugFlag(270395010,
-            "USE_SEARCH_REQUEST_TIMEOUT_OVERRIDES", DISABLED,
-            "Use local overrides for search request timeout");
-
-    public static final BooleanFlag CONTINUOUS_VIEW_TREE_CAPTURE = getDebugFlag(270395171,
-            "CONTINUOUS_VIEW_TREE_CAPTURE", ENABLED, "Capture View tree every frame");
-
-    public static final BooleanFlag SECONDARY_DRAG_N_DROP_TO_PIN = getDebugFlag(270395140,
-            "SECONDARY_DRAG_N_DROP_TO_PIN", DISABLED,
-            "Enable dragging and dropping to pin apps within secondary display");
-
-    public static final BooleanFlag FOLDABLE_WORKSPACE_REORDER = getDebugFlag(270395070,
-            "FOLDABLE_WORKSPACE_REORDER", DISABLED,
-            "In foldables, when reordering the icons and widgets, is now going to use both sides");
-
-    public static final BooleanFlag ENABLE_MULTI_DISPLAY_PARTIAL_DEPTH = getDebugFlag(270395073,
-            "ENABLE_MULTI_DISPLAY_PARTIAL_DEPTH", DISABLED,
-            "Allow bottom sheet depth to be smaller than 1 for multi-display devices.");
-
-    public static final BooleanFlag SCROLL_TOP_TO_RESET = getReleaseFlag(270395177,
-            "SCROLL_TOP_TO_RESET", ENABLED,
-            "Bring up IME and focus on input when scroll to top if 'Always show keyboard'"
-                    + " is enabled or in prefix state");
-
-    public static final BooleanFlag ENABLE_MATERIAL_U_POPUP = getDebugFlag(270395516,
-            "ENABLE_MATERIAL_U_POPUP", ENABLED, "Switch popup UX to use material U");
-
-    public static final BooleanFlag ENABLE_SEARCH_UNINSTALLED_APPS = getReleaseFlag(270395269,
-            "ENABLE_SEARCH_UNINSTALLED_APPS", DISABLED, "Search uninstalled app results.");
-
-    public static final BooleanFlag ENABLE_DOWNLOAD_APP_UX_V2 = getReleaseFlag(270395134,
-            "ENABLE_DOWNLOAD_APP_UX_V2", ENABLED, "Updates the download app UX"
-                    + " to have better visuals");
-
-    public static final BooleanFlag ENABLE_DOWNLOAD_APP_UX_V3 = getDebugFlag(270395186,
-            "ENABLE_DOWNLOAD_APP_UX_V3", ENABLED, "Updates the download app UX"
-                    + " to have better visuals, improve contrast, and color");
-
-    public static final BooleanFlag FORCE_PERSISTENT_TASKBAR = getDebugFlag(270395077,
-            "FORCE_PERSISTENT_TASKBAR", DISABLED, "Forces taskbar to be persistent, even in gesture"
-                    + " nav mode and when transient taskbar is enabled.");
-
-    public static final BooleanFlag FOLDABLE_SINGLE_PAGE = getDebugFlag(270395274,
-            "FOLDABLE_SINGLE_PAGE", ENABLED, "Use a single page for the workspace");
-
-    public static final BooleanFlag ENABLE_TRANSIENT_TASKBAR = getDebugFlag(270395798,
-            "ENABLE_TRANSIENT_TASKBAR", ENABLED, "Enables transient taskbar.");
-
     public static final BooleanFlag ENABLE_TRACKPAD_GESTURE = getDebugFlag(271010401,
             "ENABLE_TRACKPAD_GESTURE", ENABLED, "Enables trackpad gesture.");
 
-    public static final BooleanFlag ENABLE_ICON_IN_TEXT_HEADER = getDebugFlag(270395143,
-            "ENABLE_ICON_IN_TEXT_HEADER", DISABLED, "Show icon in textheader");
-
-    public static final BooleanFlag ENABLE_APP_ICON_FOR_INLINE_SHORTCUTS = getDebugFlag(270395087,
-            "ENABLE_APP_ICON_IN_INLINE_SHORTCUTS", DISABLED, "Show app icon for inline shortcut");
-
-    public static final BooleanFlag SHOW_DOT_PAGINATION = getDebugFlag(270395278,
-            "SHOW_DOT_PAGINATION", ENABLED, "Enable showing dot pagination in workspace");
-
-    public static final BooleanFlag LARGE_SCREEN_WIDGET_PICKER = getDebugFlag(270395809,
-            "LARGE_SCREEN_WIDGET_PICKER", ENABLED, "Enable new widget picker that takes "
-                    + "advantage of large screen format");
-
-    public static final BooleanFlag MULTI_SELECT_EDIT_MODE = getDebugFlag(270709220,
-            "MULTI_SELECT_EDIT_MODE", DISABLED, "Enable new multi-select edit mode "
-                    + "for home screen");
-
-    public static final BooleanFlag ENABLE_NEW_GESTURE_NAV_TUTORIAL = getDebugFlag(270396257,
-            "ENABLE_NEW_GESTURE_NAV_TUTORIAL", ENABLED,
-            "Enable the redesigned gesture navigation tutorial");
-
-    public static final BooleanFlag ENABLE_LAUNCH_FROM_STAGED_APP = getDebugFlag(270395567,
-            "ENABLE_LAUNCH_FROM_STAGED_APP", ENABLED,
-            "Enable the ability to tap a staged app during split select to launch it in full "
-                    + "screen");
-
-    public static final BooleanFlag ENABLE_PREMIUM_HAPTICS_ALL_APPS = getDebugFlag(270396358,
-            "ENABLE_PREMIUM_HAPTICS_ALL_APPS", DISABLED,
-            "Enables haptics opening/closing All apps");
-
-    public static final BooleanFlag ENABLE_FORCED_MONO_ICON = getDebugFlag(270396209,
-            "ENABLE_FORCED_MONO_ICON", DISABLED,
-            "Enable the ability to generate monochromatic icons, if it is not provided by the app");
-
-    public static final BooleanFlag ENABLE_MULTI_INSTANCE = getDebugFlag(270396680,
-            "ENABLE_MULTI_INSTANCE", DISABLED,
-            "Enables creation and filtering of multiple task instances in overview");
-
-    public static final BooleanFlag ENABLE_TASKBAR_PINNING = getDebugFlag(270396583,
-            "ENABLE_TASKBAR_PINNING", DISABLED,
-            "Enables taskbar pinning to allow user to switch between transient and persistent "
-                    + "taskbar flavors");
-
-    public static final BooleanFlag ENABLE_WORKSPACE_LOADING_OPTIMIZATION = getDebugFlag(251502424,
-            "ENABLE_WORKSPACE_LOADING_OPTIMIZATION", DISABLED,
-            "load the current workspace screen visible to the user before the rest rather than "
-                    + "loading all of them at once.");
-
-    public static final BooleanFlag CHANGE_MODEL_DELEGATE_LOADING_ORDER = getDebugFlag(251502424,
-            "CHANGE_MODEL_DELEGATE_LOADING_ORDER", DISABLED,
-            "changes the timing of the loading and binding of delegate items during "
-                    + "data preparation for loading the home screen");
-
-    public static final BooleanFlag ENABLE_GRID_ONLY_OVERVIEW = getDebugFlag(270397206,
-            "ENABLE_GRID_ONLY_OVERVIEW", DISABLED,
-            "Enable a grid-only overview without a focused task.");
-
-    public static final BooleanFlag RECEIVE_UNFOLD_EVENTS_FROM_SYSUI = getDebugFlag(270397209,
-            "RECEIVE_UNFOLD_EVENTS_FROM_SYSUI", ENABLED,
-            "Enables receiving unfold animation events from sysui instead of calculating "
-                    + "them in launcher process using hinge sensor values.");
+    // TODO(Block 29): Clean up flags
+    public static final BooleanFlag ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT = getDebugFlag(270393897,
+            "ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT", DISABLED,
+            "Enables displaying the all apps button in the hotseat.");
 
     public static final BooleanFlag ENABLE_KEYBOARD_QUICK_SWITCH = getDebugFlag(270396844,
             "ENABLE_KEYBOARD_QUICK_SWITCH", ENABLED, "Enables keyboard quick switching");
 
-    public static final BooleanFlag ENABLE_APP_CLONING_CHANGES_IN_LAUNCHER = getDebugFlag(266177840,
-            "ENABLE_APP_CLONING_CHANGES_IN_LAUNCHER", DISABLED,
-            "Removes clone apps from the work profile tab.");
+    // TODO(Block 30): Clean up flags
+    public static final BooleanFlag USE_SEARCH_REQUEST_TIMEOUT_OVERRIDES = getDebugFlag(270395010,
+            "USE_SEARCH_REQUEST_TIMEOUT_OVERRIDES", DISABLED,
+            "Use local overrides for search request timeout");
 
-    public static final BooleanFlag ENABLE_APP_PAIRS = getDebugFlag(274189428,
-            "ENABLE_APP_PAIRS", DISABLED,
-            "Enables the ability to create and save app pairs on the Home screen for easy"
-                    + " split screen launching.");
+    // TODO(Block 31): Empty block
 
     public static final BooleanFlag ENABLE_CURSOR_HOVER_STATES = getDebugFlag(243191650,
             "ENABLE_CURSOR_HOVER_STATES", DISABLED,
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 9cca29a..bc492fd 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -241,6 +241,7 @@
                     deepShortcutCount,
                     popupDataProvider.getNotificationKeysForItem(item),
                     systemShortcuts);
+            launcher.tryClearAccessibilityFocus(icon);
         }
         launcher.refreshAndBindWidgetsForPackageUser(PackageUserKey.fromItemInfo(item));
         container.requestFocus();
diff --git a/src/com/android/launcher3/views/ActivityContext.java b/src/com/android/launcher3/views/ActivityContext.java
index 79d4df0..31b1934 100644
--- a/src/com/android/launcher3/views/ActivityContext.java
+++ b/src/com/android/launcher3/views/ActivityContext.java
@@ -53,6 +53,7 @@
 import com.android.launcher3.BubbleTextView;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
+import com.android.launcher3.DropTargetHandler;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
@@ -189,6 +190,13 @@
     }
 
     /**
+     * Handler for actions taken on drop targets that require launcher
+     */
+    default DropTargetHandler getDropTargetHandler() {
+        return null;
+    }
+
+    /**
      * Returns the FolderIcon with the given item id, if it exists.
      */
     default @Nullable FolderIcon findFolderIcon(final int folderIconId) {
diff --git a/tests/src/com/android/launcher3/DeleteDropTargetTest.kt b/tests/src/com/android/launcher3/DeleteDropTargetTest.kt
new file mode 100644
index 0000000..a588554
--- /dev/null
+++ b/tests/src/com/android/launcher3/DeleteDropTargetTest.kt
@@ -0,0 +1,42 @@
+package com.android.launcher3
+
+import android.content.Context
+import androidx.test.core.app.ApplicationProvider.getApplicationContext
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.launcher3.Utilities.*
+import com.android.launcher3.util.ActivityContextWrapper
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class DeleteDropTargetTest {
+
+    private var mContext: Context = ActivityContextWrapper(getApplicationContext())
+
+    // Use a non-abstract class implementation
+    private var buttonDropTarget: DeleteDropTarget = DeleteDropTarget(mContext)
+
+    @Before
+    fun setup() {
+        enableRunningInTestHarnessForTests()
+    }
+
+    // Needs mText, mTempRect, getPaddingTop, getPaddingBottom
+    // availableHeight as a parameter
+    @Test
+    fun isTextClippedVerticallyTest() {
+        buttonDropTarget.mText = "My Test"
+        // No space for text
+        assertThat(buttonDropTarget.isTextClippedVertically(30)).isTrue()
+
+        // Some space for text, and just enough that the text should not be clipped
+        assertThat(buttonDropTarget.isTextClippedVertically(50)).isFalse()
+
+        // A lot of space for text so the text should not be clipped
+        assertThat(buttonDropTarget.isTextClippedVertically(100)).isFalse()
+    }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index ba8f070..c4f8269 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -177,6 +177,7 @@
     private static final String OVERVIEW_RES_ID = "overview_panel";
     private static final String WIDGETS_RES_ID = "primary_widgets_list_view";
     private static final String CONTEXT_MENU_RES_ID = "popup_container";
+    private static final String OPEN_FOLDER_RES_ID = "folder_content";
     static final String TASKBAR_RES_ID = "taskbar_view";
     private static final String SPLIT_PLACEHOLDER_RES_ID = "split_placeholder";
     public static final int WAIT_TIME_MS = 30000;
@@ -560,6 +561,7 @@
 
     private String getVisibleStateMessage() {
         if (hasLauncherObject(CONTEXT_MENU_RES_ID)) return "Context Menu";
+        if (hasLauncherObject(OPEN_FOLDER_RES_ID)) return "Open Folder";
         if (hasLauncherObject(WIDGETS_RES_ID)) return "Widgets";
         if (hasSystemLauncherObject(OVERVIEW_RES_ID)) return "Overview";
         if (hasLauncherObject(WORKSPACE_RES_ID)) return "Workspace";