Merge "Remove unused @ScreenRecord" into main
diff --git a/quickstep/res/layout/taskbar_divider_popup_menu.xml b/quickstep/res/layout/taskbar_divider_popup_menu.xml
index 00e47c9..4348a47 100644
--- a/quickstep/res/layout/taskbar_divider_popup_menu.xml
+++ b/quickstep/res/layout/taskbar_divider_popup_menu.xml
@@ -19,7 +19,7 @@
     android:layout_width="@dimen/taskbar_pinning_popup_menu_width"
     android:layout_height="wrap_content"
     android:focusable="true"
-    android:background="@drawable/popup_background_material_u"
+    android:background="@drawable/popup_background"
     android:orientation="vertical">
 
     <LinearLayout
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index c6c4dde..f8ea932 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -159,6 +159,7 @@
 import com.android.wm.shell.startingsurface.IStartingWindowListener;
 
 import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -225,7 +226,8 @@
     private final float mClosingWindowTransY;
     private final float mMaxShadowRadius;
 
-    private final StartingWindowListener mStartingWindowListener = new StartingWindowListener();
+    private final StartingWindowListener mStartingWindowListener =
+            new StartingWindowListener(this);
 
     private DeviceProfile mDeviceProfile;
 
@@ -278,7 +280,6 @@
                 }
             };
 
-            mStartingWindowListener.setTransitionManager(this);
             SystemUiProxy.INSTANCE.get(mLauncher).setStartingWindowListener(
                     mStartingWindowListener);
         }
@@ -310,8 +311,8 @@
         mAppLaunchRunner = new AppLaunchAnimationRunner(v, onEndCallback);
         ItemInfo tag = (ItemInfo) v.getTag();
         if (tag != null && tag.shouldUseBackgroundAnimation()) {
-            ContainerAnimationRunner containerAnimationRunner =
-                    ContainerAnimationRunner.from(v, mStartingWindowListener, onEndCallback);
+            ContainerAnimationRunner containerAnimationRunner = ContainerAnimationRunner.from(
+                            v, mLauncher, mStartingWindowListener, onEndCallback);
             if (containerAnimationRunner != null) {
                 mAppLaunchRunner = containerAnimationRunner;
             }
@@ -1152,7 +1153,6 @@
     public void onActivityDestroyed() {
         unregisterRemoteAnimations();
         unregisterRemoteTransitions();
-        mStartingWindowListener.setTransitionManager(null);
         SystemUiProxy.INSTANCE.get(mLauncher).setStartingWindowListener(null);
     }
 
@@ -1775,8 +1775,8 @@
         }
 
         @Nullable
-        private static ContainerAnimationRunner from(
-                View v, StartingWindowListener startingWindowListener, RunnableList onEndCallback) {
+        private static ContainerAnimationRunner from(View v, Launcher launcher,
+                StartingWindowListener startingWindowListener, RunnableList onEndCallback) {
             View viewToUse = findViewWithBackground(v);
             if (viewToUse == null) {
                 viewToUse = v;
@@ -1801,8 +1801,13 @@
                         }
                     };
 
-            ActivityLaunchAnimator.Callback callback = task -> ColorUtils.setAlphaComponent(
-                    startingWindowListener.getBackgroundColor(), 255);
+            ActivityLaunchAnimator.Callback callback = task -> {
+                final int backgroundColor =
+                        startingWindowListener.mBackgroundColor == Color.TRANSPARENT
+                                ? launcher.getScrimView().getBackgroundColor()
+                                : startingWindowListener.mBackgroundColor;
+                return ColorUtils.setAlphaComponent(backgroundColor, 255);
+            };
 
             ActivityLaunchAnimator.Listener listener = new ActivityLaunchAnimator.Listener() {
                 @Override
@@ -1912,25 +1917,22 @@
         }
     }
 
