Merge "Fixing dark tint for ShadowDrawable. Updating the dark theme for empty all-apps search drawable." into ub-launcher3-dorval-polish
diff --git a/res/drawable/deep_shortcuts_drag_handle.xml b/res/drawable/deep_shortcuts_drag_handle.xml
index 82e844d..8fc3779 100644
--- a/res/drawable/deep_shortcuts_drag_handle.xml
+++ b/res/drawable/deep_shortcuts_drag_handle.xml
@@ -22,6 +22,7 @@
         android:tint="?android:attr/textColorHint" >
 
     <path
-        android:pathData="M20 9H4v2h16V9zM4 15h16v-2H4v2z"
+        android:pathData="M19,9H5c-0.55,0-1,0.45-1,1l0,0c0,0.55,0.45,1,1,1h14c0.55,0,1-0.45,1-1l0,0C20,9.45,19.55,9,19,9z M5,
+        15h14c0.55,0,1-0.45,1-1l0,0c0-0.55-0.45-1-1-1H5c-0.55,0-1,0.45-1,1l0,0C4,14.55,4.45,15,5,15z"
         android:fillColor="@android:color/white" />
 </vector>
\ No newline at end of file
diff --git a/res/drawable/ic_info_no_shadow.xml b/res/drawable/ic_info_no_shadow.xml
index 91a3a56..b5512c3 100644
--- a/res/drawable/ic_info_no_shadow.xml
+++ b/res/drawable/ic_info_no_shadow.xml
@@ -21,5 +21,7 @@
         android:tint="?android:attr/textColorPrimary" >
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 9h2V7h-2v2z"/>
+        android:pathData="M12,17L12,17c0.55,0,1-0.45,1-1v-4c0-0.55-0.45-1-1-1l0,0c-0.55,0-1,0.45-1,1v4C11,16.55,11.45,17,12,17z M12,2C6.48,
+        2,2,6.48,2,12s4.48,10,10,10s10-4.48,10-10S17.52,2,12,2z M12,20c-4.41,0-8-3.59-8-8s3.59-8,8-8s8,3.59,8,8S16.41,20,12,20zM12,
+        9.1L12,9.1c0.61,0,1.1-0.49,1.1-1.1l0,0c0-0.61-0.49-1.1-1.1-1.1l0,0c-0.61,0-1.1,0.49-1.1,1.1l0,0C10.9,8.61,11.39,9.1,12,9.1z"/>
 </vector>
diff --git a/res/drawable/ic_widget.xml b/res/drawable/ic_widget.xml
index 3e7bd7b..de2980f 100644
--- a/res/drawable/ic_widget.xml
+++ b/res/drawable/ic_widget.xml
@@ -20,5 +20,7 @@
         android:viewportHeight="48.0">
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M26 26v16h16V26H26zM6 42h16V26H6v16zM6 6v16h16V6H6zm27.31-2.63L22 14.69 33.31 26l11.31-11.31L33.31 3.37z"/>
+        android:pathData="M26,28v12c0,1,0.8,2,2,2h12c1,0,2-1,2-2V28c0-1.2-1-2-2-2H28C26.8,26,26,26.8,26,28z M8,42h12c1.2,0,2-1,2-2V28
+        c0-1.2-0.8-2-2-2H8c-1,0-2,0.8-2,2v12C6,41,7,42,8,42z M6,8v12c0,1.2,1,2,2,2h12c1.2,0,2-0.8,2-2V8c0-1-0.8-2-2-2H8C7,6,6,7,6,8z
+        M32.6,4.6l-8,8c-0.8,0.8-0.8,2,0,2.8l8,8c0.8,0.8,2,0.8,2.8,0l8-8c0.8-0.8,0.8-2,0-2.8l-8-8C34.6,3.8,33.4,3.8,32.6,4.6z"/>
 </vector>
diff --git a/res/layout/all_apps_icon.xml b/res/layout/all_apps_icon.xml
index ca0cbcc..79fb612 100644
--- a/res/layout/all_apps_icon.xml
+++ b/res/layout/all_apps_icon.xml
@@ -23,7 +23,6 @@
     android:stateListAnimator="@animator/all_apps_fastscroll_icon_anim"
     launcher:iconDisplay="all_apps"
     launcher:centerVertically="true"
-    android:paddingLeft="4dp"
-    android:paddingRight="4dp"
-    android:drawablePadding="@dimen/dynamic_grid_icon_drawable_padding" />
+    android:paddingLeft="@dimen/dynamic_grid_cell_padding_x"
+    android:paddingRight="@dimen/dynamic_grid_cell_padding_x" />
 
diff --git a/res/layout/notification_main.xml b/res/layout/notification_main.xml
index b2443f5..7a8cf6d 100644
--- a/res/layout/notification_main.xml
+++ b/res/layout/notification_main.xml
@@ -30,7 +30,8 @@
         android:gravity="center_vertical"
         android:background="?attr/popupColorPrimary"
         android:paddingStart="@dimen/notification_padding_start"
-        android:paddingEnd="@dimen/notification_main_text_padding_end">
+        android:paddingEnd="@dimen/notification_main_text_padding_end"
+        android:paddingBottom="16dp">
         <TextView
             android:id="@+id/title"
             android:layout_width="match_parent"
@@ -58,6 +59,7 @@
         android:layout_width="@dimen/notification_icon_size"
         android:layout_height="@dimen/notification_icon_size"
         android:layout_marginEnd="@dimen/notification_padding_end"
+        android:layout_marginBottom="8dp"
         android:layout_gravity="center_vertical|end" />
 
 </com.android.launcher3.notification.NotificationMainView>
