Merge "Ignore clicks on notifications that don't have intents." into ub-launcher3-dorval-polish2
diff --git a/res/layout/notification.xml b/res/layout/notification.xml
index 4a02aa1..1eebb43 100644
--- a/res/layout/notification.xml
+++ b/res/layout/notification.xml
@@ -49,7 +49,7 @@
                 android:layout_width="wrap_content"
                 android:layout_height="match_parent"
                 android:layout_gravity="start"
-                android:gravity="bottom"
+                android:gravity="center_vertical"
                 android:text="@string/notifications_header"
                 android:textSize="@dimen/notification_header_text_size"
                 android:textColor="?android:attr/textColorPrimary" />
@@ -58,7 +58,7 @@
                 android:layout_width="@dimen/notification_icon_size"
                 android:layout_height="match_parent"
                 android:layout_gravity="end"
-                android:gravity="bottom|center_horizontal"
+                android:gravity="center"
                 android:textSize="@dimen/notification_header_count_text_size"
                 android:fontFamily="sans-serif-medium"
                 android:textColor="?android:attr/textColorPrimary" />
diff --git a/res/layout/notification_main.xml b/res/layout/notification_main.xml
index f681e8b..f94face 100644
--- a/res/layout/notification_main.xml
+++ b/res/layout/notification_main.xml
@@ -31,7 +31,7 @@
         android:background="?attr/popupColorPrimary"
         android:paddingStart="@dimen/notification_padding_start"
         android:paddingEnd="@dimen/notification_main_text_padding_end"
-        android:paddingBottom="16dp">
+        android:paddingBottom="14dp">
         <TextView
             android:id="@+id/title"
             android:layout_width="match_parent"
@@ -59,7 +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_marginBottom="7dp"
         android:layout_gravity="center_vertical|end" />
 
 </com.android.launcher3.notification.NotificationMainView>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 3f6efd7..b1f9d63 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -214,9 +214,11 @@
     <dimen name="notification_padding_end">12dp</dimen>
     <!-- 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">96dp</dimen>
+    <dimen name="notification_header_height">36dp</dimen>
+    <dimen name="notification_main_height">84dp</dimen>
     <dimen name="notification_footer_height">32dp</dimen>
+    <!-- How much space to keep as padding for the last notification when the footer collapses -->
+    <dimen name="notification_empty_footer_height">6dp</dimen>
     <dimen name="notification_header_text_size">13sp</dimen>
     <dimen name="notification_header_count_text_size">12sp</dimen>
     <dimen name="notification_main_title_size">16sp</dimen>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 5d06705..8129e81 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -62,7 +62,7 @@
         <item name="android:textColorHint">#A0FFFFFF</item>
         <item name="android:colorControlHighlight">#A0FFFFFF</item>
         <item name="android:colorPrimary">#FF333333</item>
-        <item name="allAppsScrimColor">#7A000000</item>
+        <item name="allAppsScrimColor">#7A212121</item>
         <item name="allAppsNavBarScrimColor">#80000000</item>
         <item name="popupColorPrimary">?android:attr/colorPrimary</item>
         <item name="popupColorSecondary">#424242</item> <!-- Gray 800 -->
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index af3abeb..a6d80e3 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -149,7 +149,6 @@
             allAppsButton.setOnKeyListener(new HotseatIconKeyEventListener());
             if (mLauncher != null) {
                 mLauncher.setAllAppsButton(allAppsButton);
-                allAppsButton.setOnTouchListener(mLauncher.getHapticFeedbackTouchListener());
                 allAppsButton.setOnClickListener(mLauncher);
                 allAppsButton.setOnFocusChangeListener(mLauncher.mFocusHandler);
             }
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index 6f86954..573e8a2 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -123,7 +123,7 @@
     }
 
     private Drawable getFullResDefaultActivityIcon() {
-        return getFullResIcon(Resources.getSystem(), Utilities.isAtLeastO() ?
+        return getFullResIcon(Resources.getSystem(), Utilities.ATLEAST_OREO ?
                 android.R.drawable.sym_def_app_icon : android.R.mipmap.sym_def_app_icon);
     }
 
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 60d2e81..1e12b42 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -279,8 +279,6 @@
 
     private PopupDataProvider mPopupDataProvider;
 
-    private View.OnTouchListener mHapticFeedbackTouchListener;
-
     // Determines how long to wait after a rotation before restoring the screen orientation to
     // match the sensor state.
     private static final int RESTORE_SCREEN_ORIENTATION_DELAY = 500;
@@ -1132,7 +1130,7 @@
             // On O and above we there is always some setting present settings (add icon to
             // home screen or icon badging). On earlier APIs we will have the allow rotation
             // setting, on devices with a locked orientation,
-            return Utilities.isAtLeastO() || !getResources().getBoolean(R.bool.allow_rotation);
+            return Utilities.ATLEAST_OREO || !getResources().getBoolean(R.bool.allow_rotation);
         }
     }
 