-    private class StartingWindowListener extends IStartingWindowListener.Stub {
-        private QuickstepTransitionManager mTransitionManager;
+    private static class StartingWindowListener extends IStartingWindowListener.Stub {
+        private final WeakReference<QuickstepTransitionManager> mTransitionManagerRef;
         private int mBackgroundColor;
 
-        public void setTransitionManager(QuickstepTransitionManager transitionManager) {
-            mTransitionManager = transitionManager;
+        private StartingWindowListener(QuickstepTransitionManager transitionManager) {
+            mTransitionManagerRef = new WeakReference<>(transitionManager);
         }
 
         @Override
         public void onTaskLaunching(int taskId, int supportedType, int color) {
-            mTransitionManager.mTaskStartParams.put(taskId, Pair.create(supportedType, color));
+            QuickstepTransitionManager transitionManager = mTransitionManagerRef.get();
+            if (transitionManager != null) {
+                transitionManager.mTaskStartParams.put(taskId, Pair.create(supportedType, color));
+            }
             mBackgroundColor = color;
         }
-
-        public int getBackgroundColor() {
-            return mBackgroundColor == Color.TRANSPARENT
-                    ? mLauncher.getScrimView().getBackgroundColor()
-                    : mBackgroundColor;
-        }
     }
 
     /**
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
index 512b77a..a667dca 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
@@ -15,7 +15,6 @@
  */
 package com.android.launcher3.taskbar;
 
-import static com.android.launcher3.config.FeatureFlags.ENABLE_MATERIAL_U_POPUP;
 import static com.android.launcher3.util.SplitConfigurationOptions.getLogEventForPosition;
 
 import android.content.Intent;
@@ -163,19 +162,9 @@
                 .filter(Objects::nonNull)
                 .collect(Collectors.toList());
 
-        if (ENABLE_MATERIAL_U_POPUP.get()) {
-            container = (PopupContainerWithArrow) context.getLayoutInflater().inflate(
-                    R.layout.popup_container_material_u, context.getDragLayer(), false);
-            container.populateAndShowRowsMaterialU(icon, deepShortcutCount, systemShortcuts);
-        } else {
-            container = (PopupContainerWithArrow) context.getLayoutInflater().inflate(
+        container = (PopupContainerWithArrow) context.getLayoutInflater().inflate(
                     R.layout.popup_container, context.getDragLayer(), false);
-            container.populateAndShow(
-                    icon,
-                    deepShortcutCount,
-                    mPopupDataProvider.getNotificationKeysForItem(item),
-                    systemShortcuts);
-        }
+        container.populateAndShowRows(icon, deepShortcutCount, systemShortcuts);
 
         container.addOnAttachStateChangeListener(
                 new PopupLiveUpdateHandler<BaseTaskbarContext>(context, container) {
diff --git a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java
index f1660ee..857c831 100644
--- a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java
+++ b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java
@@ -58,6 +58,8 @@
 import com.android.quickstep.util.RectFSpringAnim;
 import com.android.systemui.shared.system.QuickStepContract;
 
+import java.lang.ref.WeakReference;
+
 /**
  * Controls the animation of swiping back and returning to launcher.
  *
@@ -105,7 +107,7 @@
     private boolean mAnimatorSetInProgress = false;
     private float mBackProgress = 0;
     private boolean mBackInProgress = false;
-    private IOnBackInvokedCallback mBackCallback;
+    private OnBackInvokedCallbackStub mBackCallback;
     private IRemoteAnimationFinishedCallback mAnimationFinishedCallback;
     private BackProgressAnimator mProgressAnimator = new BackProgressAnimator();
     private SurfaceControl mScrimLayer;
@@ -137,65 +139,104 @@
      * @param handler Handler to the thread to run the animations on.
      */
     public void registerBackCallbacks(Handler handler) {
-        mBackCallback = new IOnBackInvokedCallback.Stub() {
-            @Override
-            public void onBackCancelled() {
-                handler.post(() -> {
+        mBackCallback = new OnBackInvokedCallbackStub(handler, mProgressAnimator, this);
+        SystemUiProxy.INSTANCE.get(mLauncher).setBackToLauncherCallback(mBackCallback,
+                new RemoteAnimationRunnerStub(this));
+    }
+
+    private static class OnBackInvokedCallbackStub extends IOnBackInvokedCallback.Stub {
+        private Handler mHandler;
+        private BackProgressAnimator mProgressAnimator;
+        // LauncherBackAnimationController has strong reference to Launcher activity, the binder
+        // callback should not hold strong reference to it to avoid memory leak.
+        private WeakReference<LauncherBackAnimationController> mControllerRef;
+
+        private OnBackInvokedCallbackStub(
+                Handler handler,
+                BackProgressAnimator progressAnimator,
+                LauncherBackAnimationController controller) {
+            mHandler = handler;
+            mProgressAnimator = progressAnimator;
+            mControllerRef = new WeakReference<>(controller);
+        }
+
+        @Override
+        public void onBackCancelled() {
+            mHandler.post(() -> {
+                LauncherBackAnimationController controller = mControllerRef.get();
+                if (controller != null) {
                     mProgressAnimator.onBackCancelled(
-                            LauncherBackAnimationController.this::resetPositionAnimated);
-                });
-            }
-
-            @Override
-            public void onBackInvoked() {
-                handler.post(() -> {
-                    startTransition();
-                    mProgressAnimator.reset();
-                });
-            }
-
-            @Override
-            public void onBackProgressed(BackMotionEvent backEvent) {
-                handler.post(() -> {
-                    mProgressAnimator.onBackProgressed(backEvent);
-                });
-            }
-
-            @Override
-            public void onBackStarted(BackMotionEvent backEvent) {
-                handler.post(() -> {
-                    startBack(backEvent);
-                    mProgressAnimator.onBackStarted(backEvent, event -> {
-                        mBackProgress = event.getProgress();
-                        // TODO: Update once the interpolation curve spec is finalized.
-                        mBackProgress =
-                                1 - (1 - mBackProgress) * (1 - mBackProgress) * (1
-                                        - mBackProgress);
-                        updateBackProgress(mBackProgress, event);
-                    });
-                });
-            }
-        };
-
-        final IRemoteAnimationRunner runner = new IRemoteAnimationRunner.Stub() {
-            @Override
-            public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
-                    RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
-                    IRemoteAnimationFinishedCallback finishedCallback) {
-                for (final RemoteAnimationTarget target : apps) {
-                    if (MODE_CLOSING == target.mode) {
-                        mBackTarget = target;
-                        break;
-                    }
+                            controller::resetPositionAnimated);
                 }
-                mAnimationFinishedCallback = finishedCallback;
+            });
+        }
+
+        @Override
+        public void onBackInvoked() {
+            mHandler.post(() -> {
+                LauncherBackAnimationController controller = mControllerRef.get();
+                if (controller != null) {
+                    controller.startTransition();
+                }
+                mProgressAnimator.reset();
+            });
+        }
+
+        @Override
+        public void onBackProgressed(BackMotionEvent backMotionEvent) {
+            mHandler.post(() -> {
+                mProgressAnimator.onBackProgressed(backMotionEvent);
+            });
+        }
+
+        @Override
+        public void onBackStarted(BackMotionEvent backEvent) {
+            mHandler.post(() -> {
+                LauncherBackAnimationController controller = mControllerRef.get();
+                if (controller != null) {
+                    controller.startBack(backEvent);
+                    mProgressAnimator.onBackStarted(backEvent, event -> {
+                        float backProgress = event.getProgress();
+                        // TODO: Update once the interpolation curve spec is finalized.
+                        controller.mBackProgress =
+                                1 - (1 - backProgress) * (1 - backProgress) * (1
+                                        - backProgress);
+                        controller.updateBackProgress(controller.mBackProgress, event);
+                    });
+                }
+            });
+        }
+    }
+
+    private static class RemoteAnimationRunnerStub extends IRemoteAnimationRunner.Stub {
+
+        // LauncherBackAnimationController has strong reference to Launcher activity, the binder
+        // callback should not hold strong reference to it to avoid memory leak.
+        private WeakReference<LauncherBackAnimationController> mControllerRef;
+
+        private RemoteAnimationRunnerStub(LauncherBackAnimationController controller) {
+            mControllerRef = new WeakReference<>(controller);
+        }
+
+        @Override
+        public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
+                RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
+                IRemoteAnimationFinishedCallback finishedCallback) {
+            LauncherBackAnimationController controller = mControllerRef.get();
+            if (controller == null) {
+                return;
             }
+            for (final RemoteAnimationTarget target : apps) {
+                if (MODE_CLOSING == target.mode) {
+                    controller.mBackTarget = target;
+                    break;
+                }
+            }
+            controller.mAnimationFinishedCallback = finishedCallback;
+        }
 
-            @Override
-            public void onAnimationCancelled() {}
-        };
-
-        SystemUiProxy.INSTANCE.get(mLauncher).setBackToLauncherCallback(mBackCallback, runner);
+        @Override
+        public void onAnimationCancelled() {}
     }
 
     private void resetPositionAnimated() {
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index f9b003f..7cf47ce 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -3812,33 +3812,19 @@
                                         taskViewIdArray.removeValue(
                                                 finalNextFocusedTaskView.getTaskViewId());
                                     }
-                                    try {
-                                        if (snappedIndex < taskViewIdArray.size()) {
-                                            taskViewIdToSnapTo = taskViewIdArray.get(snappedIndex);
-                                        } else if (snappedIndex == taskViewIdArray.size()) {
-                                            // If the snapped task is the last item from the
-                                            // dismissed row,
-                                            // snap to the same column in the other grid row
-                                            IntArray inverseRowTaskViewIdArray =
-                                                    isSnappedTaskInTopRow ? getBottomRowIdArray()
-                                                            : getTopRowIdArray();
-                                            if (snappedIndex < inverseRowTaskViewIdArray.size()) {
-                                                taskViewIdToSnapTo = inverseRowTaskViewIdArray.get(
-                                                        snappedIndex);
-                                            }
+                                    if (snappedIndex < taskViewIdArray.size()) {
+                                        taskViewIdToSnapTo = taskViewIdArray.get(snappedIndex);
+                                    } else if (snappedIndex == taskViewIdArray.size()) {
+                                        // If the snapped task is the last item from the
+                                        // dismissed row,
+                                        // snap to the same column in the other grid row
+                                        IntArray inverseRowTaskViewIdArray =
+                                                isSnappedTaskInTopRow ? getBottomRowIdArray()
+                                                        : getTopRowIdArray();
+                                        if (snappedIndex < inverseRowTaskViewIdArray.size()) {
+                                            taskViewIdToSnapTo = inverseRowTaskViewIdArray.get(
+                                                    snappedIndex);
                                         }
-                                    } catch (ArrayIndexOutOfBoundsException e) {
-                                        throw new IllegalStateException(
-                                                "b/269956477 invalid snappedIndex"
-                                                        + "\nsnappedTaskViewId: "
-                                                        + snappedTaskViewId
-                                                        + "\nfocusedTaskViewId: "
-                                                        + mFocusedTaskViewId
-                                                        + "\ntopRowIdArray: "
-                                                        + getTopRowIdArray().toConcatString()
-                                                        + "\nbottomRowIdArray: "
-                                                        + getBottomRowIdArray().toConcatString(),
-                                                e);
                                     }
                                 }
                             }
diff --git a/res/drawable/popup_background_material_u.xml b/res/drawable/popup_background.xml
similarity index 100%
rename from res/drawable/popup_background_material_u.xml
rename to res/drawable/popup_background.xml
diff --git a/res/layout/deep_shortcut.xml b/res/layout/deep_shortcut.xml
index b175d17..6c1a2f7 100644
--- a/res/layout/deep_shortcut.xml
+++ b/res/layout/deep_shortcut.xml
@@ -13,10 +13,10 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
 <com.android.launcher3.shortcuts.DeepShortcutView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:launcher="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/deep_shortcut_material"
     android:layout_width="@dimen/bg_popup_item_width"
     android:layout_height="@dimen/bg_popup_item_height"
     android:elevation="@dimen/deep_shortcuts_elevation"
@@ -31,12 +31,11 @@
         android:textAlignment="viewStart"
         android:paddingStart="@dimen/deep_shortcuts_text_padding_start"
         android:paddingEnd="@dimen/popup_padding_end"
-        android:drawableEnd="@drawable/ic_drag_handle"
         android:drawablePadding="@dimen/deep_shortcut_drawable_padding"
         android:singleLine="true"
         android:ellipsize="end"
         android:textSize="14sp"
-        android:textColor="?android:attr/textColorPrimary"
+        android:textColor="?attr/popupTextColor"
         launcher:layoutHorizontal="true"
         launcher:iconDisplay="shortcut_popup"
         launcher:iconSizeOverride="@dimen/deep_shortcut_icon_size" />
@@ -48,5 +47,4 @@
         android:layout_marginStart="@dimen/popup_padding_start"
         android:layout_gravity="start|center_vertical"
         android:background="@drawable/ic_deepshortcut_placeholder"/>
-
-</com.android.launcher3.shortcuts.DeepShortcutView>
+</com.android.launcher3.shortcuts.DeepShortcutView>
\ No newline at end of file
diff --git a/res/layout/deep_shortcut_container.xml b/res/layout/deep_shortcut_container.xml
index b6c3f56..bf9124a 100644
--- a/res/layout/deep_shortcut_container.xml
+++ b/res/layout/deep_shortcut_container.xml
@@ -16,7 +16,7 @@
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/deep_shortcuts_container"
-    android:background="@drawable/popup_background_material_u"
+    android:background="@drawable/popup_background"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:tag="@string/popup_container_iterate_children"
diff --git a/res/layout/deep_shortcut_material_u.xml b/res/layout/deep_shortcut_material_u.xml
deleted file mode 100644
index 2e21ddb..0000000
--- a/res/layout/deep_shortcut_material_u.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2023 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<com.android.launcher3.shortcuts.DeepShortcutView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/deep_shortcut_material"
-    android:layout_width="@dimen/bg_popup_item_width"
-    android:layout_height="@dimen/bg_popup_item_height"
-    android:elevation="@dimen/deep_shortcuts_elevation"
-    android:background="@drawable/middle_item_primary"
-    android:theme="@style/PopupItem" >
-
-    <com.android.launcher3.shortcuts.DeepShortcutTextView
-        style="@style/BaseIcon"
-        android:id="@+id/bubble_text"
-        android:background="?android:attr/selectableItemBackground"
-        android:gravity="start|center_vertical"
-        android:textAlignment="viewStart"
-        android:paddingStart="@dimen/deep_shortcuts_text_padding_start"
-        android:paddingEnd="@dimen/popup_padding_end"
-        android:drawablePadding="@dimen/deep_shortcut_drawable_padding"
-        android:singleLine="true"
-        android:ellipsize="end"
-        android:textSize="14sp"
-        android:textColor="?attr/popupTextColor"
-        launcher:layoutHorizontal="true"
-        launcher:iconDisplay="shortcut_popup"
-        launcher:iconSizeOverride="@dimen/deep_shortcut_icon_size" />
-
-    <View
-        android:id="@+id/icon"
-        android:layout_width="@dimen/deep_shortcut_icon_size"
-        android:layout_height="@dimen/deep_shortcut_icon_size"
-        android:layout_marginStart="@dimen/popup_padding_start"
-        android:layout_gravity="start|center_vertical"
-        android:background="@drawable/ic_deepshortcut_placeholder"/>
-</com.android.launcher3.shortcuts.DeepShortcutView>
\ No newline at end of file
diff --git a/res/layout/popup_container.xml b/res/layout/popup_container.xml
index 9327287..bf7b126 100644
--- a/res/layout/popup_container.xml
+++ b/res/layout/popup_container.xml
@@ -13,27 +13,11 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
 <com.android.launcher3.popup.PopupContainerWithArrow
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/popup_container"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
-    android:clipToPadding="false"
     android:clipChildren="false"
-    android:orientation="vertical">
-
-    <LinearLayout
-        android:id="@+id/deep_shortcuts_container"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:tag="@string/popup_container_iterate_children"
-        android:elevation="@dimen/deep_shortcuts_elevation"
-        android:orientation="vertical"/>
-
-    <com.android.launcher3.notification.NotificationContainer
-        android:id="@+id/notification_container"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:visibility="gone"/>
-</com.android.launcher3.popup.PopupContainerWithArrow>
\ No newline at end of file
+    android:clipToPadding="false"
+    android:orientation="vertical"/>
\ No newline at end of file
diff --git a/res/layout/popup_container_material_u.xml b/res/layout/popup_container_material_u.xml
deleted file mode 100644
index d34c500..0000000
--- a/res/layout/popup_container_material_u.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2023 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<com.android.launcher3.popup.PopupContainerWithArrow
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/popup_container"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:clipChildren="false"
-    android:clipToPadding="false"
-    android:orientation="vertical"/>
\ No newline at end of file
diff --git a/res/layout/system_shortcut_icons_container.xml b/res/layout/system_shortcut_icons_container.xml
index fa92ba3..a5c0be3 100644
--- a/res/layout/system_shortcut_icons_container.xml
+++ b/res/layout/system_shortcut_icons_container.xml
@@ -17,9 +17,10 @@
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/system_shortcuts_container"
+    android:tag="@string/popup_container_iterate_children"
     android:layout_width="match_parent"
     android:layout_height="@dimen/system_shortcut_header_height"
     android:orientation="horizontal"
     android:gravity="end|center_vertical"
-    android:background="@drawable/single_item_primary"
+    android:background="@drawable/popup_background"
     android:elevation="@dimen/deep_shortcuts_elevation"/>
diff --git a/res/layout/system_shortcut_icons_container_material_u.xml b/res/layout/system_shortcut_icons_container_material_u.xml
deleted file mode 100644
index fbf18af..0000000
--- a/res/layout/system_shortcut_icons_container_material_u.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2023 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/system_shortcuts_container"
-    android:tag="@string/popup_container_iterate_children"
-    android:layout_width="match_parent"
-    android:layout_height="@dimen/system_shortcut_header_height"
-    android:orientation="horizontal"
-    android:gravity="end|center_vertical"
-    android:background="@drawable/popup_background_material_u"
-    android:elevation="@dimen/deep_shortcuts_elevation"/>
diff --git a/res/layout/system_shortcut_rows_container.xml b/res/layout/system_shortcut_rows_container.xml
index f992ef5..1940139 100644
--- a/res/layout/system_shortcut_rows_container.xml
+++ b/res/layout/system_shortcut_rows_container.xml
@@ -17,6 +17,7 @@
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/system_shortcuts_container"
+    android:background="@drawable/popup_background"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:tag="@string/popup_container_iterate_children"
diff --git a/res/layout/system_shortcut_rows_container_material_u.xml b/res/layout/system_shortcut_rows_container_material_u.xml
deleted file mode 100644
index 006e280..0000000
--- a/res/layout/system_shortcut_rows_container_material_u.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2023 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/system_shortcuts_container"
-    android:background="@drawable/popup_background_material_u"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:tag="@string/popup_container_iterate_children"
-    android:elevation="@dimen/deep_shortcuts_elevation"
-    android:orientation="vertical"/>
diff --git a/res/layout/widget_shortcut_container_material_u.xml b/res/layout/widget_shortcut_container_material_u.xml
index aab34e3..3a49c70 100644
--- a/res/layout/widget_shortcut_container_material_u.xml
+++ b/res/layout/widget_shortcut_container_material_u.xml
@@ -17,7 +17,7 @@
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/widget_shortcut_container"
-    android:background="@drawable/popup_background_material_u"
+    android:background="@drawable/popup_background"
     android:layout_width="match_parent"
     android:layout_height="@dimen/system_shortcut_header_height"
     android:orientation="horizontal"
diff --git a/src/com/android/launcher3/AppWidgetResizeFrame.java b/src/com/android/launcher3/AppWidgetResizeFrame.java
index 7131452..7b0d71b 100644
--- a/src/com/android/launcher3/AppWidgetResizeFrame.java
+++ b/src/com/android/launcher3/AppWidgetResizeFrame.java
@@ -11,6 +11,7 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
+import android.animation.LayoutTransition;
 import android.animation.ObjectAnimator;
 import android.animation.PropertyValuesHolder;
 import android.appwidget.AppWidgetProviderInfo;
@@ -26,12 +27,14 @@
 import android.widget.ImageButton;
 import android.widget.ImageView;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.Px;
 
 import com.android.launcher3.accessibility.DragViewStateAnnouncer;
 import com.android.launcher3.celllayout.CellLayoutLayoutParams;
 import com.android.launcher3.celllayout.CellPosMapper.CellPos;
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.dragndrop.DragLayer;
 import com.android.launcher3.keyboard.ViewGroupFocusHelper;
 import com.android.launcher3.logging.InstanceId;
@@ -47,15 +50,18 @@
 import java.util.List;
 
 public class AppWidgetResizeFrame extends AbstractFloatingView implements View.OnKeyListener {
-    private static final int SNAP_DURATION = 150;
+    private static final int SNAP_DURATION_MS = 150;
     private static final float DIMMED_HANDLE_ALPHA = 0f;
     private static final float RESIZE_THRESHOLD = 0.66f;
+    private static final int RESIZE_TRANSITION_DURATION_MS = 150;
 
     private static final String KEY_RECONFIGURABLE_WIDGET_EDUCATION_TIP_SEEN =
             "launcher.reconfigurable_widget_education_tip_seen";
     private static final Rect sTmpRect = new Rect();
     private static final Rect sTmpRect2 = new Rect();
 
+    private static final int[] sDragLayerLoc = new int[2];
+
     private static final int HANDLE_COUNT = 4;
     private static final int INDEX_LEFT = 0;
     private static final int INDEX_TOP = 1;
@@ -124,6 +130,12 @@
     private int mTopTouchRegionAdjustment = 0;
     private int mBottomTouchRegionAdjustment = 0;
 
+    private int[] mWidgetViewWindowPos;
+    private final Rect mWidgetViewOldRect = new Rect();
+    private final Rect mWidgetViewNewRect = new Rect();
+    private final @Nullable LauncherAppWidgetHostView.CellChildViewPreLayoutListener
+            mCellChildViewPreLayoutListener;
+
     private int mXDown, mYDown;
 
     public AppWidgetResizeFrame(Context context) {
@@ -140,6 +152,18 @@
         mLauncher = Launcher.getLauncher(context);
         mStateAnnouncer = DragViewStateAnnouncer.createFor(this);
 
+        mCellChildViewPreLayoutListener = FeatureFlags.ENABLE_WIDGET_TRANSITION_FOR_RESIZING.get()
+                ? (v, left, top, right, bottom) -> {
+                            if (mWidgetViewWindowPos == null) {
+                                mWidgetViewWindowPos = new int[2];
+                            }
+                            v.getLocationInWindow(mWidgetViewWindowPos);
+                            mWidgetViewOldRect.set(v.getLeft(), v.getTop(), v.getRight(),
+                                    v.getBottom());
+                            mWidgetViewNewRect.set(left, top, right, bottom);
+                        }
+                : null;
+
         mBackgroundPadding = getResources()
                 .getDimensionPixelSize(R.dimen.resize_frame_background_padding);
         mTouchTargetWidth = 2 * mBackgroundPadding;
@@ -260,6 +284,14 @@
             }
         }
 
+        if (FeatureFlags.ENABLE_WIDGET_TRANSITION_FOR_RESIZING.get()) {
+            mWidgetView.setCellChildViewPreLayoutListener(mCellChildViewPreLayoutListener);
+            mWidgetViewOldRect.set(mWidgetView.getLeft(), mWidgetView.getTop(),
+                    mWidgetView.getRight(),
+                    mWidgetView.getBottom());
+            mWidgetViewNewRect.set(mWidgetViewOldRect);
+        }
+
         CellLayoutLayoutParams lp = (CellLayoutLayoutParams) mWidgetView.getLayoutParams();
         ItemInfo widgetInfo = (ItemInfo) mWidgetView.getTag();
         CellPos presenterPos = mLauncher.getCellPosMapper().mapModelToPresenter(widgetInfo);
@@ -344,22 +376,6 @@
 
         resizeWidgetIfNeeded(false);
 
-        // When the widget resizes in multi-window mode, the translation value changes to maintain
-        // a center fit. These overrides ensure the resize frame always aligns with the widget view.
-        getSnappedRectRelativeToDragLayer(sTmpRect);
-        if (mLeftBorderActive) {
-            lp.width = sTmpRect.width() + sTmpRect.left - lp.x;
-        }
-        if (mTopBorderActive) {
-            lp.height = sTmpRect.height() + sTmpRect.top - lp.y;
-        }
-        if (mRightBorderActive) {
-            lp.x = sTmpRect.left;
-        }
-        if (mBottomBorderActive) {
-            lp.y = sTmpRect.top;
-        }
-
         // Handle invalid resize across CellLayouts in the two panel UI.
         if (mCellLayout.getParent() instanceof Workspace) {
             Workspace<?> workspace = (Workspace<?>) mCellLayout.getParent();
@@ -508,9 +524,13 @@
      * Returns the rect of this view when the frame is snapped around the widget, with the bounds
      * relative to the {@link DragLayer}.
      */
-    private void getSnappedRectRelativeToDragLayer(Rect out) {
+    private void getSnappedRectRelativeToDragLayer(@NonNull Rect out) {
         float scale = mWidgetView.getScaleToFit();
-        mDragLayer.getViewRectRelativeToSelf(mWidgetView, out);
+        if (FeatureFlags.ENABLE_WIDGET_TRANSITION_FOR_RESIZING.get()) {
+            getViewRectRelativeToDragLayer(out);
+        } else {
+            mDragLayer.getViewRectRelativeToSelf(mWidgetView, out);
+        }
 
         int width = 2 * mBackgroundPadding + Math.round(scale * out.width());
         int height = 2 * mBackgroundPadding + Math.round(scale * out.height());
@@ -523,7 +543,41 @@
         out.bottom = out.top + height;
     }
 
+    private void getViewRectRelativeToDragLayer(@NonNull Rect out) {
+        int[] afterPos = getViewPosRelativeToDragLayer();
+        out.set(afterPos[0], afterPos[1], afterPos[0] + mWidgetViewNewRect.width(),
+                afterPos[1] + mWidgetViewNewRect.height());
+    }
+
+    /** Returns the relative x and y values of the widget view after the layout transition */
+    private int[] getViewPosRelativeToDragLayer() {
+        mDragLayer.getLocationInWindow(sDragLayerLoc);
+        int x = sDragLayerLoc[0];
+        int y = sDragLayerLoc[1];
+
+        if (mWidgetViewWindowPos == null) {
+            mWidgetViewWindowPos = new int[2];
+            mWidgetView.getLocationInWindow(mWidgetViewWindowPos);
+        }
+
+        int leftOffset = mWidgetViewNewRect.left - mWidgetViewOldRect.left;
+        int topOffset = mWidgetViewNewRect.top - mWidgetViewOldRect.top;
+
+        return new int[] {mWidgetViewWindowPos[0] - x + leftOffset,
+                mWidgetViewWindowPos[1] - y + topOffset};
+    }
+
     private void snapToWidget(boolean animate) {
+        // The widget is guaranteed to be attached to the cell layout at this point, thus setting
+        // the transition here
+        if (FeatureFlags.ENABLE_WIDGET_TRANSITION_FOR_RESIZING.get()
+                && mWidgetView.getLayoutTransition() == null) {
+            final LayoutTransition transition = new LayoutTransition();
+            transition.setDuration(RESIZE_TRANSITION_DURATION_MS);
+            transition.enableTransitionType(LayoutTransition.CHANGING);
+            mWidgetView.setLayoutTransition(transition);
+        }
+
         getSnappedRectRelativeToDragLayer(sTmpRect);
         int newWidth = sTmpRect.width();
         int newHeight = sTmpRect.height();
@@ -585,7 +639,7 @@
                 updateInvalidResizeEffect(mCellLayout, pairedCellLayout, /* alpha= */ 1f,
                         /* springLoadedProgress= */ 0f, /* animatorSet= */ set);
             }
-            set.setDuration(SNAP_DURATION);
+            set.setDuration(SNAP_DURATION_MS);
             set.start();
         }
 
@@ -665,6 +719,10 @@
 
     @Override
     protected void handleClose(boolean animate) {
+        if (FeatureFlags.ENABLE_WIDGET_TRANSITION_FOR_RESIZING.get()) {
+            mWidgetView.clearCellChildViewPreLayoutListener();
+            mWidgetView.setLayoutTransition(null);
+        }
         mDragLayer.removeView(this);
     }
 
diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
index f0fea61..5e7f21b 100644
--- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java
+++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
@@ -38,6 +38,7 @@
 import com.android.launcher3.folder.FolderIcon;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.views.ActivityContext;
+import com.android.launcher3.widget.LauncherAppWidgetHostView;
 import com.android.launcher3.widget.NavigableAppWidgetHostView;
 
 public class ShortcutAndWidgetContainer extends ViewGroup implements FolderIcon.FolderIconParent {
@@ -217,6 +218,16 @@
 
         int childLeft = lp.x;
         int childTop = lp.y;
+
+        // We want to get the layout position of the widget, but layout() is a final function in
+        // ViewGroup which makes it impossible to be overridden. Overriding onLayout() will have no
+        // effect since it will not be called when the transition is enabled. The only possible
+        // solution here seems to be sending the positions when CellLayout is laying out the views
+        if (child instanceof LauncherAppWidgetHostView widgetView
+                && widgetView.getCellChildViewPreLayoutListener() != null) {
+            widgetView.getCellChildViewPreLayoutListener().notifyBoundChangeOnPreLayout(child,
+                    childLeft, childTop, childLeft + lp.width, childTop + lp.height);
+        }
         child.layout(childLeft, childTop, childLeft + lp.width, childTop + lp.height);
 
         if (lp.dropped) {
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 21520bf..813713d 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -154,8 +154,6 @@
             "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,
diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java
index e0f245f..6b08153 100644
--- a/src/com/android/launcher3/popup/ArrowPopup.java
+++ b/src/com/android/launcher3/popup/ArrowPopup.java
@@ -18,12 +18,9 @@
 
 import static androidx.core.content.ContextCompat.getColorStateList;
 
-import static com.android.app.animation.Interpolators.ACCELERATED_EASE;
-import static com.android.app.animation.Interpolators.DECELERATED_EASE;
 import static com.android.app.animation.Interpolators.EMPHASIZED_ACCELERATE;
 import static com.android.app.animation.Interpolators.EMPHASIZED_DECELERATE;
 import static com.android.app.animation.Interpolators.LINEAR;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_MATERIAL_U_POPUP;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -170,7 +167,7 @@
 
         mIterateChildrenTag = getContext().getString(R.string.popup_container_iterate_children);
 
-        if (!ENABLE_MATERIAL_U_POPUP.get() && mActivityContext.canUseMultipleShadesForPopup()) {
+        if (mActivityContext.canUseMultipleShadesForPopup()) {
             mColorIds = new int[]{R.color.popup_shade_first, R.color.popup_shade_second,
                     R.color.popup_shade_third};
         } else {
@@ -241,7 +238,6 @@
             }
         }
 
-        int numVisibleChild = 0;
         int numVisibleShortcut = 0;
         View lastView = null;
         AnimatorSet colorAnimator = new AnimatorSet();
@@ -256,26 +252,13 @@
                 MarginLayoutParams mlp = (MarginLayoutParams) lastView.getLayoutParams();
                 mlp.bottomMargin = 0;
 
-                if (colors != null) {
-                    if (!ENABLE_MATERIAL_U_POPUP.get()) {
-                        backgroundColor = colors[numVisibleChild % colors.length];
-                    }
-
-                    if (ENABLE_MATERIAL_U_POPUP.get() && isShortcutContainer(view)) {
-                        setChildColor(view, colors[0], colorAnimator);
-                        mArrowColor = colors[0];
-                    }
-                }
-
-                // Arrow color matches the first child or the last child.
-                if (!ENABLE_MATERIAL_U_POPUP.get()
-                        && (mIsAboveIcon || (numVisibleChild == 0 && viewGroup == this))) {
-                    mArrowColor = backgroundColor;
+                if (colors != null && isShortcutContainer(view)) {
+                    setChildColor(view, colors[0], colorAnimator);
+                    mArrowColor = colors[0];
                 }
 
                 if (view instanceof ViewGroup && isShortcutContainer(view)) {
                     assignMarginsAndBackgrounds((ViewGroup) view, backgroundColor);
-                    numVisibleChild++;
                     continue;
                 }
 
@@ -295,7 +278,6 @@
                 }
 
                 setChildColor(view, backgroundColor, colorAnimator);
-                numVisibleChild++;
             }
         }
 
@@ -573,23 +555,14 @@
 
     protected void animateOpen() {
         setVisibility(View.VISIBLE);
-        mOpenCloseAnimator = ENABLE_MATERIAL_U_POPUP.get()
-                ? getMaterialUOpenCloseAnimator(
+        mOpenCloseAnimator = getOpenCloseAnimator(
                         true,
                         OPEN_DURATION_U,
                         OPEN_FADE_START_DELAY_U,
                         OPEN_FADE_DURATION_U,
                         OPEN_CHILD_FADE_START_DELAY_U,
                         OPEN_CHILD_FADE_DURATION_U,
-                        EMPHASIZED_DECELERATE)
-                : getOpenCloseAnimator(
-                        true,
-                        mOpenDuration,
-                        mOpenFadeStartDelay,
-                        mOpenFadeDuration,
-                        mOpenChildFadeStartDelay,
-                        mOpenChildFadeDuration,
-                        DECELERATED_EASE);
+                        EMPHASIZED_DECELERATE);
 
         onCreateOpenAnimation(mOpenCloseAnimator);
         mOpenCloseAnimator.addListener(new AnimatorListenerAdapter() {
@@ -603,44 +576,6 @@
         mOpenCloseAnimator.start();
     }
 
-    private AnimatorSet getOpenCloseAnimator(boolean isOpening, int totalDuration,
-            int fadeStartDelay, int fadeDuration, int childFadeStartDelay,
-            int childFadeDuration, Interpolator interpolator) {
-        final AnimatorSet animatorSet = new AnimatorSet();
-        float[] alphaValues = isOpening ? new float[] {0, 1} : new float[] {1, 0};
-        float[] scaleValues = isOpening ? new float[] {0.5f, 1} : new float[] {1, 0.5f};
-
-        ValueAnimator fade = ValueAnimator.ofFloat(alphaValues);
-        fade.setStartDelay(fadeStartDelay);
-        fade.setDuration(fadeDuration);
-        fade.setInterpolator(LINEAR);
-        fade.addUpdateListener(anim -> {
-            float alpha = (float) anim.getAnimatedValue();
-            mArrow.setAlpha(alpha);
-            setAlpha(alpha);
-        });
-        animatorSet.play(fade);
-
-        setPivotX(mIsLeftAligned ? 0 : getMeasuredWidth());
-        setPivotY(mIsAboveIcon ? getMeasuredHeight() : 0);
-        Animator scale = ObjectAnimator.ofFloat(this, View.SCALE_Y, scaleValues);
-        scale.setDuration(totalDuration);
-        scale.setInterpolator(interpolator);
-        animatorSet.play(scale);
-
-        if (shouldScaleArrow) {
-            Animator arrowScaleAnimator = ObjectAnimator.ofFloat(mArrow, View.SCALE_Y,
-                    scaleValues);
-            arrowScaleAnimator.setDuration(totalDuration);
-            arrowScaleAnimator.setInterpolator(interpolator);
-            animatorSet.play(arrowScaleAnimator);
-        }
-
-        fadeInChildViews(this, alphaValues, childFadeStartDelay, childFadeDuration, animatorSet);
-
-        return animatorSet;
-    }
-
     private void fadeInChildViews(ViewGroup group, float[] alphaValues, long startDelay,
             long duration, AnimatorSet out) {
         for (int i = group.getChildCount() - 1; i >= 0; --i) {
@@ -673,22 +608,14 @@
         }
         mIsOpen = false;
 
-        mOpenCloseAnimator = ENABLE_MATERIAL_U_POPUP.get()
-                ? getMaterialUOpenCloseAnimator(
+        mOpenCloseAnimator = getOpenCloseAnimator(
                         false,
                         CLOSE_DURATION_U,
                         CLOSE_FADE_START_DELAY_U,
                         CLOSE_FADE_DURATION_U,
                         CLOSE_CHILD_FADE_START_DELAY_U,
                         CLOSE_CHILD_FADE_DURATION_U,
-                        EMPHASIZED_ACCELERATE)
-                : getOpenCloseAnimator(false,
-                        mCloseDuration,
-                        mCloseFadeStartDelay,
-                        mCloseFadeDuration,
-                        mCloseChildFadeStartDelay,
-                        mCloseChildFadeDuration,
-                        ACCELERATED_EASE);
+                        EMPHASIZED_ACCELERATE);
 
         onCreateCloseAnimation(mOpenCloseAnimator);
         mOpenCloseAnimator.addListener(new AnimatorListenerAdapter() {
@@ -705,7 +632,7 @@
         mOpenCloseAnimator.start();
     }
 
-    protected AnimatorSet getMaterialUOpenCloseAnimator(boolean isOpening, int scaleDuration,
+    protected AnimatorSet getOpenCloseAnimator(boolean isOpening, int scaleDuration,
             int fadeStartDelay, int fadeDuration, int childFadeStartDelay, int childFadeDuration,
             Interpolator interpolator) {
 
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 1f26bab..934d43b 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -20,21 +20,15 @@
 import static com.android.launcher3.Utilities.ATLEAST_P;
 import static com.android.launcher3.Utilities.squaredHypot;
 import static com.android.launcher3.Utilities.squaredTouchSlop;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_MATERIAL_U_POPUP;
 import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS;
-import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS_IF_NOTIFICATIONS;
 import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
 
-import static java.util.Collections.emptyList;
-
 import android.animation.AnimatorSet;
 import android.animation.LayoutTransition;
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
-import android.os.Build;
 import android.os.Handler;
 import android.os.Looper;
 import android.util.AttributeSet;
@@ -55,17 +49,12 @@
 import com.android.launcher3.R;
 import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
 import com.android.launcher3.accessibility.ShortcutMenuAccessibilityDelegate;
-import com.android.launcher3.dot.DotInfo;
 import com.android.launcher3.dragndrop.DragController;
 import com.android.launcher3.dragndrop.DragOptions;
 import com.android.launcher3.dragndrop.DragView;
 import com.android.launcher3.dragndrop.DraggableView;
 import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.model.data.ItemInfoWithIcon;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.notification.NotificationContainer;
-import com.android.launcher3.notification.NotificationInfo;
-import com.android.launcher3.notification.NotificationKeyData;
 import com.android.launcher3.shortcuts.DeepShortcutView;
 import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider;
 import com.android.launcher3.touch.ItemLongClickListener;
@@ -81,7 +70,7 @@
 import java.util.stream.Collectors;
 
 /**
- * A container for shortcuts to deep links and notifications associated with an app.
+ * A container for shortcuts to deep links associated with an app.
  *
  * @param <T> The activity on with the popup shows
  */
@@ -98,8 +87,6 @@
     private final float mShortcutHeight;
 
     private BubbleTextView mOriginalIcon;
-    private int mNumNotifications;
-    private NotificationContainer mNotificationContainer;
     private int mContainerWidth;
 
     private ViewGroup mWidgetContainer;
@@ -142,24 +129,12 @@
         if (ev.getAction() == MotionEvent.ACTION_DOWN) {
             mInterceptTouchDown.set(ev.getX(), ev.getY());
         }
-        if (mNotificationContainer != null
-                && mNotificationContainer.onInterceptSwipeEvent(ev)) {
-            return true;
-        }
         // Stop sending touch events to deep shortcut views if user moved beyond touch slop.
         return squaredHypot(mInterceptTouchDown.x - ev.getX(), mInterceptTouchDown.y - ev.getY())
                 > squaredTouchSlop(getContext());
     }
 
     @Override
-    public boolean onTouchEvent(MotionEvent ev) {
-        if (mNotificationContainer != null) {
-            return mNotificationContainer.onSwipeEvent(ev) || super.onTouchEvent(ev);
-        }
-        return super.onTouchEvent(ev);
-    }
-
-    @Override
     protected boolean isOfType(int type) {
         return (type & TYPE_ACTION_POPUP) != 0;
     }
@@ -194,14 +169,6 @@
         return false;
     }
 
-    @Override
-    protected void setChildColor(View view, int color, AnimatorSet animatorSetOut) {
-        super.setChildColor(view, color, animatorSetOut);
-        if (view.getId() == R.id.notification_container && mNotificationContainer != null) {
-            mNotificationContainer.updateBackgroundColor(color, animatorSetOut);
-        }
-    }
-
     /**
      * Returns true if we can show the container.
      *
@@ -213,7 +180,8 @@
     }
 
     /**
-     * Shows the notifications and deep shortcuts associated with a Launcher {@param icon}.
+     * Shows a popup with shortcuts associated with a Launcher icon
+     * @param icon the app icon to show the popup for
      * @return the container if shown or null.
      */
     public static PopupContainerWithArrow<Launcher> showForIcon(BubbleTextView icon) {
@@ -235,21 +203,10 @@
                 .map(s -> s.getShortcut(launcher, item, icon))
                 .filter(Objects::nonNull)
                 .collect(Collectors.toList());
-        if (ENABLE_MATERIAL_U_POPUP.get()) {
-            container = (PopupContainerWithArrow) launcher.getLayoutInflater().inflate(
-                    R.layout.popup_container_material_u, launcher.getDragLayer(), false);
-            container.configureForLauncher(launcher);
-            container.populateAndShowRowsMaterialU(icon, deepShortcutCount, systemShortcuts);
-        } else {
-            container = (PopupContainerWithArrow) launcher.getLayoutInflater().inflate(
-                    R.layout.popup_container, launcher.getDragLayer(), false);
-            container.configureForLauncher(launcher);
-            container.populateAndShow(
-                    icon,
-                    deepShortcutCount,
-                    popupDataProvider.getNotificationKeysForItem(item),
-                    systemShortcuts);
-        }
+        container = (PopupContainerWithArrow) launcher.getLayoutInflater().inflate(
+                R.layout.popup_container, launcher.getDragLayer(), false);
+        container.configureForLauncher(launcher);
+        container.populateAndShowRows(icon, deepShortcutCount, systemShortcuts);
         launcher.refreshAndBindWidgetsForPackageUser(PackageUserKey.fromItemInfo(item));
         container.requestFocus();
         return container;
@@ -263,91 +220,6 @@
         launcher.getDragController().addDragListener(this);
     }
 
-    private void initializeSystemShortcuts(List<SystemShortcut> shortcuts) {
-        if (shortcuts.isEmpty()) {
-            return;
-        }
-        // If there is only 1 shortcut, add it to its own container so it can show text and icon
-        if (shortcuts.size() == 1) {
-            mSystemShortcutContainer = inflateAndAdd(R.layout.system_shortcut_rows_container,
-                    this, 0);
-            initializeSystemShortcut(R.layout.system_shortcut, mSystemShortcutContainer,
-                    shortcuts.get(0), false);
-            return;
-        }
-        addSystemShortcutsIconsOnly(shortcuts);
-    }
-
-    @TargetApi(Build.VERSION_CODES.P)
-    public void populateAndShow(final BubbleTextView originalIcon, int shortcutCount,
-            final List<NotificationKeyData> notificationKeys, List<SystemShortcut> shortcuts) {
-        mNumNotifications = notificationKeys.size();
-        mOriginalIcon = originalIcon;
-
-        boolean hasDeepShortcuts = shortcutCount > 0;
-        mContainerWidth = getResources().getDimensionPixelSize(R.dimen.bg_popup_item_width);
-
-        // Add views
-        if (mNumNotifications > 0) {
-            // Add notification entries
-            if (mNotificationContainer == null) {
-                mNotificationContainer = findViewById(R.id.notification_container);
-                mNotificationContainer.setVisibility(VISIBLE);
-                mNotificationContainer.setPopupView(this);
-            } else {
-                mNotificationContainer.setVisibility(GONE);
-            }
-            updateNotificationHeader();
-        }
-        mSystemShortcutContainer = this;
-        if (mDeepShortcutContainer == null) {
-            mDeepShortcutContainer = findViewById(R.id.deep_shortcuts_container);
-        }
-        if (hasDeepShortcuts) {
-            List<SystemShortcut> systemShortcuts = getNonWidgetSystemShortcuts(shortcuts);
-            // if there are deep shortcuts, we might want to increase the width of shortcuts to fit
-            // horizontally laid out system shortcuts.
-            mContainerWidth = Math.max(mContainerWidth,
-                    systemShortcuts.size() * getResources()
-                            .getDimensionPixelSize(R.dimen.system_shortcut_header_icon_touch_size)
-            );
-
-            mDeepShortcutContainer.setVisibility(View.VISIBLE);
-
-            for (int i = shortcutCount; i > 0; i--) {
-                DeepShortcutView v = inflateAndAdd(R.layout.deep_shortcut, mDeepShortcutContainer);
-                v.getLayoutParams().width = mContainerWidth;
-                mDeepShortcuts.add(v);
-            }
-            updateHiddenShortcuts();
-            Optional<SystemShortcut.Widgets> widgetShortcutOpt = getWidgetShortcut(shortcuts);
-            if (widgetShortcutOpt.isPresent()) {
-                if (mWidgetContainer == null) {
-                    mWidgetContainer = inflateAndAdd(R.layout.widget_shortcut_container, this, 0);
-                }
-                initializeWidgetShortcut(mWidgetContainer, widgetShortcutOpt.get());
-            }
-
-            initializeSystemShortcuts(systemShortcuts);
-        } else {
-            mDeepShortcutContainer.setVisibility(View.GONE);
-            mSystemShortcutContainer = inflateAndAdd(R.layout.system_shortcut_rows_container,
-                    this, 0);
-            mWidgetContainer = mSystemShortcutContainer;
-            if (!shortcuts.isEmpty()) {
-                for (int i = 0; i < shortcuts.size(); i++) {
-                    initializeSystemShortcut(
-                            R.layout.system_shortcut,
-                            mSystemShortcutContainer,
-                            shortcuts.get(i),
-                            i < shortcuts.size() - 1);
-                }
-            }
-        }
-        show();
-        loadAppShortcuts((ItemInfo) originalIcon.getTag(), notificationKeys);
-    }
-
     /**
      * Populate and show shortcuts for the Launcher U app shortcut design.
      * Will inflate the container and shortcut View instances for the popup container.
@@ -355,28 +227,27 @@
      * @param deepShortcutCount Number of DeepShortcutView instances to add to container
      * @param systemShortcuts List of SystemShortcuts to add to container
      */
-    public void populateAndShowRowsMaterialU(final BubbleTextView originalIcon,
+    public void populateAndShowRows(final BubbleTextView originalIcon,
             int deepShortcutCount, List<SystemShortcut> systemShortcuts) {
 
         mOriginalIcon = originalIcon;
         mContainerWidth = getResources().getDimensionPixelSize(R.dimen.bg_popup_item_width);
 
         if (deepShortcutCount > 0) {
-            addAllShortcutsMaterialU(deepShortcutCount, systemShortcuts);
+            addAllShortcuts(deepShortcutCount, systemShortcuts);
         } else if (!systemShortcuts.isEmpty()) {
-            addSystemShortcutsMaterialU(systemShortcuts,
-                    R.layout.system_shortcut_rows_container_material_u,
+            addSystemShortcuts(systemShortcuts,
+                    R.layout.system_shortcut_rows_container,
                     R.layout.system_shortcut);
         }
         show();
-        loadAppShortcuts((ItemInfo) originalIcon.getTag(), /* notificationKeys= */ emptyList());
+        loadAppShortcuts((ItemInfo) originalIcon.getTag());
     }
 
     /**
      * Animates and loads shortcuts on background thread for this popup container
      */
-    private void loadAppShortcuts(ItemInfo originalItemInfo,
-            List<NotificationKeyData> notificationKeys) {
+    private void loadAppShortcuts(ItemInfo originalItemInfo) {
 
         if (ATLEAST_P) {
             setAccessibilityPaneTitle(getTitleForAccessibility());
@@ -387,7 +258,7 @@
         // Load the shortcuts on a background thread and update the container as it animates.
         MODEL_EXECUTOR.getHandler().postAtFrontOfQueue(PopupPopulator.createUpdateRunnable(
                 mActivityContext, originalItemInfo, new Handler(Looper.getMainLooper()),
-                this, mDeepShortcuts, notificationKeys));
+                this, mDeepShortcuts));
     }
 
     /**
@@ -396,16 +267,16 @@
      * @param deepShortcutCount number of DeepShortcutView instances
      * @param systemShortcuts List of SystemShortcuts
      */
-    private void addAllShortcutsMaterialU(int deepShortcutCount,
+    private void addAllShortcuts(int deepShortcutCount,
             List<SystemShortcut> systemShortcuts) {
         if (deepShortcutCount + systemShortcuts.size() <= SHORTCUT_COLLAPSE_THRESHOLD) {
             // add all system shortcuts including widgets shortcut to same container
-            addSystemShortcutsMaterialU(systemShortcuts,
-                    R.layout.system_shortcut_rows_container_material_u,
+            addSystemShortcuts(systemShortcuts,
+                    R.layout.system_shortcut_rows_container,
                     R.layout.system_shortcut);
             float currentHeight = (mShortcutHeight * systemShortcuts.size())
                     + mChildContainerMargin;
-            addDeepShortcutsMaterialU(deepShortcutCount, currentHeight);
+            addDeepShortcuts(deepShortcutCount, currentHeight);
             return;
         }
 
@@ -426,7 +297,7 @@
             initializeWidgetShortcut(mWidgetContainer, widgetShortcutOpt.get());
             currentHeight += mShortcutHeight + mChildContainerMargin;
         }
-        addDeepShortcutsMaterialU(deepShortcutCount, currentHeight);
+        addDeepShortcuts(deepShortcutCount, currentHeight);
     }
 
     /**
@@ -464,7 +335,7 @@
      * @param systemShortcutContainerLayout Layout Resource for the Container of shortcut Views
      * @param systemShortcutLayout Layout Resource for the individual shortcut Views
      */
-    private void addSystemShortcutsMaterialU(List<SystemShortcut> systemShortcuts,
+    private void addSystemShortcuts(List<SystemShortcut> systemShortcuts,
             @LayoutRes int systemShortcutContainerLayout, @LayoutRes int systemShortcutLayout) {
 
         if (systemShortcuts.size() == 0) {
@@ -486,9 +357,7 @@
             return;
         }
 
-        mSystemShortcutContainer = ENABLE_MATERIAL_U_POPUP.get()
-                ? inflateAndAdd(R.layout.system_shortcut_icons_container_material_u, this)
-                : inflateAndAdd(R.layout.system_shortcut_icons_container, this, 0);
+        mSystemShortcutContainer = inflateAndAdd(R.layout.system_shortcut_icons_container, this);
 
         for (int i = 0; i < systemShortcuts.size(); i++) {
             @LayoutRes int shortcutIconLayout = R.layout.system_shortcut_icon_only;
@@ -513,13 +382,13 @@
      * @param deepShortcutCount number of DeepShortcutView instances to add
      * @param currentHeight height of popup before adding deep shortcuts
      */
-    private void addDeepShortcutsMaterialU(int deepShortcutCount, float currentHeight) {
+    private void addDeepShortcuts(int deepShortcutCount, float currentHeight) {
         mDeepShortcutContainer = inflateAndAdd(R.layout.deep_shortcut_container, this);
         for (int i = deepShortcutCount; i > 0; i--) {
             currentHeight += mShortcutHeight;
             // when there is limited vertical screen space, limit total popup rows to fit
             if (currentHeight >= mActivityContext.getDeviceProfile().availableHeightPx) break;
-            DeepShortcutView v = inflateAndAdd(R.layout.deep_shortcut_material_u,
+            DeepShortcutView v = inflateAndAdd(R.layout.deep_shortcut,
                     mDeepShortcutContainer);
             v.getLayoutParams().width = mContainerWidth;
             mDeepShortcuts.add(v);
@@ -527,10 +396,6 @@
         updateHiddenShortcuts();
     }
 
-    protected NotificationContainer getNotificationContainer() {
-        return mNotificationContainer;
-    }
-
     protected BubbleTextView getOriginalIcon() {
         return mOriginalIcon;
     }
@@ -548,9 +413,7 @@
     }
 
     private String getTitleForAccessibility() {
-        return getContext().getString(mNumNotifications == 0 ?
-                R.string.action_deep_shortcut :
-                R.string.shortcuts_menu_with_notifications_description);
+        return getContext().getString(R.string.action_deep_shortcut);
     }
 
     @Override
@@ -564,20 +427,11 @@
                 : mOriginalIcon.getHeight());
     }
 
-    public void applyNotificationInfos(List<NotificationInfo> notificationInfos) {
-        if (mNotificationContainer != null) {
-            mNotificationContainer.applyNotificationInfos(notificationInfos);
-        }
-    }
-
     protected void updateHiddenShortcuts() {
-        int allowedCount = mNotificationContainer != null
-                ? MAX_SHORTCUTS_IF_NOTIFICATIONS : MAX_SHORTCUTS;
-
         int total = mDeepShortcuts.size();
         for (int i = 0; i < total; i++) {
             DeepShortcutView view = mDeepShortcuts.get(i);
-            view.setVisibility(i >= allowedCount ? GONE : VISIBLE);
+            view.setVisibility(i >= MAX_SHORTCUTS ? GONE : VISIBLE);
         }
     }
 
@@ -666,14 +520,6 @@
         };
     }
 
-    protected void updateNotificationHeader() {
-        ItemInfoWithIcon itemInfo = (ItemInfoWithIcon) mOriginalIcon.getTag();
-        DotInfo dotInfo = mActivityContext.getDotInfoForItem(itemInfo);
-        if (mNotificationContainer != null && dotInfo != null) {
-            mNotificationContainer.updateHeader(dotInfo.getNotificationCount());
-        }
-    }
-
     @Override
     public void onDropCompleted(View target, DragObject d, boolean success) {  }
 
diff --git a/src/com/android/launcher3/popup/PopupLiveUpdateHandler.java b/src/com/android/launcher3/popup/PopupLiveUpdateHandler.java
index c5d5452..9d6f2a5 100644
--- a/src/com/android/launcher3/popup/PopupLiveUpdateHandler.java
+++ b/src/com/android/launcher3/popup/PopupLiveUpdateHandler.java
@@ -15,22 +15,12 @@
  */
 package com.android.launcher3.popup;
 
-import static android.view.View.GONE;
-
 import android.content.Context;
 import android.view.View;
 
 import com.android.launcher3.BubbleTextView;
-import com.android.launcher3.dot.DotInfo;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.notification.NotificationContainer;
-import com.android.launcher3.notification.NotificationKeyData;
-import com.android.launcher3.util.PackageUserKey;
 import com.android.launcher3.views.ActivityContext;
 
-import java.util.Map;
-import java.util.function.Predicate;
-
 /**
  * Utility class to handle updates while the popup is visible (like widgets and
  * notification changes)
@@ -67,40 +57,6 @@
         }
     }
 
-    /**
-     * Updates the notification header if the original icon's dot updated.
-     */
-    @Override
-    public void onNotificationDotsUpdated(Predicate<PackageUserKey> updatedDots) {
-        ItemInfo itemInfo = (ItemInfo) mPopupContainerWithArrow.getOriginalIcon().getTag();
-        PackageUserKey packageUser = PackageUserKey.fromItemInfo(itemInfo);
-        if (updatedDots.test(packageUser)) {
-            mPopupContainerWithArrow.updateNotificationHeader();
-        }
-    }
-
-
-    @Override
-    public void trimNotifications(Map<PackageUserKey, DotInfo> updatedDots) {
-        NotificationContainer notificationContainer =
-                mPopupContainerWithArrow.getNotificationContainer();
-        if (notificationContainer == null) {
-            return;
-        }
-        ItemInfo originalInfo = (ItemInfo) mPopupContainerWithArrow.getOriginalIcon().getTag();
-        DotInfo dotInfo = updatedDots.get(PackageUserKey.fromItemInfo(originalInfo));
-        if (dotInfo == null || dotInfo.getNotificationKeys().size() == 0) {
-            // No more notifications, remove the notification views and expand all shortcuts.
-            notificationContainer.setVisibility(GONE);
-            mPopupContainerWithArrow.updateHiddenShortcuts();
-            mPopupContainerWithArrow.assignMarginsAndBackgrounds(mPopupContainerWithArrow);
-            mPopupContainerWithArrow.updateArrowColor();
-        } else {
-            notificationContainer.trimNotifications(
-                    NotificationKeyData.extractKeysOnly(dotInfo.getNotificationKeys()));
-        }
-    }
-
     @Override
     public void onSystemShortcutsUpdated() {
         mPopupContainerWithArrow.close(true);
diff --git a/src/com/android/launcher3/popup/PopupPopulator.java b/src/com/android/launcher3/popup/PopupPopulator.java
index 8be4e6c..aa24f60 100644
--- a/src/com/android/launcher3/popup/PopupPopulator.java
+++ b/src/com/android/launcher3/popup/PopupPopulator.java
@@ -24,26 +24,19 @@
 import android.os.Handler;
 import android.os.UserHandle;
 
-import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.icons.IconCache;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.notification.NotificationInfo;
-import com.android.launcher3.notification.NotificationKeyData;
-import com.android.launcher3.notification.NotificationListener;
 import com.android.launcher3.shortcuts.DeepShortcutView;
 import com.android.launcher3.shortcuts.ShortcutRequest;
 import com.android.launcher3.views.ActivityContext;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Comparator;
-import java.util.Iterator;
 import java.util.List;
-import java.util.stream.Collectors;
 
 /**
  * Contains logic relevant to populating a {@link PopupContainerWithArrow}. In particular,
@@ -52,24 +45,20 @@
 public class PopupPopulator {
 
     public static final int MAX_SHORTCUTS = 4;
-    @VisibleForTesting static final int NUM_DYNAMIC = 2;
-    public static final int MAX_SHORTCUTS_IF_NOTIFICATIONS = 2;
+    @VisibleForTesting
+    static final int NUM_DYNAMIC = 2;
 
     /**
      * Sorts shortcuts in rank order, with manifest shortcuts coming before dynamic shortcuts.
      */
-    private static final Comparator<ShortcutInfo> SHORTCUT_RANK_COMPARATOR
-            = new Comparator<ShortcutInfo>() {
-        @Override
-        public int compare(ShortcutInfo a, ShortcutInfo b) {
-            if (a.isDeclaredInManifest() && !b.isDeclaredInManifest()) {
-                return -1;
-            }
-            if (!a.isDeclaredInManifest() && b.isDeclaredInManifest()) {
-                return 1;
-            }
-            return Integer.compare(a.getRank(), b.getRank());
+    private static final Comparator<ShortcutInfo> SHORTCUT_RANK_COMPARATOR = (a, b) -> {
+        if (a.isDeclaredInManifest() && !b.isDeclaredInManifest()) {
+            return -1;
         }
+        if (!a.isDeclaredInManifest() && b.isDeclaredInManifest()) {
+            return 1;
+        }
+        return Integer.compare(a.getRank(), b.getRank());
     };
 
     /**
@@ -77,23 +66,10 @@
      * We want the filter to include both static and dynamic shortcuts, so we always
      * include NUM_DYNAMIC dynamic shortcuts, if at least that many are present.
      *
-     * @param shortcutIdToRemoveFirst An id that should be filtered out first, if any.
      * @return a subset of shortcuts, in sorted order, with size <= MAX_SHORTCUTS.
      */
-    public static List<ShortcutInfo> sortAndFilterShortcuts(
-            List<ShortcutInfo> shortcuts, @Nullable String shortcutIdToRemoveFirst) {
-        // Remove up to one specific shortcut before sorting and doing somewhat fancy filtering.
-        if (shortcutIdToRemoveFirst != null) {
-            Iterator<ShortcutInfo> shortcutIterator = shortcuts.iterator();
-            while (shortcutIterator.hasNext()) {
-                if (shortcutIterator.next().getId().equals(shortcutIdToRemoveFirst)) {
-                    shortcutIterator.remove();
-                    break;
-                }
-            }
-        }
-
-        Collections.sort(shortcuts, SHORTCUT_RANK_COMPARATOR);
+    public static List<ShortcutInfo> sortAndFilterShortcuts(List<ShortcutInfo> shortcuts) {
+        shortcuts.sort(SHORTCUT_RANK_COMPARATOR);
         if (shortcuts.size() <= MAX_SHORTCUTS) {
             return shortcuts;
         }
@@ -127,37 +103,20 @@
     }
 
     /**
-     * Returns a runnable to update the provided shortcuts and notifications
+     * Returns a runnable to update the provided shortcuts
      */
     public static <T extends Context & ActivityContext> Runnable createUpdateRunnable(
             final T context,
             final ItemInfo originalInfo,
             final Handler uiHandler, final PopupContainerWithArrow container,
-            final List<DeepShortcutView> shortcutViews,
-            final List<NotificationKeyData> notificationKeys) {
+            final List<DeepShortcutView> shortcutViews) {
         final ComponentName activity = originalInfo.getTargetComponent();
         final UserHandle user = originalInfo.user;
         return () -> {
-            if (!notificationKeys.isEmpty()) {
-                NotificationListener notificationListener =
-                        NotificationListener.getInstanceIfConnected();
-                final List<NotificationInfo> infos;
-                if (notificationListener == null) {
-                    infos = Collections.emptyList();
-                } else {
-                    infos = notificationListener.getNotificationsForKeys(notificationKeys).stream()
-                            .map(sbn -> new NotificationInfo(context, sbn, originalInfo))
-                            .collect(Collectors.toList());
-                }
-                uiHandler.post(() -> container.applyNotificationInfos(infos));
-            }
-
             List<ShortcutInfo> shortcuts = new ShortcutRequest(context, user)
                     .withContainer(activity)
                     .query(ShortcutRequest.PUBLISHED);
-            String shortcutIdToDeDupe = notificationKeys.isEmpty() ? null
-                    : notificationKeys.get(0).shortcutId;
-            shortcuts = PopupPopulator.sortAndFilterShortcuts(shortcuts, shortcutIdToDeDupe);
+            shortcuts = PopupPopulator.sortAndFilterShortcuts(shortcuts);
             IconCache cache = LauncherAppState.getInstance(context).getIconCache();
             for (int i = 0; i < shortcuts.size() && i < shortcutViews.size(); i++) {
                 final ShortcutInfo shortcut = shortcuts.get(i);
diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java
index e8be12c..6e697d9 100644
--- a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java
+++ b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java
@@ -18,7 +18,6 @@
 import static android.view.View.MeasureSpec.EXACTLY;
 import static android.view.View.MeasureSpec.makeMeasureSpec;
 
-import static com.android.launcher3.config.FeatureFlags.ENABLE_MATERIAL_U_POPUP;
 import static com.android.launcher3.popup.SystemShortcut.APP_INFO;
 
 import android.content.Context;
@@ -45,7 +44,6 @@
 import com.android.launcher3.views.BaseDragLayer;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 
 /**
@@ -203,20 +201,10 @@
         }
         int deepShortcutCount = popupDataProvider.getShortcutCountForItem(item);
         final PopupContainerWithArrow<SecondaryDisplayLauncher> container;
-        if (ENABLE_MATERIAL_U_POPUP.get()) {
-            container = (PopupContainerWithArrow) mActivity.getLayoutInflater().inflate(
-                    R.layout.popup_container_material_u, mActivity.getDragLayer(), false);
-            container.populateAndShowRowsMaterialU((BubbleTextView) v, deepShortcutCount,
-                    systemShortcuts);
-        } else {
-            container = (PopupContainerWithArrow) mActivity.getLayoutInflater().inflate(
-                    R.layout.popup_container, mActivity.getDragLayer(), false);
-            container.populateAndShow(
-                    (BubbleTextView) v,
-                    deepShortcutCount,
-                    Collections.emptyList(),
-                    systemShortcuts);
-        }
+        container = (PopupContainerWithArrow) mActivity.getLayoutInflater().inflate(
+                R.layout.popup_container, mActivity.getDragLayer(), false);
+        container.populateAndShowRows((BubbleTextView) v, deepShortcutCount,
+                systemShortcuts);
         container.requestFocus();
 
         if (!FeatureFlags.SECONDARY_DRAG_N_DROP_TO_PIN.get() || !mActivity.isAppDrawerShown()) {
diff --git a/src/com/android/launcher3/views/OptionsPopupView.java b/src/com/android/launcher3/views/OptionsPopupView.java
index b62f60d..cf59085 100644
--- a/src/com/android/launcher3/views/OptionsPopupView.java
+++ b/src/com/android/launcher3/views/OptionsPopupView.java
@@ -18,7 +18,6 @@
 import static androidx.core.content.ContextCompat.getColorStateList;
 
 import static com.android.launcher3.LauncherState.EDIT_MODE;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_MATERIAL_U_POPUP;
 import static com.android.launcher3.config.FeatureFlags.MULTI_SELECT_EDIT_MODE;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.IGNORE;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SETTINGS_BUTTON_TAP_OR_LONGPRESS;
@@ -26,7 +25,6 @@
 
 import android.content.Context;
 import android.content.Intent;
-import android.graphics.Color;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.drawable.Drawable;
@@ -149,12 +147,8 @@
 
     @Override
     public void assignMarginsAndBackgrounds(ViewGroup viewGroup) {
-        if (ENABLE_MATERIAL_U_POPUP.get()) {
-            assignMarginsAndBackgrounds(viewGroup,
-                    getColorStateList(getContext(), mColorIds[0]).getDefaultColor());
-        } else {
-            assignMarginsAndBackgrounds(viewGroup, Color.TRANSPARENT);
-        }
+        assignMarginsAndBackgrounds(viewGroup,
+                getColorStateList(getContext(), mColorIds[0]).getDefaultColor());
     }
 
     public static <T extends Context & ActivityContext> OptionsPopupView<T> show(
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
index 98d854e..76a044d 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
@@ -37,6 +37,7 @@
 import android.widget.Advanceable;
 import android.widget.RemoteViews;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
 import com.android.launcher3.CheckLongPressHelper;
@@ -63,6 +64,8 @@
     private static final long ADVANCE_INTERVAL = 20000;
     private static final long ADVANCE_STAGGER = 250;
 
+    private @Nullable CellChildViewPreLayoutListener mCellChildViewPreLayoutListener;
+
     // Maintains a list of widget ids which are supposed to be auto advanced.
     private static final SparseBooleanArray sAutoAdvanceWidgetIds = new SparseBooleanArray();
     // Maximum duration for which updates can be deferred.
@@ -335,6 +338,26 @@
         requestLayout();
     }
 
+    /**
+     * Set the pre-layout listener
+     * @param listener The listener to be notified when {@code CellLayout} is to layout this view
+     */
+    public void setCellChildViewPreLayoutListener(
+            @NonNull CellChildViewPreLayoutListener listener) {
+        mCellChildViewPreLayoutListener = listener;
+    }
+
+    /** @return The current cell layout listener */
+    @Nullable
+    public CellChildViewPreLayoutListener getCellChildViewPreLayoutListener() {
+        return mCellChildViewPreLayoutListener;
+    }
+
+    /** Clear the listener for the pre-layout in CellLayout */
+    public void clearCellChildViewPreLayoutListener() {
+        mCellChildViewPreLayoutListener = null;
+    }
+
     @Override
     public void onColorsChanged(SparseIntArray colors) {
         if (isDeferringUpdates()) {
@@ -460,4 +483,19 @@
         }
         return false;
     }
+
+    /**
+     * Listener interface to be called when {@code CellLayout} is about to layout this child view
+     */
+    public interface CellChildViewPreLayoutListener {
+        /**
+         * Notify the bound changes to this view on pre-layout
+         * @param v The view which the listener is set for
+         * @param left The new left coordinate of this view
+         * @param top The new top coordinate of this view
+         * @param right The new right coordinate of this view
+         * @param bottom The new bottom coordinate of this view
+         */
+        void notifyBoundChangeOnPreLayout(View v, int left, int top, int right, int bottom);
+    }
 }
diff --git a/tests/src/com/android/launcher3/popup/PopupPopulatorTest.java b/tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
index 6764e09..f3eb0a9 100644
--- a/tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
+++ b/tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
@@ -64,34 +64,14 @@
                 MAX_SHORTCUTS - NUM_DYNAMIC, NUM_DYNAMIC);
     }
 
-    @Test
-    public void testDeDupeShortcutId() {
-        // Successfully remove one of the shortcuts
-        filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(3, 0), 2, 0, generateId(true, 1));
-        filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(0, 3), 0, 2, generateId(false, 1));
-        filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(2, 2), 2, 1, generateId(false, 1));
-        filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(2, 2), 1, 2, generateId(true, 1));
-        // Successfully keep all shortcuts when id doesn't exist
-        filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(3, 0), 3, 0, generateId(false, 1));
-        filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(3, 0), 3, 0, generateId(true, 4));
-        filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(2, 2), 2, 2, generateId(false, 4));
-        filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(2, 2), 2, 2, generateId(true, 4));
-    }
-
     private String generateId(boolean isStatic, int rank) {
         return (isStatic ? "static" : "dynamic") + rank;
     }
 
     private void filterShortcutsAndAssertNumStaticAndDynamic(
             List<ShortcutInfo> shortcuts, int expectedStatic, int expectedDynamic) {
-        filterShortcutsAndAssertNumStaticAndDynamic(shortcuts, expectedStatic, expectedDynamic, null);
-    }
-
-    private void filterShortcutsAndAssertNumStaticAndDynamic(List<ShortcutInfo> shortcuts,
-            int expectedStatic, int expectedDynamic, String shortcutIdToRemove) {
         Collections.shuffle(shortcuts);
-        List<ShortcutInfo> filteredShortcuts = PopupPopulator.sortAndFilterShortcuts(
-                shortcuts, shortcutIdToRemove);
+        List<ShortcutInfo> filteredShortcuts = PopupPopulator.sortAndFilterShortcuts(shortcuts);
         assertIsSorted(filteredShortcuts);
 
         int numStatic = 0;