diff --git a/res/layout/page_indicator.xml b/res/layout/page_indicator.xml
index e29e5b1..c5ef6e0 100644
--- a/res/layout/page_indicator.xml
+++ b/res/layout/page_indicator.xml
@@ -23,6 +23,6 @@
             android:id="@+id/all_apps_handle"
             android:layout_width="48dp"
             android:layout_height="match_parent"
-            android:layout_gravity="center"
+            android:layout_gravity="top|center"
             android:scaleType="centerInside"/>
 </com.android.launcher3.pageindicators.PageIndicatorLineCaret>
diff --git a/res/layout/qsb_default_view.xml b/res/layout/qsb_default_view.xml
index 3075f80..04fe236 100644
--- a/res/layout/qsb_default_view.xml
+++ b/res/layout/qsb_default_view.xml
@@ -21,7 +21,7 @@
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="48dp"
-        android:layout_margin="16dp"
+        android:layout_margin="8dp"
         android:layout_gravity="center_vertical"
         android:background="@drawable/round_rect_primary"
         android:elevation="2dp"
diff --git a/res/layout/shortcuts_item.xml b/res/layout/shortcuts_item.xml
index e54462e..7cd996d 100644
--- a/res/layout/shortcuts_item.xml
+++ b/res/layout/shortcuts_item.xml
@@ -22,10 +22,18 @@
     android:elevation="@dimen/deep_shortcuts_elevation">
 
     <LinearLayout
-        android:id="@+id/deep_shortcuts"
+        android:id="@+id/content"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:orientation="vertical">
+
+        <!-- The shortcuts header is added at runtime when necessary. -->
+
+        <LinearLayout
+            android:id="@+id/shortcuts"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:orientation="vertical" />
     </LinearLayout>
 
 </com.android.launcher3.shortcuts.ShortcutsItemView>
diff --git a/res/layout/system_shortcut_icons.xml b/res/layout/system_shortcut_icons.xml
index db59d49..34d63e7 100644
--- a/res/layout/system_shortcut_icons.xml
+++ b/res/layout/system_shortcut_icons.xml
@@ -21,4 +21,7 @@
     android:layout_height="@dimen/system_shortcut_header_height"
     android:orientation="horizontal"
     android:gravity="end|center_vertical"
-    android:background="?attr/popupColorSecondary" />
+    android:background="?attr/popupColorSecondary"
+    android:elevation="1dp"
+    android:outlineProvider="none" />
+    <!-- We have elevation so this is drawn on top, but no outline provider to remove shadow -->
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 57b4be4..b90de82 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -16,8 +16,8 @@
 
 <resources>
 <!-- Dynamic Grid -->
-    <dimen name="dynamic_grid_edge_margin">8dp</dimen>
-    <dimen name="dynamic_grid_page_indicator_height">28dp</dimen>
+    <dimen name="dynamic_grid_edge_margin">16dp</dimen>
+    <dimen name="dynamic_grid_page_indicator_height">32dp</dimen>
     <dimen name="dynamic_grid_page_indicator_line_height">1dp</dimen>
     <dimen name="dynamic_grid_page_indicator_gutter_width_left_nav_bar">38dp</dimen>
     <dimen name="dynamic_grid_page_indicator_gutter_width_right_nav_bar">48dp</dimen>
@@ -26,14 +26,17 @@
     <dimen name="dynamic_grid_overview_max_icon_zone_height">120dp</dimen>
     <dimen name="dynamic_grid_overview_bar_item_width">80dp</dimen>
     <dimen name="dynamic_grid_overview_bar_spacer_width">25dp</dimen>
-    <dimen name="dynamic_grid_workspace_top_padding">12dp</dimen>
+    <dimen name="dynamic_grid_workspace_top_padding">8dp</dimen>
     <dimen name="dynamic_grid_workspace_page_spacing">8dp</dimen>
     <!-- Minimum space between workspace and hotseat in spring loaded mode -->
     <dimen name="dynamic_grid_min_spring_loaded_space">8dp</dimen>
 
+    <!-- dynamic_grid_edge_margin / 2 -->
+    <dimen name="dynamic_grid_cell_padding_x">8dp</dimen>
+
     <!-- Hotseat -->
     <dimen name="dynamic_grid_hotseat_top_padding">8dp</dimen>
-    <dimen name="dynamic_grid_hotseat_bottom_padding">0dp</dimen>
+    <dimen name="dynamic_grid_hotseat_bottom_padding">2dp</dimen>
     <dimen name="dynamic_grid_hotseat_height">80dp</dimen>
     <dimen name="dynamic_grid_hotseat_land_gutter_width">24dp</dimen>
 
@@ -152,6 +155,7 @@
     <dimen name="deep_shortcuts_elevation">9dp</dimen>
     <dimen name="bg_popup_item_width">220dp</dimen>
     <dimen name="bg_popup_item_height">56dp</dimen>
+    <dimen name="bg_popup_item_condensed_height">48dp</dimen>
     <dimen name="pre_drag_view_scale">6dp</dimen>
     <!-- an icon with shortcuts must be dragged this far before the container is removed. -->
     <dimen name="deep_shortcuts_start_drag_threshold">16dp</dimen>
@@ -195,7 +199,7 @@
     <!-- notification_padding_end + (icon_size - footer_icon_size) / 2 -->
     <dimen name="notification_footer_icon_row_padding">15dp</dimen>
     <dimen name="notification_header_height">32dp</dimen>
-    <dimen name="notification_main_height">80dp</dimen>
+    <dimen name="notification_main_height">96dp</dimen>
     <dimen name="notification_footer_height">32dp</dimen>
     <dimen name="notification_header_text_size">13sp</dimen>
     <dimen name="notification_header_count_text_size">12sp</dimen>
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index b6e7328..f8e87c5 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -168,6 +168,7 @@
         int defaultIconSize = grid.iconSizePx;
         if (display == DISPLAY_WORKSPACE) {
             setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.iconTextSizePx);