@@ -1326,7 +1324,6 @@
                 onClickWallpaperPicker(view);
             }
         }.attachTo(wallpaperButton);
-        wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());
 
         // Bind widget button actions
         mWidgetsButton = findViewById(R.id.widget_button);
@@ -1336,7 +1333,6 @@
                 onClickAddWidgetButton(view);
             }
         }.attachTo(mWidgetsButton);
-        mWidgetsButton.setOnTouchListener(getHapticFeedbackTouchListener());
 
         // Bind settings actions
         View settingsButton = findViewById(R.id.settings_button);
@@ -1348,7 +1344,6 @@
                     onClickSettingsButton(view);
                 }
             }.attachTo(settingsButton);
-            settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());
         } else {
             settingsButton.setVisibility(View.GONE);
         }
@@ -1414,7 +1409,7 @@
         CellLayout layout = getCellLayout(container, screenId);
 
         ShortcutInfo info = null;
-        if (Utilities.isAtLeastO()) {
+        if (Utilities.ATLEAST_OREO) {
             info = LauncherAppsCompatVO.createShortcutInfoFromPinItemRequest(
                     this, LauncherAppsCompatVO.getPinItemRequest(data), 0);
         }
@@ -2533,22 +2528,6 @@
         startActivity(intent, getActivityLaunchOptions(v));
     }
 
-    public View.OnTouchListener getHapticFeedbackTouchListener() {
-        if (mHapticFeedbackTouchListener == null) {
-            mHapticFeedbackTouchListener = new View.OnTouchListener() {
-                @SuppressLint("ClickableViewAccessibility")
-                @Override
-                public boolean onTouch(View v, MotionEvent event) {
-                    if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {
-                        v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
-                    }
-                    return false;
-                }
-            };
-        }
-        return mHapticFeedbackTouchListener;
-    }
-
     @Override
     public void onAccessibilityStateChanged(boolean enabled) {
         mDragLayer.onAccessibilityStateChanged(enabled);
diff --git a/src/com/android/launcher3/LauncherAppWidgetHostView.java b/src/com/android/launcher3/LauncherAppWidgetHostView.java
index c7b7782..b65b74e 100644
--- a/src/com/android/launcher3/LauncherAppWidgetHostView.java
+++ b/src/com/android/launcher3/LauncherAppWidgetHostView.java
@@ -92,7 +92,7 @@
         setAccessibilityDelegate(Launcher.getLauncher(context).getAccessibilityDelegate());
         setBackgroundResource(R.drawable.widget_internal_focus_bg);
 
-        if (Utilities.isAtLeastO()) {
+        if (Utilities.ATLEAST_OREO) {
             setExecutor(Utilities.THREAD_POOL_EXECUTOR);
         }
     }
diff --git a/src/com/android/launcher3/SessionCommitReceiver.java b/src/com/android/launcher3/SessionCommitReceiver.java
index 8caba75..edb7ff5 100644
--- a/src/com/android/launcher3/SessionCommitReceiver.java
+++ b/src/com/android/launcher3/SessionCommitReceiver.java
@@ -59,7 +59,7 @@
 
     @Override
     public void onReceive(Context context, Intent intent) {
-        if (!isEnabled(context) || !Utilities.isAtLeastO()) {
+        if (!isEnabled(context) || !Utilities.ATLEAST_OREO) {
             // User has decided to not add icons on homescreen.
             return;
         }
@@ -92,7 +92,7 @@
     }
 
     public static void applyDefaultUserPrefs(final Context context) {
-        if (!Utilities.isAtLeastO()) {
+        if (!Utilities.ATLEAST_OREO) {
             return;
         }
         SharedPreferences prefs = Utilities.getPrefs(context);
diff --git a/src/com/android/launcher3/SettingsActivity.java b/src/com/android/launcher3/SettingsActivity.java
index 5bdc1f5..d40ac8f 100644
--- a/src/com/android/launcher3/SettingsActivity.java
+++ b/src/com/android/launcher3/SettingsActivity.java
@@ -94,7 +94,7 @@
 
             ButtonPreference iconBadgingPref =
                     (ButtonPreference) findPreference(ICON_BADGING_PREFERENCE_KEY);
-            if (!Utilities.isAtLeastO()) {
+            if (!Utilities.ATLEAST_OREO) {
                 getPreferenceScreen().removePreference(
                         findPreference(SessionCommitReceiver.ADD_ICON_PREFERENCE_KEY));
                 getPreferenceScreen().removePreference(iconBadgingPref);
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 3aa2db0..b6876f6 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -83,15 +83,17 @@
     private static final Matrix sMatrix = new Matrix();
     private static final Matrix sInverseMatrix = new Matrix();
 
-    public static boolean isAtLeastO() {
-        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
-    }
+    public static final boolean ATLEAST_OREO_MR1 =
+            Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1;
+
+    public static final boolean ATLEAST_OREO =
+            Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
 
     public static final boolean ATLEAST_NOUGAT_MR1 =
-        Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1;
+            Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1;
 
     public static final boolean ATLEAST_NOUGAT =
-        Build.VERSION.SDK_INT >= Build.VERSION_CODES.N;
+            Build.VERSION.SDK_INT >= Build.VERSION_CODES.N;
 
     public static final boolean ATLEAST_MARSHMALLOW =
             Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
diff --git a/src/com/android/launcher3/compat/AppWidgetManagerCompat.java b/src/com/android/launcher3/compat/AppWidgetManagerCompat.java
index 4e00eae..a77a87f 100644
--- a/src/com/android/launcher3/compat/AppWidgetManagerCompat.java
+++ b/src/com/android/launcher3/compat/AppWidgetManagerCompat.java
@@ -40,7 +40,7 @@
     public static AppWidgetManagerCompat getInstance(Context context) {
         synchronized (sInstanceLock) {
             if (sInstance == null) {
-                if (Utilities.isAtLeastO()) {
+                if (Utilities.ATLEAST_OREO) {
                     sInstance = new AppWidgetManagerCompatVO(context.getApplicationContext());
                 } else {
                     sInstance = new AppWidgetManagerCompatVL(context.getApplicationContext());
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompat.java b/src/com/android/launcher3/compat/LauncherAppsCompat.java
index 75a2a5d..2cac536 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompat.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompat.java
@@ -53,7 +53,7 @@
     public static LauncherAppsCompat getInstance(Context context) {
         synchronized (sInstanceLock) {
             if (sInstance == null) {
-                if (Utilities.isAtLeastO()) {
+                if (Utilities.ATLEAST_OREO) {
                     sInstance = new LauncherAppsCompatVO(context.getApplicationContext());
                 } else {
                     sInstance = new LauncherAppsCompatVL(context.getApplicationContext());
diff --git a/src/com/android/launcher3/compat/WallpaperManagerCompat.java b/src/com/android/launcher3/compat/WallpaperManagerCompat.java
index cbcabdf..00258c7 100644
--- a/src/com/android/launcher3/compat/WallpaperManagerCompat.java
+++ b/src/com/android/launcher3/compat/WallpaperManagerCompat.java
@@ -31,10 +31,10 @@
             if (sInstance == null) {
                 context = context.getApplicationContext();
 
-                if (Utilities.isAtLeastO()) {
+                if (Utilities.ATLEAST_OREO) {
                     try {
                         sInstance = new WallpaperManagerCompatVOMR1(context);
-                    } catch (Exception e) {
+                    } catch (Throwable e) {
                         // The wallpaper APIs do not yet exist
                     }
                 }
diff --git a/src/com/android/launcher3/compat/WallpaperManagerCompatVOMR1.java b/src/com/android/launcher3/compat/WallpaperManagerCompatVOMR1.java
index fe5ff2a..524f266 100644
--- a/src/com/android/launcher3/compat/WallpaperManagerCompatVOMR1.java
+++ b/src/com/android/launcher3/compat/WallpaperManagerCompatVOMR1.java
@@ -16,96 +16,70 @@
 package com.android.launcher3.compat;
 
 import android.annotation.TargetApi;
+import android.app.WallpaperColors;
 import android.app.WallpaperManager;
+import android.app.WallpaperManager.OnColorsChangedListener;
 import android.content.Context;
 import android.graphics.Color;
-import android.os.Build;
-import android.os.Handler;
 import android.support.annotation.Nullable;
 import android.util.Log;
 
-import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
 
-@TargetApi(Build.VERSION_CODES.O)
+
+@TargetApi(27)
 public class WallpaperManagerCompatVOMR1 extends WallpaperManagerCompat {
 
     private static final String TAG = "WMCompatVOMR1";
 
     private final WallpaperManager mWm;
+    private Method mWCColorHintsMethod;
 
-    private final Class mOCLClass;
-    private final Method mAddOCLMethod;
-
-    private final Method mWCGetMethod;
-    private final Method mWCGetPrimaryColorMethod;
-    private final Method mWCGetSecondaryColorMethod;
-    private final Method mWCGetTertiaryColorMethod;
-    private final Method mWCColorHintsMethod;
-
-    WallpaperManagerCompatVOMR1(Context context) throws Exception {
+    WallpaperManagerCompatVOMR1(Context context) throws Throwable {
         mWm = context.getSystemService(WallpaperManager.class);
-
-        mOCLClass = Class.forName("android.app.WallpaperManager$OnColorsChangedListener");
-        mAddOCLMethod = WallpaperManager.class.getDeclaredMethod(
-                "addOnColorsChangedListener", mOCLClass, Handler.class);
-        mWCGetMethod = WallpaperManager.class.getDeclaredMethod("getWallpaperColors", int.class);
-        Class wallpaperColorsClass = mWCGetMethod.getReturnType();
-        mWCGetPrimaryColorMethod = wallpaperColorsClass.getDeclaredMethod("getPrimaryColor");
-        mWCGetSecondaryColorMethod = wallpaperColorsClass.getDeclaredMethod("getSecondaryColor");
-        mWCGetTertiaryColorMethod = wallpaperColorsClass.getDeclaredMethod("getTertiaryColor");
-        mWCColorHintsMethod = wallpaperColorsClass.getDeclaredMethod("getColorHints");
+        String className = WallpaperColors.class.getName();
+        try {
+            mWCColorHintsMethod = WallpaperColors.class.getDeclaredMethod("getColorHints");
+        } catch (Exception exc) {
+            Log.e(TAG, "getColorHints not available", exc);
+        }
     }
 
     @Nullable
     @Override
     public WallpaperColorsCompat getWallpaperColors(int which) {
-        try {
-            return convertColorsObject(mWCGetMethod.invoke(mWm, which));
-        } catch (Exception e) {
-            Log.e(TAG, "Error calling wallpaper API", e);
-            return null;
-        }
+        return convertColorsObject(mWm.getWallpaperColors(which));
     }
 
     @Override
     public void addOnColorsChangedListener(final OnColorsChangedListenerCompat listener) {
-        Object onChangeListener = Proxy.newProxyInstance(
-                WallpaperManager.class.getClassLoader(),
-                new Class[]{mOCLClass},
-                new InvocationHandler() {
-                    @Override
-                    public Object invoke(Object o, Method method, Object[] objects)
-                            throws Throwable {
-                        String methodName = method.getName();
-                        if ("onColorsChanged".equals(methodName)) {
-                            listener.onColorsChanged(
-                                    convertColorsObject(objects[0]), (Integer) objects[1]);
-                        } else if ("toString".equals(methodName)) {
-                            return listener.toString();
-                        }
-                        return null;
-                    }
-                });
-        try {
-            mAddOCLMethod.invoke(mWm, onChangeListener, null);
-        } catch (Exception e) {
-            Log.e(TAG, "Error calling wallpaper API", e);
-        }
+        OnColorsChangedListener onChangeListener = new OnColorsChangedListener() {
+            @Override
+            public void onColorsChanged(WallpaperColors colors, int which) {
+                listener.onColorsChanged(convertColorsObject(colors), which);
+            }
+        };
+        mWm.addOnColorsChangedListener(onChangeListener, null);
     }
 
-    private WallpaperColorsCompat convertColorsObject(Object colors) throws Exception {
+    private WallpaperColorsCompat convertColorsObject(WallpaperColors colors) {
         if (colors == null) {
             return null;
         }
-        Color primary = (Color) mWCGetPrimaryColorMethod.invoke(colors);
-        Color secondary = (Color) mWCGetSecondaryColorMethod.invoke(colors);
-        Color tertiary = (Color) mWCGetTertiaryColorMethod.invoke(colors);
+        Color primary = colors.getPrimaryColor();
+        Color secondary = colors.getSecondaryColor();
+        Color tertiary = colors.getTertiaryColor();
         int primaryVal = primary != null ? primary.toArgb() : 0;
         int secondaryVal = secondary != null ? secondary.toArgb() : 0;
         int tertiaryVal = tertiary != null ? tertiary.toArgb() : 0;
-        int colorHints = (Integer) mWCColorHintsMethod.invoke(colors);
+        int colorHints = 0;
+        try {
+            if (mWCColorHintsMethod != null) {
+                colorHints = (Integer) mWCColorHintsMethod.invoke(colors);
+            }
+        } catch (Exception exc) {
+            Log.e(TAG, "error calling color hints", exc);
+        }
         return new WallpaperColorsCompat(primaryVal, secondaryVal, tertiaryVal, colorHints);
     }
 }
diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java
index e81e2a3..33d4fa6 100644
--- a/src/com/android/launcher3/dragndrop/DragView.java
+++ b/src/com/android/launcher3/dragndrop/DragView.java
@@ -193,7 +193,7 @@
      */
     @TargetApi(Build.VERSION_CODES.O)
     public void setItemInfo(final ItemInfo info) {
-        if (!(FeatureFlags.LAUNCHER3_SPRING_ICONS && Utilities.isAtLeastO())) {
+        if (!(FeatureFlags.LAUNCHER3_SPRING_ICONS && Utilities.ATLEAST_OREO)) {
             return;
         }
         if (info.itemType != LauncherSettings.Favorites.ITEM_TYPE_APPLICATION &&
diff --git a/src/com/android/launcher3/dragndrop/PinItemDragListener.java b/src/com/android/launcher3/dragndrop/PinItemDragListener.java
index c8d3890..b9d97ac 100644
--- a/src/com/android/launcher3/dragndrop/PinItemDragListener.java
+++ b/src/com/android/launcher3/dragndrop/PinItemDragListener.java
@@ -128,7 +128,7 @@
     }
 
     public static boolean handleDragRequest(Launcher launcher, Intent intent) {
-        if (!Utilities.isAtLeastO()) {
+        if (!Utilities.ATLEAST_OREO) {
             return false;
         }
         if (intent == null || !Intent.ACTION_MAIN.equals(intent.getAction())) {
diff --git a/src/com/android/launcher3/graphics/DrawableFactory.java b/src/com/android/launcher3/graphics/DrawableFactory.java
index 45344c0..371479b 100644
--- a/src/com/android/launcher3/graphics/DrawableFactory.java
+++ b/src/com/android/launcher3/graphics/DrawableFactory.java
@@ -80,7 +80,7 @@
 
 
     protected Path getPreloadProgressPath(Context context) {
-        if (Utilities.isAtLeastO()) {
+        if (Utilities.ATLEAST_OREO) {
             try {
                 // Try to load the path from Mask Icon
                 Drawable icon = context.getDrawable(R.drawable.adaptive_icon_drawable_wrapper);
diff --git a/src/com/android/launcher3/graphics/IconNormalizer.java b/src/com/android/launcher3/graphics/IconNormalizer.java
index 8ed62bc..28fc423 100644
--- a/src/com/android/launcher3/graphics/IconNormalizer.java
+++ b/src/com/android/launcher3/graphics/IconNormalizer.java
@@ -231,7 +231,7 @@
      */
     public synchronized float getScale(@NonNull Drawable d, @Nullable RectF outBounds,
             @Nullable Path path, @Nullable boolean[] outMaskShape) {
-        if (Utilities.isAtLeastO() && d instanceof AdaptiveIconDrawable &&
+        if (Utilities.ATLEAST_OREO && d instanceof AdaptiveIconDrawable &&
                 mAdaptiveIconScale != SCALE_NOT_INITIALIZED) {
             if (outBounds != null) {
                 outBounds.set(mAdaptiveIconBounds);
@@ -347,7 +347,7 @@
         float areaScale = area / (width * height);
         // Use sqrt of the final ratio as the images is scaled across both width and height.
         float scale = areaScale > scaleRequired ? (float) Math.sqrt(scaleRequired / areaScale) : 1;
-        if (Utilities.isAtLeastO() && d instanceof AdaptiveIconDrawable &&
+        if (Utilities.ATLEAST_OREO && d instanceof AdaptiveIconDrawable &&
                 mAdaptiveIconScale == SCALE_NOT_INITIALIZED) {
             mAdaptiveIconScale = scale;
             mAdaptiveIconBounds.set(mBounds);
diff --git a/src/com/android/launcher3/graphics/IconShapeOverride.java b/src/com/android/launcher3/graphics/IconShapeOverride.java
index 654fa98..223243b 100644
--- a/src/com/android/launcher3/graphics/IconShapeOverride.java
+++ b/src/com/android/launcher3/graphics/IconShapeOverride.java
@@ -59,7 +59,7 @@
     private static final int RESTART_REQUEST_CODE = 42; // the answer to everything
 
     public static boolean isSupported(Context context) {
-        if (!Utilities.isAtLeastO()) {
+        if (!Utilities.ATLEAST_OREO) {
             return false;
         }
         // Only supported when developer settings is enabled
@@ -82,7 +82,7 @@
     }
 
     public static void apply(Context context) {
-        if (!Utilities.isAtLeastO()) {
+        if (!Utilities.ATLEAST_OREO) {
             return;
         }
         String path = getAppliedValue(context);
diff --git a/src/com/android/launcher3/graphics/LauncherIcons.java b/src/com/android/launcher3/graphics/LauncherIcons.java
index 7c80c30..d55baf0 100644
--- a/src/com/android/launcher3/graphics/LauncherIcons.java
+++ b/src/com/android/launcher3/graphics/LauncherIcons.java
@@ -104,7 +104,7 @@
         float scale = 1f;
         if (!FeatureFlags.LAUNCHER3_DISABLE_ICON_NORMALIZATION) {
             normalizer = IconNormalizer.getInstance(context);
-            if (Utilities.isAtLeastO() && iconAppTargetSdk >= Build.VERSION_CODES.O) {
+            if (Utilities.ATLEAST_OREO && iconAppTargetSdk >= Build.VERSION_CODES.O) {
                 boolean[] outShape = new boolean[1];
                 AdaptiveIconDrawable dr = (AdaptiveIconDrawable)
                         context.getDrawable(R.drawable.adaptive_icon_drawable_wrapper).mutate();
@@ -123,7 +123,7 @@
             }
         }
         Bitmap bitmap = createIconBitmap(icon, context, scale);
-        if (FeatureFlags.ADAPTIVE_ICON_SHADOW && Utilities.isAtLeastO() &&
+        if (FeatureFlags.ADAPTIVE_ICON_SHADOW && Utilities.ATLEAST_OREO &&
                 icon instanceof AdaptiveIconDrawable) {
             bitmap = ShadowGenerator.getInstance(context).recreateIcon(bitmap);
         }
@@ -158,13 +158,13 @@
         float scale = 1f;
         if (!FeatureFlags.LAUNCHER3_DISABLE_ICON_NORMALIZATION) {
             normalizer = IconNormalizer.getInstance(context);
-            if (Utilities.isAtLeastO() && iconAppTargetSdk >= Build.VERSION_CODES.O) {
+            if (Utilities.ATLEAST_OREO && iconAppTargetSdk >= Build.VERSION_CODES.O) {
                 boolean[] outShape = new boolean[1];
                 AdaptiveIconDrawable dr = (AdaptiveIconDrawable)
                         context.getDrawable(R.drawable.adaptive_icon_drawable_wrapper).mutate();
                 dr.setBounds(0, 0, 1, 1);
                 scale = normalizer.getScale(icon, iconBounds, dr.getIconMask(), outShape);
-                if (Utilities.isAtLeastO() && FeatureFlags.LEGACY_ICON_TREATMENT &&
+                if (Utilities.ATLEAST_OREO && FeatureFlags.LEGACY_ICON_TREATMENT &&
                         !outShape[0]) {
                     Drawable wrappedIcon = wrapToAdaptiveIconDrawable(context, icon, scale);
                     if (wrappedIcon != icon) {
@@ -213,12 +213,12 @@
      */
     public static Bitmap createIconBitmap(Drawable icon, Context context) {
         float scale = 1f;
-        if (FeatureFlags.ADAPTIVE_ICON_SHADOW && Utilities.isAtLeastO() &&
+        if (FeatureFlags.ADAPTIVE_ICON_SHADOW && Utilities.ATLEAST_OREO &&
                 icon instanceof AdaptiveIconDrawable) {
             scale = ShadowGenerator.getScaleForBounds(new RectF(0, 0, 0, 0));
         }
         Bitmap bitmap =  createIconBitmap(icon, context, scale);
-        if (FeatureFlags.ADAPTIVE_ICON_SHADOW && Utilities.isAtLeastO() &&
+        if (FeatureFlags.ADAPTIVE_ICON_SHADOW && Utilities.ATLEAST_OREO &&
                 icon instanceof AdaptiveIconDrawable) {
             bitmap = ShadowGenerator.getInstance(context).recreateIcon(bitmap);
         }
@@ -271,7 +271,7 @@
             final int top = (textureHeight-height) / 2;
 
             sOldBounds.set(icon.getBounds());
-            if (Utilities.isAtLeastO() && icon instanceof AdaptiveIconDrawable) {
+            if (Utilities.ATLEAST_OREO && icon instanceof AdaptiveIconDrawable) {
                 int offset = Math.max((int)(ShadowGenerator.BLUR_FACTOR * iconBitmapSize),
                         Math.min(left, top));
                 int size = Math.max(width, height);
@@ -296,7 +296,7 @@
      * create AdaptiveIconDrawable.
      */
     static Drawable wrapToAdaptiveIconDrawable(Context context, Drawable drawable, float scale) {
-        if (!(FeatureFlags.LEGACY_ICON_TREATMENT && Utilities.isAtLeastO())) {
+        if (!(FeatureFlags.LEGACY_ICON_TREATMENT && Utilities.ATLEAST_OREO)) {
             return drawable;
         }
 
diff --git a/src/com/android/launcher3/graphics/ShadowDrawable.java b/src/com/android/launcher3/graphics/ShadowDrawable.java
index ffcedb2..b40bf78 100644
--- a/src/com/android/launcher3/graphics/ShadowDrawable.java
+++ b/src/com/android/launcher3/graphics/ShadowDrawable.java
@@ -146,7 +146,7 @@
             d.draw(canvas);
         }
 
-        if (Utilities.isAtLeastO()) {
+        if (Utilities.ATLEAST_OREO) {
             bitmap = bitmap.copy(Bitmap.Config.HARDWARE, false);
         }
         mState.mLastDrawnBitmap = bitmap;
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index 13962a2..292f23c 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -101,7 +101,7 @@
                     appsList.addPackage(context, packages[i], mUser);
 
                     // Automatically add homescreen icon for work profile apps for below O device.
-                    if (!Utilities.isAtLeastO() && !Process.myUserHandle().equals(mUser)) {
+                    if (!Utilities.ATLEAST_OREO && !Process.myUserHandle().equals(mUser)) {
                         SessionCommitReceiver.queueAppIconAddition(context, packages[i], mUser);
                     }
                 }
@@ -231,6 +231,9 @@
                                             continue;
                                         }
                                     }
+                                } else {
+                                    si.status = ShortcutInfo.DEFAULT;
+                                    infoUpdated = true;
                                 }
                             }
 
@@ -342,7 +345,7 @@
                     callbacks.notifyWidgetProvidersChanged();
                 }
             });
-        } else if (Utilities.isAtLeastO() && mOp == OP_ADD) {
+        } else if (Utilities.ATLEAST_OREO && mOp == OP_ADD) {
             // Load widgets for the new package.
             for (int i = 0; i < N; i++) {
                 dataModel.widgetsModel.update(app, new PackageUserKey(packages[i], mUser));
diff --git a/src/com/android/launcher3/notification/NotificationFooterLayout.java b/src/com/android/launcher3/notification/NotificationFooterLayout.java
index 2455eab..ad07d37 100644
--- a/src/com/android/launcher3/notification/NotificationFooterLayout.java
+++ b/src/com/android/launcher3/notification/NotificationFooterLayout.java
@@ -200,7 +200,9 @@
             PopupContainerWithArrow popup = PopupContainerWithArrow.getOpen(
                     Launcher.getLauncher(getContext()));
             if (popup != null) {
-                Animator collapseFooter = popup.reduceNotificationViewHeight(getHeight(),
+                final int newHeight = getResources().getDimensionPixelSize(
+                        R.dimen.notification_empty_footer_height);
+                Animator collapseFooter = popup.reduceNotificationViewHeight(getHeight() - newHeight,
                         getResources().getInteger(R.integer.config_removeNotificationViewDuration));
                 collapseFooter.addListener(new AnimatorListenerAdapter() {
                     @Override
@@ -208,7 +210,7 @@
                         ((ViewGroup) getParent()).findViewById(R.id.divider).setVisibility(GONE);
                         // Keep view around because gutter is aligned to it, but remove height to
                         // both hide the view and keep calculations correct for last dismissal.
-                        getLayoutParams().height = 0;
+                        getLayoutParams().height = newHeight;
                         requestLayout();
                     }
                 });
diff --git a/src/com/android/launcher3/notification/NotificationItemView.java b/src/com/android/launcher3/notification/NotificationItemView.java
index 78c64d7..ab94c32 100644
--- a/src/com/android/launcher3/notification/NotificationItemView.java
+++ b/src/com/android/launcher3/notification/NotificationItemView.java
@@ -90,9 +90,19 @@
         return mMainView;
     }
 
+    /**
+     * This method is used to calculate the height to remove when dismissing the last notification.
+     * We subtract the height of the footer in this case since the footer should be gone or in the
+     * process of being removed.
+     * @return The height of the entire notification item, minus the footer if it still exists.
+     */
     public int getHeightMinusFooter() {
-        int footerHeight = mFooter.getParent() == null ? 0 : mFooter.getHeight();
-        return getHeight() - footerHeight;
+        if (mFooter.getParent() == null) {
+            return getHeight();
+        }
+        int excessFooterHeight = mFooter.getHeight() - getResources().getDimensionPixelSize(
+                R.dimen.notification_empty_footer_height);
+        return getHeight() - excessFooterHeight;
     }
 
     public Animator animateHeightRemoval(int heightToRemove, boolean shouldRemoveFromTop) {
diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorCaretLandscape.java b/src/com/android/launcher3/pageindicators/PageIndicatorCaretLandscape.java
index 682d5a9..911be93 100644
--- a/src/com/android/launcher3/pageindicators/PageIndicatorCaretLandscape.java
+++ b/src/com/android/launcher3/pageindicators/PageIndicatorCaretLandscape.java
@@ -48,7 +48,6 @@
         setCaretDrawable(caretDrawable);
 
         Launcher l = Launcher.getLauncher(context);
-        setOnTouchListener(l.getHapticFeedbackTouchListener());
         setOnClickListener(l);
         setOnFocusChangeListener(l.mFocusHandler);
     }
diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorLineCaret.java b/src/com/android/launcher3/pageindicators/PageIndicatorLineCaret.java
index 29834d7..6281fec 100644
--- a/src/com/android/launcher3/pageindicators/PageIndicatorLineCaret.java
+++ b/src/com/android/launcher3/pageindicators/PageIndicatorLineCaret.java
@@ -141,7 +141,6 @@
         super.onFinishInflate();
         mAllAppsHandle = (ImageView) findViewById(R.id.all_apps_handle);
         mAllAppsHandle.setImageDrawable(getCaretDrawable());
-        mAllAppsHandle.setOnTouchListener(mLauncher.getHapticFeedbackTouchListener());
         mAllAppsHandle.setOnClickListener(mLauncher);
         mAllAppsHandle.setOnFocusChangeListener(mLauncher.mFocusHandler);
         mLauncher.setAllAppsButton(mAllAppsHandle);
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index c3e2d8b..8441598 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -275,8 +275,9 @@
             if (itemTypeToPopulate == PopupPopulator.Item.NOTIFICATION) {
                 mNotificationItemView = (NotificationItemView) item;
                 boolean notificationFooterHasIcons = numNotifications > 1;
-                int footerHeight = notificationFooterHasIcons ?
-                        res.getDimensionPixelSize(R.dimen.notification_footer_height) : 0;
+                int footerHeight = res.getDimensionPixelSize(
+                        notificationFooterHasIcons ? R.dimen.notification_footer_height
+                                : R.dimen.notification_empty_footer_height);
                 item.findViewById(R.id.footer).getLayoutParams().height = footerHeight;
                 if (notificationFooterHasIcons) {
                     mNotificationItemView.findViewById(R.id.divider).setVisibility(VISIBLE);
diff --git a/src/com/android/launcher3/util/ManagedProfileHeuristic.java b/src/com/android/launcher3/util/ManagedProfileHeuristic.java
index 091dd84..009aee7 100644
--- a/src/com/android/launcher3/util/ManagedProfileHeuristic.java
+++ b/src/com/android/launcher3/util/ManagedProfileHeuristic.java
@@ -67,7 +67,7 @@
             return;
         }
 
-        if (Utilities.isAtLeastO() && !SessionCommitReceiver.isEnabled(context)) {
+        if (Utilities.ATLEAST_OREO && !SessionCommitReceiver.isEnabled(context)) {
             // Just mark the folder id preference to avoid new folder creation later.
             ufi.prefs.edit().putLong(ufi.folderIdKey, ItemInfo.NO_ID).apply();
             return;
diff --git a/src/com/android/launcher3/util/SystemUiController.java b/src/com/android/launcher3/util/SystemUiController.java
index d7a2625..edbf05a 100644
--- a/src/com/android/launcher3/util/SystemUiController.java
+++ b/src/com/android/launcher3/util/SystemUiController.java
@@ -59,7 +59,7 @@
         // Apply the state flags in priority order
         int newFlags = oldFlags;
         for (int stateFlag : mStates) {
-            if (Utilities.isAtLeastO()) {
+            if (Utilities.ATLEAST_OREO) {
                 if ((stateFlag & FLAG_LIGHT_NAV) != 0) {
                     newFlags |= View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
                 } else if ((stateFlag & FLAG_DARK_NAV) != 0) {
diff --git a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
index 4b9d83f..bd21315 100644
--- a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
@@ -141,7 +141,7 @@
 
     private void runTest(String activityMethod, boolean isWidget, ItemOperator itemMatcher,
             Intent... commandIntents) throws Throwable {
-        if (!Utilities.isAtLeastO()) {
+        if (!Utilities.ATLEAST_OREO) {
             return;
         }
         lockRotation(true);