+            setCompoundDrawablePadding(grid.iconDrawablePaddingPx);
         } else if (display == DISPLAY_ALL_APPS) {
             setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.allAppsIconTextSizePx);
             setCompoundDrawablePadding(grid.allAppsIconDrawablePaddingPx);
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 83ea067..0a346a6 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -32,6 +32,7 @@
 
 import com.android.launcher3.CellLayout.ContainerType;
 import com.android.launcher3.badge.BadgeRenderer;
+import com.android.launcher3.config.FeatureFlags;
 
 import java.util.ArrayList;
 
@@ -92,6 +93,7 @@
 
     public int cellWidthPx;
     public int cellHeightPx;
+    public int cellPaddingXPx;
 
     // Folder
     public int folderBackgroundOffset;
@@ -192,6 +194,8 @@
         workspaceSpringLoadedBottomSpace =
                 res.getDimensionPixelSize(R.dimen.dynamic_grid_min_spring_loaded_space);
 
+        cellPaddingXPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_padding_x);
+
         hotseatBarTopPaddingPx =
                 res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_top_padding);
         hotseatBarBottomPaddingPx =
@@ -264,36 +268,34 @@
     }
 
     private void updateAvailableDimensions(DisplayMetrics dm, Resources res) {
-        updateIconSize(1f, iconDrawablePaddingOriginalPx, res, dm);
+        updateIconSize(1f, res, dm);
 
         // Check to see if the icons fit within the available height.  If not, then scale down.
         float usedHeight = (cellHeightPx * inv.numRows);
         int maxHeight = (availableHeightPx - getTotalWorkspacePadding().y);
         if (usedHeight > maxHeight) {
             float scale = maxHeight / usedHeight;
-            updateIconSize(scale, 0, res, dm);
+            updateIconSize(scale, res, dm);
         }
-
         updateAvailableFolderCellDimensions(dm, res);
     }
 
-    private void updateIconSize(float scale, int drawablePadding, Resources res,
-                                DisplayMetrics dm) {
+    private void updateIconSize(float scale, Resources res, DisplayMetrics dm) {
         iconSizePx = (int) (Utilities.pxFromDp(inv.iconSize, dm) * scale);
         iconTextSizePx = (int) (Utilities.pxFromSp(inv.iconTextSize, dm) * scale);
-        iconDrawablePaddingPx = drawablePadding;
+        iconDrawablePaddingPx = (int) (iconDrawablePaddingOriginalPx * scale);
         hotseatIconSizePx = (int) (Utilities.pxFromDp(inv.hotseatIconSize, dm) * scale);
         allAppsIconSizePx = iconSizePx;
         allAppsIconDrawablePaddingPx = iconDrawablePaddingPx;
         allAppsIconTextSizePx = iconTextSizePx;
 
-        cellWidthPx = iconSizePx;
+        cellWidthPx = iconSizePx + iconDrawablePaddingPx;
         cellHeightPx = iconSizePx + iconDrawablePaddingPx
                 + Utilities.calculateTextHeight(iconTextSizePx);
 
         // Hotseat
-        hotseatCellWidthPx = iconSizePx;
-        hotseatCellHeightPx = iconSizePx;
+        hotseatCellWidthPx = cellWidthPx;
+        hotseatCellHeightPx = iconSizePx + iconDrawablePaddingPx;
 
         if (!isVerticalBarLayout()) {
             int expectedWorkspaceHeight = availableHeightPx - hotseatBarHeightPx
@@ -308,7 +310,7 @@
         }
 
         // Folder icon
-        folderBackgroundOffset = -edgeMarginPx;
+        folderBackgroundOffset = -iconDrawablePaddingPx;
         folderIconSizePx = iconSizePx + 2 * -folderBackgroundOffset;
         folderIconPreviewPadding = res.getDimensionPixelSize(R.dimen.folder_preview_padding);
     }
@@ -522,7 +524,7 @@
         lp = (FrameLayout.LayoutParams) searchBar.getLayoutParams();
         lp.width = searchBarBounds.x;
         lp.height = searchBarBounds.y;
-        lp.topMargin = mInsets.top + edgeMarginPx;
+        lp.topMargin = mInsets.top + edgeMarginPx / 2;
         searchBar.setLayoutParams(lp);
 
         // Layout the workspace
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index ad816af..09ca5c5 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -749,7 +749,7 @@
     }
 
     private static final class IconDB extends SQLiteCacheHelper {
-        private final static int DB_VERSION = 14;
+        private final static int DB_VERSION = 15;
 
         private final static int RELEASE_VERSION = DB_VERSION +
                 (FeatureFlags.LAUNCHER3_DISABLE_ICON_NORMALIZATION ? 0 : 1);
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index bd006c7..bb32a45 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -1413,7 +1413,6 @@
         BubbleTextView favorite = (BubbleTextView) LayoutInflater.from(parent.getContext())
                 .inflate(R.layout.app_icon, parent, false);
         favorite.applyFromShortcutInfo(info);
-        favorite.setCompoundDrawablePadding(mDeviceProfile.iconDrawablePaddingPx);
         favorite.setOnClickListener(this);
         favorite.setOnFocusChangeListener(mFocusHandler);
         return favorite;
diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
index f8742f8..3a3e13d 100644
--- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java
+++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
@@ -120,7 +120,7 @@
                 // Center the icon/folder
                 int cHeight = getCellContentHeight();
                 int cellPaddingY = (int) Math.max(0, ((lp.height - cHeight) / 2f));
-                int cellPaddingX = (int) (profile.edgeMarginPx / 2f);
+                int cellPaddingX = profile.cellPaddingXPx;
                 child.setPadding(cellPaddingX, cellPaddingY, cellPaddingX, 0);
             }
         } else {
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index f66995f..d421a0e 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -111,7 +111,7 @@
      * sizes (landscape vs portrait).
      */
     private static class CacheDb extends SQLiteCacheHelper {
-        private static final int DB_VERSION = 6;
+        private static final int DB_VERSION = 7;
 
         private static final String TABLE_NAME = "shortcut_and_widget_previews";
         private static final String COLUMN_COMPONENT = "componentName";
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 5794004..fc25c9a 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -60,7 +60,6 @@
 import com.android.launcher3.LogDecelerateInterpolator;
 import com.android.launcher3.OnAlarmListener;
 import com.android.launcher3.PagedView;
-import com.android.launcher3.PendingAddItemInfo;
 import com.android.launcher3.R;
 import com.android.launcher3.ShortcutInfo;
 import com.android.launcher3.UninstallDropTarget.DropTargetSource;
@@ -637,7 +636,9 @@
             @Override
             public void onAnimationStart(Animator animation) {
                 if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION) {
+                    mFolderIcon.setBackgroundVisible(false);
                     mFolderIcon.drawLeaveBehindIfExists();
+                } else {
                     mFolderIcon.setVisibility(INVISIBLE);
                 }
 
@@ -790,6 +791,7 @@
         mDragController.removeDropTarget(this);
         clearFocus();
         if (mFolderIcon != null) {
+            mFolderIcon.setBackgroundVisible(true);
             mFolderIcon.setVisibility(View.VISIBLE);
             if (wasAnimated) {
                 mFolderIcon.mBackground.animateBackgroundStroke();
diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java
index bee0bd4..bb2d1a2 100644
--- a/src/com/android/launcher3/folder/FolderAnimationManager.java
+++ b/src/com/android/launcher3/folder/FolderAnimationManager.java
@@ -208,6 +208,7 @@
         play(a, getAnimator(mFolder, SCALE_PROPERTY, initialScale, finalScale));
         play(a, getAnimator(items, ITEMS_TEXT_COLOR_PROPERTY, Color.TRANSPARENT, finalTextColor));
         play(a, getAnimator(mFolderBackground, "color", initialColor, finalColor));
+        play(a, mFolderIcon.mFolderName.createTextAlphaAnimator(!mIsOpening));
         play(a, new RoundedRectRevealOutlineProvider(initialRadius, finalRadius, startRect,
                 endRect).createRevealAnimator(mFolder, !mIsOpening));
 
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index 82a0733..aaa19af 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -120,6 +120,7 @@
     private int mPrevTopPadding = -1;
 
     PreviewBackground mBackground = new PreviewBackground();
+    private boolean mBackgroundIsVisible = true;
 
     private PreviewLayoutRule mPreviewLayoutRule;
 
@@ -883,10 +884,17 @@
         mBackground.setInvalidateDelegate(this);
     }
 
+    public void setBackgroundVisible(boolean visible) {
+        mBackgroundIsVisible = visible;
+        invalidate();
+    }
+
     @Override
     protected void dispatchDraw(Canvas canvas) {
         super.dispatchDraw(canvas);
 
+        if (!mBackgroundIsVisible) return;
+
         if (mReferenceDrawable != null) {
             computePreviewDrawingParams(mReferenceDrawable);
         }
diff --git a/src/com/android/launcher3/notification/NotificationItemView.java b/src/com/android/launcher3/notification/NotificationItemView.java
index cc81b11..0b08ef8 100644
--- a/src/com/android/launcher3/notification/NotificationItemView.java
+++ b/src/com/android/launcher3/notification/NotificationItemView.java
@@ -86,11 +86,16 @@
         return getHeight() - footerHeight;
     }
 
-    public Animator animateHeightRemoval(int heightToRemove) {
+    public Animator animateHeightRemoval(int heightToRemove, boolean shouldRemoveFromTop) {
+        Rect startRect = new Rect(mPillRect);
         Rect endRect = new Rect(mPillRect);
-        endRect.bottom -= heightToRemove;
+        if (shouldRemoveFromTop) {
+            endRect.top += heightToRemove;
+        } else {
+            endRect.bottom -= heightToRemove;
+        }
         return new RoundedRectRevealOutlineProvider(getBackgroundRadius(), getBackgroundRadius(),
-                mPillRect, endRect, mRoundedCorners).createRevealAnimator(this, false);
+                startRect, endRect, mRoundedCorners).createRevealAnimator(this, false);
     }
 
     public void updateHeader(int notificationCount, @Nullable IconPalette palette) {
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 293bab4..c5daca0 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -82,6 +82,7 @@
 import java.util.Map;
 import java.util.Set;
 
+import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS_IF_NOTIFICATIONS;
 import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 import static com.android.launcher3.userevent.nano.LauncherLogProto.ItemType;
 import static com.android.launcher3.userevent.nano.LauncherLogProto.Target;
@@ -191,7 +192,7 @@
         // Add dummy views first, and populate with real info when ready.
         PopupPopulator.Item[] itemsToPopulate = PopupPopulator
                 .getItemsToPopulate(shortcutIds, notificationKeys, systemShortcuts);
-        addDummyViews(itemsToPopulate, notificationKeys.size() > 1);
+        addDummyViews(itemsToPopulate, notificationKeys.size());
 
         measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
         orientAboutIcon(originalIcon, arrowHeight + arrowVerticalOffset);
@@ -202,7 +203,7 @@
             mNotificationItemView = null;
             mShortcutsItemView = null;
             itemsToPopulate = PopupPopulator.reverseItems(itemsToPopulate);
-            addDummyViews(itemsToPopulate, notificationKeys.size() > 1);
+            addDummyViews(itemsToPopulate, notificationKeys.size());
 
             measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
             orientAboutIcon(originalIcon, arrowHeight + arrowVerticalOffset);
@@ -252,8 +253,7 @@
                 systemShortcuts, systemShortcutViews));
     }
 
-    private void addDummyViews(PopupPopulator.Item[] itemTypesToPopulate,
-            boolean notificationFooterHasIcons) {
+    private void addDummyViews(PopupPopulator.Item[] itemTypesToPopulate, int numNotifications) {
         final Resources res = getResources();
         final LayoutInflater inflater = mLauncher.getLayoutInflater();
 
@@ -274,6 +274,7 @@
 
             if (itemTypeToPopulate == PopupPopulator.Item.NOTIFICATION) {
                 mNotificationItemView = (NotificationItemView) item;
+                boolean notificationFooterHasIcons = numNotifications > 1;
                 int footerHeight = notificationFooterHasIcons ?
                         res.getDimensionPixelSize(R.dimen.notification_footer_height) : 0;
                 item.findViewById(R.id.footer).getLayoutParams().height = footerHeight;
@@ -305,6 +306,12 @@
                         shortcutsItemRoundedCorners &= ~ROUNDED_TOP_CORNERS;
                     }
                 }
+                if (itemTypeToPopulate != PopupPopulator.Item.SYSTEM_SHORTCUT_ICON
+                        && numNotifications > 0) {
+                    // Condense shortcuts height when there are notifications.
+                    item.getLayoutParams().height = res.getDimensionPixelSize(
+                            R.dimen.bg_popup_item_condensed_height);
+                }
                 mShortcutsItemView.addShortcutView(item, itemTypeToPopulate);
                 if (shouldUnroundBottomCorners) {
                     shortcutsItemRoundedCorners &= ~ROUNDED_BOTTOM_CORNERS;
@@ -316,6 +323,9 @@
         int backgroundColor = Themes.getAttrColor(mLauncher, mNotificationItemView == null
                 ? R.attr.popupColorPrimary : R.attr.popupColorSecondary);
         mShortcutsItemView.setBackgroundWithCorners(backgroundColor, shortcutsItemRoundedCorners);
+        if (numNotifications > 0) {
+            mShortcutsItemView.hideShortcuts(mIsAboveIcon, MAX_SHORTCUTS_IF_NOTIFICATIONS);
+        }
     }
 
     protected PopupItemView getItemViewAt(int index) {
@@ -639,11 +649,22 @@
         ItemInfo originalInfo = (ItemInfo) mOriginalIcon.getTag();
         BadgeInfo badgeInfo = updatedBadges.get(PackageUserKey.fromItemInfo(originalInfo));
         if (badgeInfo == null || badgeInfo.getNotificationKeys().size() == 0) {
+            // There are no more notifications, so create an animation to remove
+            // the notifications view and expand the shortcuts view (if possible).
             AnimatorSet removeNotification = LauncherAnimUtils.createAnimatorSet();
+            int hiddenShortcutsHeight = 0;
+            if (mShortcutsItemView != null) {
+                hiddenShortcutsHeight = mShortcutsItemView.getHiddenShortcutsHeight();
+                int backgroundColor = Themes.getAttrColor(mLauncher, R.attr.popupColorPrimary);
+                // With notifications gone, all corners of shortcuts item should be rounded.
+                mShortcutsItemView.setBackgroundWithCorners(backgroundColor,
+                        ROUNDED_TOP_CORNERS | ROUNDED_BOTTOM_CORNERS);
+                removeNotification.play(mShortcutsItemView.showAllShortcuts(mIsAboveIcon));
+            }
             final int duration = getResources().getInteger(
                     R.integer.config_removeNotificationViewDuration);
-            removeNotification.play(reduceNotificationViewHeight(
-                    mNotificationItemView.getHeightMinusFooter(), duration));
+            removeNotification.play(adjustItemHeights(mNotificationItemView.getHeightMinusFooter(),
+                    hiddenShortcutsHeight, duration));
             Animator fade = ObjectAnimator.ofFloat(mNotificationItemView, ALPHA, 0)
                     .setDuration(duration);
             fade.addListener(new AnimatorListenerAdapter() {
@@ -665,12 +686,6 @@
             showArrow.setStartDelay((long) (duration - arrowScaleDuration * 1.5));
             removeNotification.playSequentially(hideArrow, showArrow);
             removeNotification.start();
-            if (mShortcutsItemView != null) {
-                int backgroundColor = Themes.getAttrColor(mLauncher, R.attr.popupColorPrimary);
-                // With notifications gone, all corners of shortcuts item should be rounded.
-                mShortcutsItemView.setBackgroundWithCorners(backgroundColor,
-                        ROUNDED_TOP_CORNERS | ROUNDED_BOTTOM_CORNERS);
-            }
             return;
         }
         mNotificationItemView.trimNotifications(NotificationKeyData.extractKeysOnly(
@@ -689,28 +704,50 @@
                 mArrow, new PropertyListBuilder().scale(scale).build());
     }
 
+    public Animator reduceNotificationViewHeight(int heightToRemove, int duration) {
+        return adjustItemHeights(heightToRemove, 0, duration);
+    }
+
     /**
      * Animates the height of the notification item and the translationY of other items accordingly.
      */
-    public Animator reduceNotificationViewHeight(int heightToRemove, int duration) {
+    public Animator adjustItemHeights(int notificationHeightToRemove, int shortcutHeightToAdd,
+            int duration) {
         if (mReduceHeightAnimatorSet != null) {
             mReduceHeightAnimatorSet.cancel();
         }
-        final int translateYBy = mIsAboveIcon ? heightToRemove : -heightToRemove;
+        final int translateYBy = mIsAboveIcon ? notificationHeightToRemove - shortcutHeightToAdd
+                : -notificationHeightToRemove;
         mReduceHeightAnimatorSet = LauncherAnimUtils.createAnimatorSet();
-        mReduceHeightAnimatorSet.play(mNotificationItemView.animateHeightRemoval(heightToRemove));
+        boolean removingNotification =
+                notificationHeightToRemove == mNotificationItemView.getHeightMinusFooter();
+        boolean shouldRemoveNotificationHeightFromTop = mIsAboveIcon && removingNotification;
+        mReduceHeightAnimatorSet.play(mNotificationItemView.animateHeightRemoval(
+                notificationHeightToRemove, shouldRemoveNotificationHeightFromTop));
         PropertyResetListener<View, Float> resetTranslationYListener
                 = new PropertyResetListener<>(TRANSLATION_Y, 0f);
+        boolean itemIsAfterShortcuts = false;
         for (int i = 0; i < getItemCount(); i++) {
             final PopupItemView itemView = getItemViewAt(i);
-            if (!mIsAboveIcon && itemView == mNotificationItemView) {
-                // The notification view is already in the right place when container is below icon.
+            if (itemIsAfterShortcuts) {
+                // Every item after the shortcuts item needs to adjust for the new height.
+                itemView.setTranslationY(itemView.getTranslationY() - shortcutHeightToAdd);
+            }
+            if (itemView == mNotificationItemView && (!mIsAboveIcon || removingNotification)) {
+                // The notification view is already in the right place.
                 continue;
             }
             ValueAnimator translateItem = ObjectAnimator.ofFloat(itemView, TRANSLATION_Y,
                     itemView.getTranslationY() + translateYBy).setDuration(duration);
             translateItem.addListener(resetTranslationYListener);
             mReduceHeightAnimatorSet.play(translateItem);
+            if (itemView == mShortcutsItemView) {
+                itemIsAfterShortcuts = true;
+            }
+        }
+        if (mIsAboveIcon) {
+            // We also need to adjust the arrow position to account for the new shortcuts height.
+            mArrow.setTranslationY(mArrow.getTranslationY() - shortcutHeightToAdd);
         }
         mReduceHeightAnimatorSet.addListener(new AnimatorListenerAdapter() {
             @Override
@@ -720,6 +757,7 @@
                     // container itself did not. This means the items would jump back to their
                     // original translation unless we update the container's translationY here.
                     setTranslationY(getTranslationY() + translateYBy);
+                    mArrow.setTranslationY(0);
                 }
                 mReduceHeightAnimatorSet = null;
             }
diff --git a/src/com/android/launcher3/popup/PopupPopulator.java b/src/com/android/launcher3/popup/PopupPopulator.java
index fd00105..0dc1ca0 100644
--- a/src/com/android/launcher3/popup/PopupPopulator.java
+++ b/src/com/android/launcher3/popup/PopupPopulator.java
@@ -52,9 +52,9 @@
  */
 public class PopupPopulator {
 
-    public static final int MAX_ITEMS = 4;
+    public static final int MAX_SHORTCUTS = 4;
     @VisibleForTesting static final int NUM_DYNAMIC = 2;
-    private static final int MAX_SHORTCUTS_IF_NOTIFICATIONS = 2;
+    public static final int MAX_SHORTCUTS_IF_NOTIFICATIONS = 2;
 
     public enum Item {
         SHORTCUT(R.layout.deep_shortcut, true),
@@ -77,10 +77,7 @@
         boolean hasNotifications = notificationKeys.size() > 0;
         int numNotificationItems = hasNotifications ? 1 : 0;
         int numShortcuts = shortcutIds.size();
-        if (hasNotifications && numShortcuts > MAX_SHORTCUTS_IF_NOTIFICATIONS) {
-            numShortcuts = MAX_SHORTCUTS_IF_NOTIFICATIONS;
-        }
-        int numItems = Math.min(MAX_ITEMS, numShortcuts + numNotificationItems)
+        int numItems = Math.min(MAX_SHORTCUTS, numShortcuts) + numNotificationItems
                 + systemShortcuts.size();
         Item[] items = new Item[numItems];
         for (int i = 0; i < numItems; i++) {
@@ -126,12 +123,12 @@
     };
 
     /**
-     * Filters the shortcuts so that only MAX_ITEMS or fewer shortcuts are retained.
+     * Filters the shortcuts so that only MAX_SHORTCUTS or fewer shortcuts are retained.
      * 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_ITEMS.
+     * @return a subset of shortcuts, in sorted order, with size <= MAX_SHORTCUTS.
      */
     public static List<ShortcutInfoCompat> sortAndFilterShortcuts(
             List<ShortcutInfoCompat> shortcuts, @Nullable String shortcutIdToRemoveFirst) {
@@ -147,27 +144,27 @@
         }
 
         Collections.sort(shortcuts, SHORTCUT_RANK_COMPARATOR);
-        if (shortcuts.size() <= MAX_ITEMS) {
+        if (shortcuts.size() <= MAX_SHORTCUTS) {
             return shortcuts;
         }
 
         // The list of shortcuts is now sorted with static shortcuts followed by dynamic
-        // shortcuts. We want to preserve this order, but only keep MAX_ITEMS.
-        List<ShortcutInfoCompat> filteredShortcuts = new ArrayList<>(MAX_ITEMS);
+        // shortcuts. We want to preserve this order, but only keep MAX_SHORTCUTS.
+        List<ShortcutInfoCompat> filteredShortcuts = new ArrayList<>(MAX_SHORTCUTS);
         int numDynamic = 0;
         int size = shortcuts.size();
         for (int i = 0; i < size; i++) {
             ShortcutInfoCompat shortcut = shortcuts.get(i);
             int filteredSize = filteredShortcuts.size();
-            if (filteredSize < MAX_ITEMS) {
-                // Always add the first MAX_ITEMS to the filtered list.
+            if (filteredSize < MAX_SHORTCUTS) {
+                // Always add the first MAX_SHORTCUTS to the filtered list.
                 filteredShortcuts.add(shortcut);
                 if (shortcut.isDynamic()) {
                     numDynamic++;
                 }
                 continue;
             }
-            // At this point, we have MAX_ITEMS already, but they may all be static.
+            // At this point, we have MAX_SHORTCUTS already, but they may all be static.
             // If there are dynamic shortcuts, remove static shortcuts to add them.
             if (shortcut.isDynamic() && numDynamic < NUM_DYNAMIC) {
                 numDynamic++;
diff --git a/src/com/android/launcher3/shortcuts/ShortcutsItemView.java b/src/com/android/launcher3/shortcuts/ShortcutsItemView.java
index 340a6f0..59a0386 100644
--- a/src/com/android/launcher3/shortcuts/ShortcutsItemView.java
+++ b/src/com/android/launcher3/shortcuts/ShortcutsItemView.java
@@ -16,9 +16,14 @@
 
 package com.android.launcher3.shortcuts;
 
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.graphics.Point;
+import android.graphics.Rect;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
@@ -28,7 +33,9 @@
 import com.android.launcher3.BubbleTextView;
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAnimUtils;
 import com.android.launcher3.R;
+import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
 import com.android.launcher3.dragndrop.DragOptions;
 import com.android.launcher3.dragndrop.DragView;
 import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider;
@@ -49,7 +56,10 @@
 public class ShortcutsItemView extends PopupItemView implements View.OnLongClickListener,
         View.OnTouchListener, LogContainerProvider {
 
+    private static final String TAG = "ShortcutsItem";
+
     private Launcher mLauncher;
+    private LinearLayout mContent;
     private LinearLayout mShortcutsLayout;
     private LinearLayout mSystemShortcutIcons;
     private final Point mIconShift = new Point();
@@ -57,6 +67,8 @@
     private final List<DeepShortcutView> mDeepShortcutViews = new ArrayList<>();
     private final List<View> mSystemShortcutViews = new ArrayList<>();
 
+    private int mHiddenShortcutsHeight;
+
     public ShortcutsItemView(Context context) {
         this(context, null, 0);
     }
@@ -74,7 +86,8 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mShortcutsLayout = findViewById(R.id.deep_shortcuts);
+        mContent = findViewById(R.id.content);
+        mShortcutsLayout = findViewById(R.id.shortcuts);
     }
 
     @Override
@@ -130,17 +143,18 @@
             // System shortcut icons are added to a header that is separate from the full shortcuts.
             if (mSystemShortcutIcons == null) {
                 mSystemShortcutIcons = (LinearLayout) mLauncher.getLayoutInflater().inflate(
-                        R.layout.system_shortcut_icons, mShortcutsLayout, false);
+                        R.layout.system_shortcut_icons, mContent, false);
 
                 View divider = LayoutInflater.from(getContext()).inflate(
                         R.layout.horizontal_divider, this, false);
 
-                if (mShortcutsLayout.getChildCount() > 0) {
-                    mShortcutsLayout.addView(divider);
-                }
-                mShortcutsLayout.addView(mSystemShortcutIcons);
-                if (mShortcutsLayout.getChildCount() == 1) {
-                    mShortcutsLayout.addView(divider);
+                boolean iconsAreBelowShortcuts = mShortcutsLayout.getChildCount() > 0;
+                if (iconsAreBelowShortcuts) {
+                    mContent.addView(divider);
+                    mContent.addView(mSystemShortcutIcons);
+                } else {
+                    mContent.addView(divider, 0);
+                    mContent.addView(mSystemShortcutIcons, 0);
                 }
             }
             mSystemShortcutIcons.addView(shortcutView, index);
@@ -172,6 +186,114 @@
     }
 
     /**
+     * Hides shortcuts until only {@param maxShortcuts} are showing. Also sets
+     * {@link #mHiddenShortcutsHeight} to be the amount of extra space that shortcuts will
+     * require when {@link #showAllShortcuts(boolean)} is called.
+     */
+    public void hideShortcuts(boolean hideFromTop, int maxShortcuts) {
+        // When shortcuts are shown, they get more space allocated to them.
+        final int oldHeight = mShortcutsLayout.getChildAt(0).getLayoutParams().height;
+        final int newHeight = getResources().getDimensionPixelSize(R.dimen.bg_popup_item_height);
+        mHiddenShortcutsHeight = (newHeight - oldHeight) * mShortcutsLayout.getChildCount();
+
+        int numToHide = mShortcutsLayout.getChildCount() - maxShortcuts;
+        if (numToHide <= 0) {
+            return;
+        }
+        final int numShortcuts = mShortcutsLayout.getChildCount();
+        final int dir = hideFromTop ? 1 : -1;
+        for (int i = hideFromTop ? 0 : numShortcuts - 1; 0 <= i && i < numShortcuts; i += dir) {
+            View child = mShortcutsLayout.getChildAt(i);
+            if (child instanceof DeepShortcutView) {
+                mHiddenShortcutsHeight += child.getLayoutParams().height;
+                child.setVisibility(GONE);
+                int prev = i + dir;
+                if (!hideFromTop && 0 <= prev && prev < numShortcuts) {
+                    // When hiding views from the bottom, make sure to hide the last divider.
+                    mShortcutsLayout.getChildAt(prev).findViewById(R.id.divider).setVisibility(GONE);
+                }
+                numToHide--;
+                if (numToHide == 0) {
+                    break;
+                }
+            }
+        }
+    }
+
+    public int getHiddenShortcutsHeight() {
+        return mHiddenShortcutsHeight;
+    }
+
+    /**
+     * Sets all shortcuts in {@link #mShortcutsLayout} to VISIBLE, then creates an
+     * animation to reveal the newly shown shortcuts.
+     *
+     * @see #hideShortcuts(boolean, int)
+     */
+    public Animator showAllShortcuts(boolean showFromTop) {
+        // First set all the shortcuts to VISIBLE.
+        final int numShortcuts = mShortcutsLayout.getChildCount();
+        if (numShortcuts == 0) {
+            Log.w(TAG, "Tried to show all shortcuts but there were no shortcuts to show");
+            return null;
+        }
+        final int oldHeight = mShortcutsLayout.getChildAt(0).getLayoutParams().height;
+        final int newHeight = getResources().getDimensionPixelSize(R.dimen.bg_popup_item_height);
+        for (int i = 0; i < numShortcuts; i++) {
+            DeepShortcutView view = (DeepShortcutView) mShortcutsLayout.getChildAt(i);
+            view.getLayoutParams().height = newHeight;
+            view.requestLayout();
+            view.setVisibility(VISIBLE);
+            if (i < numShortcuts - 1) {
+                view.findViewById(R.id.divider).setVisibility(VISIBLE);
+            }
+        }
+
+        // Now reveal the newly shown shortcuts.
+        AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
+
+        if (showFromTop) {
+            // The new shortcuts pushed the original shortcuts down, but we want to animate them
+            // to that position. So we revert the translation and animate to the new.
+            animation.play(translateYFrom(mShortcutsLayout, -mHiddenShortcutsHeight));
+        } else if (mSystemShortcutIcons != null) {
+            // When adding the shortcuts from the bottom, things are a little trickier, since
+            // that means they push the icons header down. To account for this, we do the same
+            // translation trick as above, but on the header. Since this means leaving behind
+            // a blank area where the header was, we also need to clip the background.
+            animation.play(translateYFrom(mSystemShortcutIcons, -mHiddenShortcutsHeight));
+            // mPillRect is the bounds of this view before the new shortcuts were shown.
+            Rect backgroundStartRect = new Rect(mPillRect);
+            Rect backgroundEndRect = new Rect(mPillRect);
+            backgroundEndRect.bottom += mHiddenShortcutsHeight;
+            animation.play(new RoundedRectRevealOutlineProvider(getBackgroundRadius(),
+                    getBackgroundRadius(), backgroundStartRect, backgroundEndRect, mRoundedCorners)
+                    .createRevealAnimator(this, false));
+        }
+        for (int i = 0; i < numShortcuts; i++) {
+            // Animate each shortcut to its new height.
+            DeepShortcutView shortcut = (DeepShortcutView) mShortcutsLayout.getChildAt(i);
+            int heightDiff = newHeight - oldHeight;
+            int heightAdjustmentIndex = showFromTop ? numShortcuts - i - 1 : i;
+            int fromDir = showFromTop ? 1 : -1;
+            animation.play(translateYFrom(shortcut, heightDiff * heightAdjustmentIndex * fromDir));
+            // Make sure the text and icon stay centered in the shortcut.
+            animation.play(translateYFrom(shortcut.getBubbleText(), heightDiff / 2 * fromDir));
+            animation.play(translateYFrom(shortcut.getIconView(), heightDiff / 2 * fromDir));
+        }
+        return animation;
+    }
+
+    /**
+     * Animates the translationY of the view from the given offset to the view's current translation
+     * @return an Animator, which should be started by the caller.
+     */
+    private Animator translateYFrom(View v, int diff) {
+        float finalY = v.getTranslationY();
+        return ObjectAnimator.ofFloat(v, TRANSLATION_Y, finalY + diff, finalY);
+    }
+
+    /**
      * Adds a {@link SystemShortcut.Widgets} item if there are widgets for the given ItemInfo.
      */
     public void enableWidgetsIfExist(final BubbleTextView originalIcon) {
diff --git a/tests/src/com/android/launcher3/popup/PopupPopulatorTest.java b/tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
index 2ad9b35..9a89b1b 100644
--- a/tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
+++ b/tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
@@ -28,7 +28,7 @@
 import java.util.Collections;
 import java.util.List;
 
-import static com.android.launcher3.popup.PopupPopulator.MAX_ITEMS;
+import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS;
 import static com.android.launcher3.popup.PopupPopulator.NUM_DYNAMIC;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -44,18 +44,18 @@
     public void testSortAndFilterShortcuts() {
         filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(3, 0), 3, 0);
         filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(0, 3), 0, 3);
-        filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(5, 0), MAX_ITEMS, 0);
-        filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(0, 5), 0, MAX_ITEMS);
+        filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(5, 0), MAX_SHORTCUTS, 0);
+        filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(0, 5), 0, MAX_SHORTCUTS);
         filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(3, 3),
-                MAX_ITEMS - NUM_DYNAMIC, NUM_DYNAMIC);
+                MAX_SHORTCUTS - NUM_DYNAMIC, NUM_DYNAMIC);
         filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(5, 5),
-                MAX_ITEMS - NUM_DYNAMIC, NUM_DYNAMIC);
-        filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(5, 1), MAX_ITEMS - 1, 1);
-        filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(1, 5), 1, MAX_ITEMS - 1);
+                MAX_SHORTCUTS - NUM_DYNAMIC, NUM_DYNAMIC);
+        filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(5, 1), MAX_SHORTCUTS - 1, 1);
+        filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(1, 5), 1, MAX_SHORTCUTS - 1);
         filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(5, 3),
-                MAX_ITEMS - NUM_DYNAMIC, NUM_DYNAMIC);
+                MAX_SHORTCUTS - NUM_DYNAMIC, NUM_DYNAMIC);
         filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(3, 5),
-                MAX_ITEMS - NUM_DYNAMIC, NUM_DYNAMIC);
+                MAX_SHORTCUTS - NUM_DYNAMIC, NUM_DYNAMIC);
     }
 
     @Test