Changing min sdk to 25

Change-Id: I0d28069967854357ca755bf25dec19d4979bdecf
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 9500a2f..655787c 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -20,7 +20,7 @@
 <manifest
     xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.launcher3">
-    <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="21"/>
+    <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="25"/>
     <!--
     Manifest entries specific to Launcher3. This is merged with AndroidManifest-common.xml.
     Refer comments around specific entries on how to extend individual components.
diff --git a/build.gradle b/build.gradle
index 4191d47..ab97687 100644
--- a/build.gradle
+++ b/build.gradle
@@ -17,7 +17,7 @@
     buildToolsVersion BUILD_TOOLS_VERSION
 
     defaultConfig {
-        minSdkVersion 21
+        minSdkVersion 25
         targetSdkVersion 28
         versionCode 1
         versionName "1.0"
diff --git a/go/AndroidManifest.xml b/go/AndroidManifest.xml
index 25518af..fae1eff 100644
--- a/go/AndroidManifest.xml
+++ b/go/AndroidManifest.xml
@@ -22,7 +22,7 @@
     xmlns:tools="http://schemas.android.com/tools"
     package="com.android.launcher3" >
 
-    <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="21"/>
+    <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="25"/>
 
     <application
         android:backupAgent="com.android.launcher3.LauncherBackupAgent"
diff --git a/gradle.properties b/gradle.properties
index b299cfe..e31f59e 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -4,7 +4,7 @@
 
 ANDROID_X_VERSION=1.0.0-beta01
 
-GRADLE_CLASS_PATH=com.android.tools.build:gradle:3.2.0-rc03
+GRADLE_CLASS_PATH=com.android.tools.build:gradle:3.3.0
 
 PROTOBUF_CLASS_PATH=com.google.protobuf:protobuf-gradle-plugin:0.8.6
 PROTOBUF_DEPENDENCY=com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-7
diff --git a/iconloaderlib/build.gradle b/iconloaderlib/build.gradle
index f6a820a..4fd3189 100644
--- a/iconloaderlib/build.gradle
+++ b/iconloaderlib/build.gradle
@@ -16,7 +16,7 @@
     publishNonDefault true
 
     defaultConfig {
-        minSdkVersion 21
+        minSdkVersion 25
         targetSdkVersion 28
         versionCode 1
         versionName "1.0"
diff --git a/iconloaderlib/src/com/android/launcher3/icons/FixedScaleDrawable.java b/iconloaderlib/src/com/android/launcher3/icons/FixedScaleDrawable.java
index e594f47..516965e 100644
--- a/iconloaderlib/src/com/android/launcher3/icons/FixedScaleDrawable.java
+++ b/iconloaderlib/src/com/android/launcher3/icons/FixedScaleDrawable.java
@@ -1,12 +1,10 @@
 package com.android.launcher3.icons;
 
-import android.annotation.TargetApi;
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
 import android.graphics.Canvas;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.DrawableWrapper;
-import android.os.Build;
 import android.util.AttributeSet;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -14,7 +12,6 @@
 /**
  * Extension of {@link DrawableWrapper} which scales the child drawables by a fixed amount.
  */
-@TargetApi(Build.VERSION_CODES.N)
 public class FixedScaleDrawable extends DrawableWrapper {
 
     // TODO b/33553066 use the constant defined in MaskableIconDrawable
diff --git a/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java b/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java
index ce66448..2966cb1 100644
--- a/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java
+++ b/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java
@@ -47,16 +47,15 @@
 import com.android.launcher3.icons.BitmapRenderer;
 import com.android.launcher3.icons.GraphicsUtils;
 import com.android.launcher3.util.ComponentKey;
-import com.android.launcher3.util.Provider;
 import com.android.launcher3.util.SQLiteCacheHelper;
 
 import java.util.AbstractMap;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.Supplier;
 
 import androidx.annotation.NonNull;
 
@@ -231,13 +230,8 @@
      * incorporates all the properties that can affect the cache like locale and system-version.
      */
     private void updateSystemState() {
-        final String locale;
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
-            locale = mContext.getResources().getConfiguration().getLocales().toLanguageTags();
-        } else {
-            locale = Locale.getDefault().toString();
-        }
-
+        final String locale =
+                mContext.getResources().getConfiguration().getLocales().toLanguageTags();
         mSystemState = locale + "," + Build.VERSION.SDK_INT;
     }
 
@@ -309,7 +303,7 @@
      */
     protected <T> CacheEntry cacheLocked(
             @NonNull ComponentName componentName, @NonNull UserHandle user,
-            @NonNull Provider<T> infoProvider, @NonNull CachingLogic<T> cachingLogic,
+            @NonNull Supplier<T> infoProvider, @NonNull CachingLogic<T> cachingLogic,
             boolean usePackageIcon, boolean useLowResIcon) {
         return cacheLocked(componentName, user, infoProvider, cachingLogic, usePackageIcon,
                 useLowResIcon, true);
@@ -317,7 +311,7 @@
 
     protected <T> CacheEntry cacheLocked(
             @NonNull ComponentName componentName, @NonNull UserHandle user,
-            @NonNull Provider<T> infoProvider, @NonNull CachingLogic<T> cachingLogic,
+            @NonNull Supplier<T> infoProvider, @NonNull CachingLogic<T> cachingLogic,
             boolean usePackageIcon, boolean useLowResIcon, boolean addToMemCache) {
         assertWorkerThread();
         ComponentKey cacheKey = new ComponentKey(componentName, user);
diff --git a/iconloaderlib/src/com/android/launcher3/util/Provider.java b/iconloaderlib/src/com/android/launcher3/util/Provider.java
deleted file mode 100644
index 4a54c0f..0000000
--- a/iconloaderlib/src/com/android/launcher3/util/Provider.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.util;
-
-/**
- * Utility class to allow lazy initialization of objects.
- */
-public interface Provider<T> {
-
-    /**
-     * Initializes and returns the object. This may contain expensive operations not suitable
-     * to UI thread.
-     */
-    T get();
-
-    static <T> Provider<T> of (T value) {
-        return() -> value;
-    }
-}
diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
index 07a5b72..4930dc5 100644
--- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
@@ -54,9 +54,6 @@
 import android.view.View;
 import android.view.ViewGroup;
 
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
 import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
 import com.android.launcher3.InsettableFrameLayout.LayoutParams;
 import com.android.launcher3.allapps.AllAppsTransitionController;
@@ -80,6 +77,9 @@
 import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
 import com.android.systemui.shared.system.WindowManagerWrapper;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
 /**
  * {@link LauncherAppTransitionManager} with Quickstep-specific app transitions for launching from
  * home and/or all-apps.
@@ -308,7 +308,7 @@
      */
     private Rect getWindowTargetBounds(RemoteAnimationTargetCompat[] targets) {
         Rect bounds = new Rect(0, 0, mDeviceProfile.widthPx, mDeviceProfile.heightPx);
-        if (mLauncher.isInMultiWindowModeCompat()) {
+        if (mLauncher.isInMultiWindowMode()) {
             for (RemoteAnimationTargetCompat target : targets) {
                 if (target.mode == MODE_OPENING) {
                     bounds.set(target.sourceContainerBounds);
diff --git a/quickstep/src/com/android/quickstep/MultiStateCallback.java b/quickstep/src/com/android/quickstep/MultiStateCallback.java
index 98d723f..1592a97 100644
--- a/quickstep/src/com/android/quickstep/MultiStateCallback.java
+++ b/quickstep/src/com/android/quickstep/MultiStateCallback.java
@@ -17,7 +17,7 @@
 
 import android.util.SparseArray;
 
-import com.android.launcher3.Utilities.Consumer;
+import java.util.function.Consumer;
 
 /**
  * Utility class to help manage multiple callbacks based on different states.
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index 89c7aba..b76a1ab 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -19,10 +19,8 @@
 import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
 
 import static com.android.launcher3.QuickstepAppTransitionManagerImpl.RECENTS_LAUNCH_DURATION;
-import static com.android.launcher3.QuickstepAppTransitionManagerImpl
-        .STATUS_BAR_TRANSITION_DURATION;
-import static com.android.launcher3.QuickstepAppTransitionManagerImpl
-        .STATUS_BAR_TRANSITION_PRE_DELAY;
+import static com.android.launcher3.QuickstepAppTransitionManagerImpl.STATUS_BAR_TRANSITION_DURATION;
+import static com.android.launcher3.QuickstepAppTransitionManagerImpl.STATUS_BAR_TRANSITION_PRE_DELAY;
 import static com.android.quickstep.TaskUtils.getRecentsWindowAnimator;
 import static com.android.quickstep.TaskUtils.taskIsATargetWithMode;
 import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
@@ -42,7 +40,6 @@
 import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.ItemInfo;
 import com.android.launcher3.LauncherAnimationRunner;
 import com.android.launcher3.R;
 import com.android.launcher3.anim.Interpolators;
@@ -108,7 +105,7 @@
     }
 
     public void onRootViewSizeChanged() {
-        if (isInMultiWindowModeCompat()) {
+        if (isInMultiWindowMode()) {
             onHandleConfigChanged();
         }
     }
@@ -135,7 +132,7 @@
 
         // In case we are reusing IDP, create a copy so that we don't conflict with Launcher
         // activity.
-        mDeviceProfile = (mRecentsRootView != null) && isInMultiWindowModeCompat()
+        mDeviceProfile = (mRecentsRootView != null) && isInMultiWindowMode()
                 ? dp.getMultiWindowProfile(this, mRecentsRootView.getLastKnownSize())
                 : dp.copy(this);
         onDeviceProfileInitiated();
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index b0ca4d7..ff85003 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -187,7 +187,7 @@
 
     @Override
     public boolean shouldUseMultiWindowTaskSizeStrategy() {
-        return mActivity.isInMultiWindowModeCompat();
+        return mActivity.isInMultiWindowMode();
     }
 
     @Override
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
index 8169d73..d0289d0 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -291,7 +291,7 @@
                 // Rotate the screenshot if not in multi-window mode
                 mIsRotated = FeatureFlags.OVERVIEW_USE_SCREENSHOT_ORIENTATION &&
                         configuration.orientation != mThumbnailData.orientation &&
-                        !mActivity.isInMultiWindowModeCompat() &&
+                        !mActivity.isInMultiWindowMode() &&
                         mThumbnailData.windowingMode == WINDOWING_MODE_FULLSCREEN;
                 // Scale the screenshot to always fit the width of the card.
                 thumbnailScale = mIsRotated
diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java
index 5137774..7f72242 100644
--- a/src/com/android/launcher3/BaseActivity.java
+++ b/src/com/android/launcher3/BaseActivity.java
@@ -17,6 +17,7 @@
 package com.android.launcher3;
 
 import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW;
+
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
 import android.app.Activity;
@@ -25,7 +26,6 @@
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.view.ContextThemeWrapper;
-import android.view.View.AccessibilityDelegate;
 
 import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
 import com.android.launcher3.logging.StatsLogManager;
@@ -125,10 +125,6 @@
         return mUserEventDispatcher;
     }
 
-    public boolean isInMultiWindowModeCompat() {
-        return Utilities.ATLEAST_NOUGAT && isInMultiWindowMode();
-    }
-
     public SystemUiController getSystemUiController() {
         if (mSystemUiController == null) {
             mSystemUiController = new SystemUiController(getWindow());
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index 12d443b..5b9b172 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -174,8 +174,7 @@
             intent.setSourceBounds(getViewBounds(v));
         }
         try {
-            boolean isShortcut = Utilities.ATLEAST_MARSHMALLOW
-                    && (item instanceof ShortcutInfo)
+            boolean isShortcut = (item instanceof ShortcutInfo)
                     && (item.itemType == Favorites.ITEM_TYPE_SHORTCUT
                     || item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)
                     && !((ShortcutInfo) item).isPromise();
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index b8b1181..1084e7a 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -74,8 +74,6 @@
 import android.view.animation.OvershootInterpolator;
 import android.widget.Toast;
 
-import androidx.annotation.Nullable;
-
 import com.android.launcher3.DropTarget.DragObject;
 import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
 import com.android.launcher3.allapps.AllAppsContainerView;
@@ -149,6 +147,8 @@
 import java.util.List;
 import java.util.Set;
 
+import androidx.annotation.Nullable;
+
 /**
  * Default launcher application.
  */
@@ -409,7 +409,7 @@
     private void initDeviceProfile(InvariantDeviceProfile idp) {
         // Load configuration-specific DeviceProfile
         mDeviceProfile = idp.getDeviceProfile(this);
-        if (isInMultiWindowModeCompat()) {
+        if (isInMultiWindowMode()) {
             Display display = getWindowManager().getDefaultDisplay();
             Point mwSize = new Point();
             display.getSize(mwSize);
@@ -2311,7 +2311,6 @@
     }
 
     @Override
-    @TargetApi(Build.VERSION_CODES.N)
     public void onProvideKeyboardShortcuts(
             List<KeyboardShortcutGroup> data, Menu menu, int deviceId) {
 
diff --git a/src/com/android/launcher3/LauncherAppTransitionManager.java b/src/com/android/launcher3/LauncherAppTransitionManager.java
index 970e558..fb50dfb 100644
--- a/src/com/android/launcher3/LauncherAppTransitionManager.java
+++ b/src/com/android/launcher3/LauncherAppTransitionManager.java
@@ -36,28 +36,19 @@
     }
 
     public ActivityOptions getActivityLaunchOptions(Launcher launcher, View v) {
-        if (Utilities.ATLEAST_MARSHMALLOW) {
-            int left = 0, top = 0;
-            int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();
-            if (v instanceof BubbleTextView) {
-                // Launch from center of icon, not entire view
-                Drawable icon = ((BubbleTextView) v).getIcon();
-                if (icon != null) {
-                    Rect bounds = icon.getBounds();
-                    left = (width - bounds.width()) / 2;
-                    top = v.getPaddingTop();
-                    width = bounds.width();
-                    height = bounds.height();
-                }
+        int left = 0, top = 0;
+        int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();
+        if (v instanceof BubbleTextView) {
+            // Launch from center of icon, not entire view
+            Drawable icon = ((BubbleTextView) v).getIcon();
+            if (icon != null) {
+                Rect bounds = icon.getBounds();
+                left = (width - bounds.width()) / 2;
+                top = v.getPaddingTop();
+                width = bounds.width();
+                height = bounds.height();
             }
-            return ActivityOptions.makeClipRevealAnimation(v, left, top, width, height);
-        } else if (Utilities.ATLEAST_LOLLIPOP_MR1) {
-            // On L devices, we use the device default slide-up transition.
-            // On L MR1 devices, we use a custom version of the slide-up transition which
-            // doesn't have the delay present in the device default.
-            return ActivityOptions.makeCustomAnimation(launcher, R.anim.task_open_enter,
-                    R.anim.no_anim);
         }
-        return null;
+        return ActivityOptions.makeClipRevealAnimation(v, left, top, width, height);
     }
 }
diff --git a/src/com/android/launcher3/LauncherAppWidgetHost.java b/src/com/android/launcher3/LauncherAppWidgetHost.java
index 56671a1..7f5ac52 100644
--- a/src/com/android/launcher3/LauncherAppWidgetHost.java
+++ b/src/com/android/launcher3/LauncherAppWidgetHost.java
@@ -26,7 +26,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.os.Handler;
-import android.util.Log;
 import android.util.SparseArray;
 import android.view.LayoutInflater;
 import android.widget.Toast;
@@ -135,9 +134,6 @@
      * @see #setResumed(boolean)
      */
     public void setListenIfResumed(boolean listenIfResumed) {
-        if (!Utilities.ATLEAST_NOUGAT_MR1) {
-            return;
-        }
         if (listenIfResumed == ((mFlags & FLAG_LISTEN_IF_RESUMED) != 0)) {
             return;
         }
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index ebca2ea..c38423a 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -54,7 +54,6 @@
 import com.android.launcher3.util.ItemInfoMatcher;
 import com.android.launcher3.util.PackageUserKey;
 import com.android.launcher3.util.Preconditions;
-import com.android.launcher3.util.Provider;
 import com.android.launcher3.util.Thunk;
 import com.android.launcher3.util.ViewOnDrawExecutor;
 import com.android.launcher3.widget.WidgetListRowEntry;
@@ -68,6 +67,7 @@
 import java.util.List;
 import java.util.concurrent.CancellationException;
 import java.util.concurrent.Executor;
+import java.util.function.Supplier;
 
 import androidx.annotation.Nullable;
 
@@ -542,10 +542,8 @@
      * use partial updates similar to {@link UserManagerCompat}
      */
     public void refreshShortcutsIfRequired() {
-        if (Utilities.ATLEAST_NOUGAT_MR1) {
-            sWorker.removeCallbacks(mShortcutPermissionCheckRunnable);
-            sWorker.post(mShortcutPermissionCheckRunnable);
-        }
+        sWorker.removeCallbacks(mShortcutPermissionCheckRunnable);
+        sWorker.post(mShortcutPermissionCheckRunnable);
     }
 
     /**
@@ -611,7 +609,7 @@
     /**
      * Utility method to update a shortcut on the background thread.
      */
-    public void updateAndBindShortcutInfo(final Provider<ShortcutInfo> shortcutProvider) {
+    public void updateAndBindShortcutInfo(final Supplier<ShortcutInfo> shortcutProvider) {
         enqueueModelUpdateTask(new BaseModelUpdateTask() {
             @Override
             public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 24dc17a..fb33694 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -189,7 +189,7 @@
     }
 
     private void reloadLauncherIfExternal() {
-        if (Utilities.ATLEAST_MARSHMALLOW && Binder.getCallingPid() != Process.myPid()) {
+        if (Binder.getCallingPid() != Process.myPid()) {
             LauncherAppState app = LauncherAppState.getInstanceNoCreate();
             if (app != null) {
                 app.getModel().forceReload();
@@ -217,21 +217,7 @@
 
         uri = ContentUris.withAppendedId(uri, rowId);
         notifyListeners();
-
-        if (Utilities.ATLEAST_MARSHMALLOW) {
-            reloadLauncherIfExternal();
-        } else {
-            // Deprecated behavior to support legacy devices which rely on provider callbacks.
-            LauncherAppState app = LauncherAppState.getInstanceNoCreate();
-            if (app != null && "true".equals(uri.getQueryParameter("isExternalAdd"))) {
-                app.getModel().forceReload();
-            }
-
-            String notify = uri.getQueryParameter("notify");
-            if (notify == null || "true".equals(notify)) {
-                getContext().getContentResolver().notifyChange(uri, null);
-            }
-        }
+        reloadLauncherIfExternal();
         return uri;
     }
 
@@ -301,7 +287,7 @@
             throws OperationApplicationException {
         createDbIfNotExists();
         try (SQLiteTransaction t = new SQLiteTransaction(mOpenHelper.getWritableDatabase())) {
-            boolean isAddOrDelete = !Utilities.ATLEAST_MARSHMALLOW;
+            boolean isAddOrDelete = false;
 
             final int numOperations = operations.size();
             final ContentProviderResult[] results = new ContentProviderResult[numOperations];
diff --git a/src/com/android/launcher3/LauncherRootView.java b/src/com/android/launcher3/LauncherRootView.java
index 3cf6d62..9f6e5cd 100644
--- a/src/com/android/launcher3/LauncherRootView.java
+++ b/src/com/android/launcher3/LauncherRootView.java
@@ -51,7 +51,7 @@
     protected boolean fitSystemWindows(Rect insets) {
         mConsumedInsets.setEmpty();
         boolean drawInsetBar = false;
-        if (mLauncher.isInMultiWindowModeCompat()
+        if (mLauncher.isInMultiWindowMode()
                 && (insets.left > 0 || insets.right > 0 || insets.bottom > 0)) {
             mConsumedInsets.left = insets.left;
             mConsumedInsets.right = insets.right;
@@ -59,8 +59,7 @@
             insets = new Rect(0, insets.top, 0, 0);
             drawInsetBar = true;
         } else  if ((insets.right > 0 || insets.left > 0) &&
-                (!Utilities.ATLEAST_MARSHMALLOW ||
-                        getContext().getSystemService(ActivityManager.class).isLowRamDevice())) {
+                getContext().getSystemService(ActivityManager.class).isLowRamDevice()) {
             mConsumedInsets.left = insets.left;
             mConsumedInsets.right = insets.right;
             insets = new Rect(0, insets.top, 0, insets.bottom);
diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java
index c2c3287..e53d59c 100644
--- a/src/com/android/launcher3/ShortcutInfo.java
+++ b/src/com/android/launcher3/ShortcutInfo.java
@@ -16,11 +16,9 @@
 
 package com.android.launcher3;
 
-import android.annotation.TargetApi;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.os.Build;
 import android.text.TextUtils;
 
 import com.android.launcher3.LauncherSettings.Favorites;
@@ -111,7 +109,6 @@
     /**
      * Creates a {@link ShortcutInfo} from a {@link ShortcutInfoCompat}.
      */
-    @TargetApi(Build.VERSION_CODES.N)
     public ShortcutInfo(ShortcutInfoCompat shortcutInfo, Context context) {
         user = shortcutInfo.getUserHandle();
         itemType = Favorites.ITEM_TYPE_DEEP_SHORTCUT;
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index a0f005c..c847120 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -28,7 +28,6 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
-import android.graphics.Bitmap;
 import android.graphics.Matrix;
 import android.graphics.Paint;
 import android.graphics.Point;
@@ -55,7 +54,6 @@
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.util.IntArray;
 
-import java.io.ByteArrayOutputStream;
 import java.io.Closeable;
 import java.io.IOException;
 import java.lang.reflect.Method;
@@ -98,18 +96,6 @@
     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;
-
-    public static final boolean ATLEAST_NOUGAT =
-            Build.VERSION.SDK_INT >= Build.VERSION_CODES.N;
-
-    public static final boolean ATLEAST_MARSHMALLOW =
-            Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
-
-    public static final boolean ATLEAST_LOLLIPOP_MR1 =
-            Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1;
-
     public static final int SINGLE_FRAME_MS = 16;
 
     /**
@@ -123,9 +109,6 @@
     // An intent extra to indicate the horizontal scroll of the wallpaper.
     public static final String EXTRA_WALLPAPER_OFFSET = "com.android.launcher3.WALLPAPER_OFFSET";
 
-    public static final int COLOR_EXTRACTION_JOB_ID = 1;
-    public static final int WALLPAPER_COMPAT_JOB_ID = 2;
-
     // These values are same as that in {@link AsyncTask}.
     private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
     private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
@@ -512,19 +495,11 @@
             // Battery saver mode no longer prevents animations.
             return false;
         }
-        PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
-        return powerManager.isPowerSaveMode();
+        return context.getSystemService(PowerManager.class).isPowerSaveMode();
     }
 
     public static boolean isWallpaperAllowed(Context context) {
-        if (ATLEAST_NOUGAT) {
-            try {
-                WallpaperManager wm = context.getSystemService(WallpaperManager.class);
-                return (Boolean) wm.getClass().getDeclaredMethod("isSetWallpaperAllowed")
-                        .invoke(wm);
-            } catch (Exception e) { }
-        }
-        return true;
+        return context.getSystemService(WallpaperManager.class).isSetWallpaperAllowed();
     }
 
     public static void closeSilently(Closeable c) {
@@ -602,8 +577,4 @@
     public static String getPointString(int x, int y) {
         return String.format(Locale.ENGLISH, "%d,%d", x, y);
     }
-
-    public interface Consumer<T> {
-        void accept(T var1);
-    }
 }
diff --git a/src/com/android/launcher3/allapps/AllAppsStore.java b/src/com/android/launcher3/allapps/AllAppsStore.java
index cf0f2a3..52d7d28 100644
--- a/src/com/android/launcher3/allapps/AllAppsStore.java
+++ b/src/com/android/launcher3/allapps/AllAppsStore.java
@@ -30,6 +30,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Set;
+import java.util.function.Consumer;
 
 /**
  * A utility class to maintain the collection of all apps.
@@ -140,7 +141,7 @@
         });
     }
 
-    private void updateAllIcons(IconAction action) {
+    private void updateAllIcons(Consumer<BubbleTextView> action) {
         for (int i = mIconContainers.size() - 1; i >= 0; i--) {
             ViewGroup parent = mIconContainers.get(i);
             int childCount = parent.getChildCount();
@@ -148,7 +149,7 @@
             for (int j = 0; j < childCount; j++) {
                 View child = parent.getChildAt(j);
                 if (child instanceof BubbleTextView) {
-                    action.apply((BubbleTextView) child);
+                    action.accept((BubbleTextView) child);
                 }
             }
         }
@@ -157,8 +158,4 @@
     public interface OnUpdateListener {
         void onAppsUpdated();
     }
-
-    public interface IconAction {
-        void apply(BubbleTextView icon);
-    }
 }
diff --git a/src/com/android/launcher3/anim/RevealOutlineAnimation.java b/src/com/android/launcher3/anim/RevealOutlineAnimation.java
index afb8875..f99dabc 100644
--- a/src/com/android/launcher3/anim/RevealOutlineAnimation.java
+++ b/src/com/android/launcher3/anim/RevealOutlineAnimation.java
@@ -8,8 +8,6 @@
 import android.view.View;
 import android.view.ViewOutlineProvider;
 
-import com.android.launcher3.Utilities;
-
 /**
  * A {@link ViewOutlineProvider} that has helper functions to create reveal animations.
  * This class should be extended so that subclasses can define the reveal shape as the
@@ -58,16 +56,10 @@
 
         });
 
-        va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator arg0) {
-                float progress = (Float) arg0.getAnimatedValue();
-                setProgress(progress);
-                revealView.invalidateOutline();
-                if (!Utilities.ATLEAST_LOLLIPOP_MR1) {
-                    revealView.invalidate();
-                }
-            }
+        va.addUpdateListener(v -> {
+            float progress = (Float) v.getAnimatedValue();
+            setProgress(progress);
+            revealView.invalidateOutline();
         });
         return va;
     }
diff --git a/src/com/android/launcher3/compat/AccessibilityManagerCompat.java b/src/com/android/launcher3/compat/AccessibilityManagerCompat.java
index 02da861..6feb1e9 100644
--- a/src/com/android/launcher3/compat/AccessibilityManagerCompat.java
+++ b/src/com/android/launcher3/compat/AccessibilityManagerCompat.java
@@ -26,6 +26,8 @@
 import com.android.launcher3.TestProtocol;
 import com.android.launcher3.Utilities;
 
+import java.util.function.Consumer;
+
 public class AccessibilityManagerCompat {
 
     public static boolean isAccessibilityEnabled(Context context) {
@@ -85,7 +87,7 @@
     }
 
     public static boolean processTestRequest(Context context, String eventTag, int action,
-            Bundle request, Utilities.Consumer<Bundle> responseFiller) {
+            Bundle request, Consumer<Bundle> responseFiller) {
         final AccessibilityManager accessibilityManager = getAccessibilityManagerForTest(context);
         if (accessibilityManager == null) return false;
 
diff --git a/src/com/android/launcher3/compat/AlphabeticIndexCompat.java b/src/com/android/launcher3/compat/AlphabeticIndexCompat.java
index a7c0a47..dfdcc70 100644
--- a/src/com/android/launcher3/compat/AlphabeticIndexCompat.java
+++ b/src/com/android/launcher3/compat/AlphabeticIndexCompat.java
@@ -1,15 +1,12 @@
 package com.android.launcher3.compat;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.icu.text.AlphabeticIndex;
-import android.os.Build;
 import android.os.LocaleList;
 import android.util.Log;
 
 import com.android.launcher3.Utilities;
 
-import java.lang.reflect.Method;
 import java.util.Locale;
 
 import androidx.annotation.NonNull;
@@ -25,19 +22,10 @@
         BaseIndex index = null;
 
         try {
-            if (Utilities.ATLEAST_NOUGAT) {
-                index = new AlphabeticIndexVN(context);
-            }
+            index = new AlphabeticIndexVN(context);
         } catch (Exception e) {
             Log.d(TAG, "Unable to load the system index", e);
         }
-        if (index == null) {
-            try {
-                index = new AlphabeticIndexV16(context);
-            } catch (Exception e) {
-                Log.d(TAG, "Unable to load the system index", e);
-            }
-        }
 
         mBaseIndex = index == null ? new BaseIndex() : index;
 
@@ -111,59 +99,8 @@
     }
 
     /**
-     * Reflected libcore.icu.AlphabeticIndex implementation, falls back to the base
-     * alphabetic index.
-     */
-    private static class AlphabeticIndexV16 extends BaseIndex {
-
-        private Object mAlphabeticIndex;
-        private Method mGetBucketIndexMethod;
-        private Method mGetBucketLabelMethod;
-
-        public AlphabeticIndexV16(Context context) throws Exception {
-            Locale curLocale = context.getResources().getConfiguration().locale;
-            Class clazz = Class.forName("libcore.icu.AlphabeticIndex");
-            mGetBucketIndexMethod = clazz.getDeclaredMethod("getBucketIndex", String.class);
-            mGetBucketLabelMethod = clazz.getDeclaredMethod("getBucketLabel", int.class);
-            mAlphabeticIndex = clazz.getConstructor(Locale.class).newInstance(curLocale);
-
-            if (!curLocale.getLanguage().equals(Locale.ENGLISH.getLanguage())) {
-                clazz.getDeclaredMethod("addLabels", Locale.class)
-                        .invoke(mAlphabeticIndex, Locale.ENGLISH);
-            }
-        }
-
-        /**
-         * Returns the index of the bucket in which {@param s} should appear.
-         * Function is synchronized because underlying routine walks an iterator
-         * whose state is maintained inside the index object.
-         */
-        protected int getBucketIndex(String s) {
-            try {
-                return (Integer) mGetBucketIndexMethod.invoke(mAlphabeticIndex, s);
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-            return super.getBucketIndex(s);
-        }
-
-        /**
-         * Returns the label for the bucket at the given index (as returned by getBucketIndex).
-         */
-        protected String getBucketLabel(int index) {
-            try {
-                return (String) mGetBucketLabelMethod.invoke(mAlphabeticIndex, index);
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-            return super.getBucketLabel(index);
-        }
-    }
-
-    /**
      * Implementation based on {@link AlphabeticIndex}.
      */
-    @TargetApi(Build.VERSION_CODES.N)
     private static class AlphabeticIndexVN extends BaseIndex {
 
         private final AlphabeticIndex.ImmutableIndex mAlphabeticIndex;
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompat.java b/src/com/android/launcher3/compat/LauncherAppsCompat.java
index 407355c..e7d4679 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompat.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompat.java
@@ -83,8 +83,4 @@
             UserHandle user);
     public abstract List<ShortcutConfigActivityInfo> getCustomShortcutActivityList(
             @Nullable PackageUserKey packageUser);
-
-    public void showAppDetailsForProfile(ComponentName component, UserHandle user) {
-        showAppDetailsForProfile(component, user, null, null);
-    }
 }
diff --git a/src/com/android/launcher3/compat/UserManagerCompat.java b/src/com/android/launcher3/compat/UserManagerCompat.java
index e13d2a6..2c0088e 100644
--- a/src/com/android/launcher3/compat/UserManagerCompat.java
+++ b/src/com/android/launcher3/compat/UserManagerCompat.java
@@ -35,14 +35,8 @@
             if (sInstance == null) {
                 if (Utilities.ATLEAST_P) {
                     sInstance = new UserManagerCompatVP(context.getApplicationContext());
-                } else if (Utilities.ATLEAST_NOUGAT_MR1) {
-                    sInstance = new UserManagerCompatVNMr1(context.getApplicationContext());
-                } else if (Utilities.ATLEAST_NOUGAT) {
-                    sInstance = new UserManagerCompatVN(context.getApplicationContext());
-                } else if (Utilities.ATLEAST_MARSHMALLOW) {
-                    sInstance = new UserManagerCompatVM(context.getApplicationContext());
                 } else {
-                    sInstance = new UserManagerCompatVL(context.getApplicationContext());
+                    sInstance = new UserManagerCompatVNMr1(context.getApplicationContext());
                 }
             }
             return sInstance;
diff --git a/src/com/android/launcher3/compat/UserManagerCompatVL.java b/src/com/android/launcher3/compat/UserManagerCompatVL.java
deleted file mode 100644
index 4688052..0000000
--- a/src/com/android/launcher3/compat/UserManagerCompatVL.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.compat;
-
-import android.content.Context;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.util.ArrayMap;
-import android.util.LongSparseArray;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-public class UserManagerCompatVL extends UserManagerCompat {
-
-    protected final UserManager mUserManager;
-
-    protected LongSparseArray<UserHandle> mUsers;
-    // Create a separate reverse map as LongSparseArray.indexOfValue checks if objects are same
-    // and not {@link Object#equals}
-    protected ArrayMap<UserHandle, Long> mUserToSerialMap;
-
-    UserManagerCompatVL(Context context) {
-        mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
-    }
-
-    @Override
-    public long getSerialNumberForUser(UserHandle user) {
-        synchronized (this) {
-            if (mUserToSerialMap != null) {
-                Long serial = mUserToSerialMap.get(user);
-                return serial == null ? 0 : serial;
-            }
-        }
-        return mUserManager.getSerialNumberForUser(user);
-    }
-
-    @Override
-    public UserHandle getUserForSerialNumber(long serialNumber) {
-        synchronized (this) {
-            if (mUsers != null) {
-                return mUsers.get(serialNumber);
-            }
-        }
-        return mUserManager.getUserForSerialNumber(serialNumber);
-    }
-
-    @Override
-    public boolean isQuietModeEnabled(UserHandle user) {
-        return false;
-    }
-
-    @Override
-    public boolean isUserUnlocked(UserHandle user) {
-        return true;
-    }
-
-    @Override
-    public boolean isDemoUser() {
-        return false;
-    }
-
-    @Override
-    public boolean requestQuietModeEnabled(boolean enableQuietMode, UserHandle user) {
-        return false;
-    }
-
-    @Override
-    public boolean isAnyProfileQuietModeEnabled() {
-        return false;
-    }
-
-    @Override
-    public void enableAndResetCache() {
-        synchronized (this) {
-            mUsers = new LongSparseArray<>();
-            mUserToSerialMap = new ArrayMap<>();
-            List<UserHandle> users = mUserManager.getUserProfiles();
-            if (users != null) {
-                for (UserHandle user : users) {
-                    long serial = mUserManager.getSerialNumberForUser(user);
-                    mUsers.put(serial, user);
-                    mUserToSerialMap.put(user, serial);
-                }
-            }
-        }
-    }
-
-    @Override
-    public List<UserHandle> getUserProfiles() {
-        synchronized (this) {
-            if (mUsers != null) {
-                return new ArrayList<>(mUserToSerialMap.keySet());
-            }
-        }
-
-        List<UserHandle> users = mUserManager.getUserProfiles();
-        return users == null ? Collections.<UserHandle>emptyList() : users;
-    }
-
-    @Override
-    public boolean hasWorkProfile() {
-        synchronized (this) {
-            if (mUsers != null) {
-                return mUsers.size() > 1;
-            }
-        }
-        return getUserProfiles().size() > 1;
-    }
-}
-
diff --git a/src/com/android/launcher3/compat/UserManagerCompatVM.java b/src/com/android/launcher3/compat/UserManagerCompatVM.java
deleted file mode 100644
index cf74b37..0000000
--- a/src/com/android/launcher3/compat/UserManagerCompatVM.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.compat;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.os.Build;
-import android.os.UserHandle;
-
-@TargetApi(Build.VERSION_CODES.M)
-public class UserManagerCompatVM extends UserManagerCompatVL {
-
-    UserManagerCompatVM(Context context) {
-        super(context);
-    }
-}
diff --git a/src/com/android/launcher3/compat/UserManagerCompatVN.java b/src/com/android/launcher3/compat/UserManagerCompatVN.java
deleted file mode 100644
index 3733565..0000000
--- a/src/com/android/launcher3/compat/UserManagerCompatVN.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.compat;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.os.Build;
-import android.os.Process;
-import android.os.UserHandle;
-
-import java.util.List;
-
-@TargetApi(Build.VERSION_CODES.N)
-public class UserManagerCompatVN extends UserManagerCompatVM {
-
-    UserManagerCompatVN(Context context) {
-        super(context);
-    }
-
-    @Override
-    public boolean isQuietModeEnabled(UserHandle user) {
-        return mUserManager.isQuietModeEnabled(user);
-    }
-
-    @Override
-    public boolean isUserUnlocked(UserHandle user) {
-        return mUserManager.isUserUnlocked(user);
-    }
-
-    @Override
-    public boolean isAnyProfileQuietModeEnabled() {
-        List<UserHandle> userProfiles = getUserProfiles();
-        for (UserHandle userProfile : userProfiles) {
-            if (Process.myUserHandle().equals(userProfile)) {
-                continue;
-            }
-            if (isQuietModeEnabled(userProfile)) {
-                return true;
-            }
-        }
-        return false;
-    }
-}
-
diff --git a/src/com/android/launcher3/compat/UserManagerCompatVNMr1.java b/src/com/android/launcher3/compat/UserManagerCompatVNMr1.java
index 3f64bc8..18d9053 100644
--- a/src/com/android/launcher3/compat/UserManagerCompatVNMr1.java
+++ b/src/com/android/launcher3/compat/UserManagerCompatVNMr1.java
@@ -19,16 +19,120 @@
 import android.annotation.TargetApi;
 import android.content.Context;
 import android.os.Build;
+import android.os.Process;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.ArrayMap;
+import android.util.LongSparseArray;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
 @TargetApi(Build.VERSION_CODES.N_MR1)
-public class UserManagerCompatVNMr1 extends UserManagerCompatVN {
+public class UserManagerCompatVNMr1 extends UserManagerCompat {
+
+    protected final UserManager mUserManager;
+
+    protected LongSparseArray<UserHandle> mUsers;
+    // Create a separate reverse map as LongSparseArray.indexOfValue checks if objects are same
+    // and not {@link Object#equals}
+    protected ArrayMap<UserHandle, Long> mUserToSerialMap;
 
     UserManagerCompatVNMr1(Context context) {
-        super(context);
+        mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+    }
+
+    @Override
+    public boolean isQuietModeEnabled(UserHandle user) {
+        return mUserManager.isQuietModeEnabled(user);
+    }
+
+    @Override
+    public boolean isUserUnlocked(UserHandle user) {
+        return mUserManager.isUserUnlocked(user);
+    }
+
+    @Override
+    public boolean isAnyProfileQuietModeEnabled() {
+        List<UserHandle> userProfiles = getUserProfiles();
+        for (UserHandle userProfile : userProfiles) {
+            if (Process.myUserHandle().equals(userProfile)) {
+                continue;
+            }
+            if (isQuietModeEnabled(userProfile)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public long getSerialNumberForUser(UserHandle user) {
+        synchronized (this) {
+            if (mUserToSerialMap != null) {
+                Long serial = mUserToSerialMap.get(user);
+                return serial == null ? 0 : serial;
+            }
+        }
+        return mUserManager.getSerialNumberForUser(user);
+    }
+
+    @Override
+    public UserHandle getUserForSerialNumber(long serialNumber) {
+        synchronized (this) {
+            if (mUsers != null) {
+                return mUsers.get(serialNumber);
+            }
+        }
+        return mUserManager.getUserForSerialNumber(serialNumber);
     }
 
     @Override
     public boolean isDemoUser() {
         return mUserManager.isDemoUser();
     }
+
+    @Override
+    public boolean requestQuietModeEnabled(boolean enableQuietMode, UserHandle user) {
+        return false;
+    }
+
+    @Override
+    public void enableAndResetCache() {
+        synchronized (this) {
+            mUsers = new LongSparseArray<>();
+            mUserToSerialMap = new ArrayMap<>();
+            List<UserHandle> users = mUserManager.getUserProfiles();
+            if (users != null) {
+                for (UserHandle user : users) {
+                    long serial = mUserManager.getSerialNumberForUser(user);
+                    mUsers.put(serial, user);
+                    mUserToSerialMap.put(user, serial);
+                }
+            }
+        }
+    }
+
+    @Override
+    public List<UserHandle> getUserProfiles() {
+        synchronized (this) {
+            if (mUsers != null) {
+                return new ArrayList<>(mUserToSerialMap.keySet());
+            }
+        }
+
+        List<UserHandle> users = mUserManager.getUserProfiles();
+        return users == null ? Collections.<UserHandle>emptyList() : users;
+    }
+
+    @Override
+    public boolean hasWorkProfile() {
+        synchronized (this) {
+            if (mUsers != null) {
+                return mUsers.size() > 1;
+            }
+        }
+        return getUserProfiles().size() > 1;
+    }
 }
diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java
index 79819cc..5ac9867 100644
--- a/src/com/android/launcher3/dragndrop/AddItemActivity.java
+++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java
@@ -57,13 +57,14 @@
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 import com.android.launcher3.util.InstantAppResolver;
 import com.android.launcher3.util.LooperExecutor;
-import com.android.launcher3.util.Provider;
 import com.android.launcher3.views.BaseDragLayer;
 import com.android.launcher3.widget.PendingAddShortcutInfo;
 import com.android.launcher3.widget.PendingAddWidgetInfo;
 import com.android.launcher3.widget.WidgetHostViewLoader;
 import com.android.launcher3.widget.WidgetImageView;
 
+import java.util.function.Supplier;
+
 @TargetApi(Build.VERSION_CODES.O)
 public class AddItemActivity extends BaseActivity implements OnLongClickListener, OnTouchListener {
 
@@ -220,7 +221,7 @@
         return true;
     }
 
-    private void applyWidgetItemAsync(final Provider<WidgetItem> itemProvider) {
+    private void applyWidgetItemAsync(final Supplier<WidgetItem> itemProvider) {
         new AsyncTask<Void, Void, WidgetItem>() {
             @Override
             protected WidgetItem doInBackground(Void... voids) {
diff --git a/src/com/android/launcher3/dragndrop/DragDriver.java b/src/com/android/launcher3/dragndrop/DragDriver.java
index d8a3024..84fc94d 100644
--- a/src/com/android/launcher3/dragndrop/DragDriver.java
+++ b/src/com/android/launcher3/dragndrop/DragDriver.java
@@ -19,8 +19,8 @@
 import android.content.Context;
 import android.view.DragEvent;
 import android.view.MotionEvent;
+
 import com.android.launcher3.DropTarget.DragObject;
-import com.android.launcher3.Utilities;
 
 /**
  * Base class for driving a drag/drop operation.
@@ -83,7 +83,7 @@
 
     public static DragDriver create(Context context, DragController dragController,
             DragObject dragObject, DragOptions options) {
-        if (Utilities.ATLEAST_NOUGAT && options.systemDndStartPoint != null) {
+        if (options.systemDndStartPoint != null) {
             return new SystemDragDriver(dragController, context, dragObject);
         } else {
             return new InternalDragDriver(dragController);
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 51c2998..6fc81c9 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -34,11 +34,8 @@
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Pair;
-import android.view.ActionMode;
 import android.view.FocusFinder;
 import android.view.KeyEvent;
-import android.view.Menu;
-import android.view.MenuItem;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewDebug;
@@ -65,7 +62,6 @@
 import com.android.launcher3.PagedView;
 import com.android.launcher3.R;
 import com.android.launcher3.ShortcutInfo;
-import com.android.launcher3.Utilities;
 import com.android.launcher3.Workspace.ItemOperator;
 import com.android.launcher3.accessibility.AccessibleDragListenerAdapter;
 import com.android.launcher3.config.FeatureFlags;
@@ -214,27 +210,6 @@
         mFolderName = findViewById(R.id.folder_name);
         mFolderName.setOnBackKeyListener(this);
         mFolderName.setOnFocusChangeListener(this);
-
-        if (!Utilities.ATLEAST_MARSHMALLOW) {
-            // We disable action mode in older OSes where floating selection menu is not yet
-            // available.
-            mFolderName.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
-                public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
-                    return false;
-                }
-
-                public boolean onCreateActionMode(ActionMode mode, Menu menu) {
-                    return false;
-                }
-
-                public void onDestroyActionMode(ActionMode mode) {
-                }
-
-                public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
-                    return false;
-                }
-            });
-        }
         mFolderName.setOnEditorActionListener(this);
         mFolderName.setSelectAllOnFocus(true);
         mFolderName.setInputType(mFolderName.getInputType()
diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java
index 4b54bc3..fb0a367 100644
--- a/src/com/android/launcher3/icons/IconCache.java
+++ b/src/com/android/launcher3/icons/IconCache.java
@@ -47,7 +47,8 @@
 import com.android.launcher3.model.PackageItemInfo;
 import com.android.launcher3.util.InstantAppResolver;
 import com.android.launcher3.util.Preconditions;
-import com.android.launcher3.util.Provider;
+
+import java.util.function.Supplier;
 
 import androidx.annotation.NonNull;
 
@@ -156,7 +157,7 @@
      */
     public synchronized void updateTitleAndIcon(AppInfo application) {
         CacheEntry entry = cacheLocked(application.componentName,
-                application.user, Provider.of(null), mLauncherActivityInfoCachingLogic,
+                application.user, () -> null, mLauncherActivityInfoCachingLogic,
                 false, application.usingLowResIcon());
         if (entry.icon != null && !isDefaultIcon(entry.icon, application.user)) {
             applyCacheEntry(entry, application);
@@ -169,7 +170,7 @@
     public synchronized void getTitleAndIcon(ItemInfoWithIcon info,
             LauncherActivityInfo activityInfo, boolean useLowResIcon) {
         // If we already have activity info, no need to use package icon
-        getTitleAndIcon(info, Provider.of(activityInfo), false, useLowResIcon);
+        getTitleAndIcon(info, () -> activityInfo, false, useLowResIcon);
     }
 
     /**
@@ -191,7 +192,7 @@
     }
 
     public synchronized String getTitleNoCache(ComponentWithLabel info) {
-        CacheEntry entry = cacheLocked(info.getComponent(), info.getUser(), Provider.of(info),
+        CacheEntry entry = cacheLocked(info.getComponent(), info.getUser(), () -> info,
                 mComponentWithLabelCachingLogic, false /* usePackageIcon */,
                 true /* useLowResIcon */, false /* addToMemCache */);
         return Utilities.trim(entry.title);
@@ -202,7 +203,7 @@
      */
     private synchronized void getTitleAndIcon(
             @NonNull ItemInfoWithIcon infoInOut,
-            @NonNull Provider<LauncherActivityInfo> activityInfoProvider,
+            @NonNull Supplier<LauncherActivityInfo> activityInfoProvider,
             boolean usePkgIcon, boolean useLowResIcon) {
         CacheEntry entry = cacheLocked(infoInOut.getTargetComponent(), infoInOut.user,
                 activityInfoProvider, mLauncherActivityInfoCachingLogic, usePkgIcon, useLowResIcon);
diff --git a/src/com/android/launcher3/icons/LauncherIcons.java b/src/com/android/launcher3/icons/LauncherIcons.java
index f0a63ba..75f76d9 100644
--- a/src/com/android/launcher3/icons/LauncherIcons.java
+++ b/src/com/android/launcher3/icons/LauncherIcons.java
@@ -31,9 +31,10 @@
 import com.android.launcher3.model.PackageItemInfo;
 import com.android.launcher3.shortcuts.DeepShortcutManager;
 import com.android.launcher3.shortcuts.ShortcutInfoCompat;
-import com.android.launcher3.util.Provider;
 import com.android.launcher3.util.Themes;
 
+import java.util.function.Supplier;
+
 import androidx.annotation.Nullable;
 
 /**
@@ -114,7 +115,7 @@
     }
 
     public BitmapInfo createShortcutIcon(ShortcutInfoCompat shortcutInfo,
-            boolean badged, @Nullable Provider<ItemInfoWithIcon> fallbackIconProvider) {
+            boolean badged, @Nullable Supplier<ItemInfoWithIcon> fallbackIconProvider) {
         Drawable unbadgedDrawable = DeepShortcutManager.getInstance(mContext)
                 .getShortcutIconDrawable(shortcutInfo, mFillResIconDpi);
         IconCache cache = LauncherAppState.getInstance(mContext).getIconCache();
diff --git a/src/com/android/launcher3/model/GridSizeMigrationTask.java b/src/com/android/launcher3/model/GridSizeMigrationTask.java
index 1c7bffa..243b286 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationTask.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationTask.java
@@ -47,8 +47,6 @@
  */
 public class GridSizeMigrationTask {
 
-    public static boolean ENABLED = Utilities.ATLEAST_NOUGAT;
-
     private static final String TAG = "GridSizeMigrationTask";
     private static final boolean DEBUG = true;
 
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index cfabc10..4fe0c85 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -49,10 +49,8 @@
 import com.android.launcher3.LauncherAppWidgetInfo;
 import com.android.launcher3.LauncherModel;
 import com.android.launcher3.LauncherSettings;
-import com.android.launcher3.LauncherSettings.Favorites;
 import com.android.launcher3.ShortcutInfo;
 import com.android.launcher3.Utilities;
-import com.android.launcher3.Workspace;
 import com.android.launcher3.compat.AppWidgetManagerCompat;
 import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.compat.PackageInstallerCompat;
@@ -75,7 +73,6 @@
 import com.android.launcher3.util.LooperIdleLock;
 import com.android.launcher3.util.MultiHashMap;
 import com.android.launcher3.util.PackageManagerHelper;
-import com.android.launcher3.util.Provider;
 import com.android.launcher3.util.TraceHelper;
 
 import java.util.ArrayList;
@@ -85,6 +82,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.CancellationException;
+import java.util.function.Supplier;
 
 /**
  * Runnable for the thread that loads the contents of the launcher:
@@ -271,8 +269,7 @@
             clearDb = true;
         }
 
-        if (!clearDb && GridSizeMigrationTask.ENABLED &&
-                !GridSizeMigrationTask.migrateGridIfNeeded(context)) {
+        if (!clearDb && !GridSizeMigrationTask.migrateGridIfNeeded(context)) {
             // Migration failed. Clear workspace.
             clearDb = true;
         }
@@ -497,7 +494,7 @@
                                     LauncherIcons li = LauncherIcons.obtain(context);
                                     // If the pinned deep shortcut is no longer published,
                                     // use the last saved icon instead of the default.
-                                    Provider<ItemInfoWithIcon> fallbackIconProvider = () ->
+                                    Supplier<ItemInfoWithIcon> fallbackIconProvider = () ->
                                             c.loadIcon(finalInfo, li) ? finalInfo : null;
                                     info.applyFrom(li.createShortcutIcon(pinnedShortcut,
                                             true /* badged */, fallbackIconProvider));
diff --git a/src/com/android/launcher3/model/ShortcutsChangedTask.java b/src/com/android/launcher3/model/ShortcutsChangedTask.java
index 4e699f7..1644c89 100644
--- a/src/com/android/launcher3/model/ShortcutsChangedTask.java
+++ b/src/com/android/launcher3/model/ShortcutsChangedTask.java
@@ -29,7 +29,6 @@
 import com.android.launcher3.shortcuts.ShortcutKey;
 import com.android.launcher3.util.ItemInfoMatcher;
 import com.android.launcher3.util.MultiHashMap;
-import com.android.launcher3.util.Provider;
 
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -97,7 +96,7 @@
                     // keep the current icon instead of reverting to the default icon.
                     LauncherIcons li = LauncherIcons.obtain(context);
                     shortcutInfo.applyFrom(li.createShortcutIcon(fullDetails, true,
-                            Provider.of(shortcutInfo)));
+                            () -> shortcutInfo));
                     li.recycle();
                     updatedShortcutInfos.add(shortcutInfo);
                 }
diff --git a/src/com/android/launcher3/model/UserLockStateChangedTask.java b/src/com/android/launcher3/model/UserLockStateChangedTask.java
index 59f4284..7c4e454 100644
--- a/src/com/android/launcher3/model/UserLockStateChangedTask.java
+++ b/src/com/android/launcher3/model/UserLockStateChangedTask.java
@@ -32,7 +32,6 @@
 import com.android.launcher3.shortcuts.ShortcutKey;
 import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.ItemInfoMatcher;
-import com.android.launcher3.util.Provider;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -95,7 +94,7 @@
                     // If the shortcut is pinned but no longer has an icon in the system,
                     // keep the current icon instead of reverting to the default icon.
                     LauncherIcons li = LauncherIcons.obtain(context);
-                    si.applyFrom(li.createShortcutIcon(shortcut, true, Provider.of(si)));
+                    si.applyFrom(li.createShortcutIcon(shortcut, true, () -> si));
                     li.recycle();
                 } else {
                     si.runtimeStatusFlags |= FLAG_DISABLED_LOCKED_USER;
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 0c098da..288d568 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -77,7 +77,6 @@
 /**
  * A container for shortcuts to deep links and notifications associated with an app.
  */
-@TargetApi(Build.VERSION_CODES.N)
 public class PopupContainerWithArrow extends ArrowPopup implements DragSource,
         DragController.DragListener, View.OnLongClickListener,
         View.OnTouchListener {
diff --git a/src/com/android/launcher3/shortcuts/ShortcutCache.java b/src/com/android/launcher3/shortcuts/ShortcutCache.java
deleted file mode 100644
index 5742d1d..0000000
--- a/src/com/android/launcher3/shortcuts/ShortcutCache.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.shortcuts;
-
-import android.annotation.TargetApi;
-import android.os.Build;
-import android.os.UserHandle;
-import android.util.ArrayMap;
-import android.util.LruCache;
-import java.util.List;
-
-/**
- * Loads {@link ShortcutInfoCompat}s on demand (e.g. when launcher
- * loads for pinned shortcuts and on long-press for dynamic shortcuts), and caches them
- * for handful of apps in an LruCache while launcher lives.
- */
-@TargetApi(Build.VERSION_CODES.N)
-public class ShortcutCache {
-    private static final int CACHE_SIZE = 30; // Max number shortcuts we cache.
-
-    private final LruCache<ShortcutKey, ShortcutInfoCompat> mCachedShortcuts;
-    // We always keep pinned shortcuts in the cache.
-    private final ArrayMap<ShortcutKey, ShortcutInfoCompat> mPinnedShortcuts;
-
-    public ShortcutCache() {
-        mCachedShortcuts = new LruCache<>(CACHE_SIZE);
-        mPinnedShortcuts = new ArrayMap<>();
-    }
-
-    /**
-     * Removes shortcuts from the cache when shortcuts change for a given package.
-     *
-     * Returns a map of ids to their evicted shortcuts.
-     *
-     * @see android.content.pm.LauncherApps.Callback#onShortcutsChanged(String, List, UserHandle).
-     */
-    public void removeShortcuts(List<ShortcutInfoCompat> shortcuts) {
-        for (ShortcutInfoCompat shortcut : shortcuts) {
-            ShortcutKey key = ShortcutKey.fromInfo(shortcut);
-            mCachedShortcuts.remove(key);
-            mPinnedShortcuts.remove(key);
-        }
-    }
-
-    public ShortcutInfoCompat get(ShortcutKey key) {
-        if (mPinnedShortcuts.containsKey(key)) {
-            return mPinnedShortcuts.get(key);
-        }
-        return mCachedShortcuts.get(key);
-    }
-
-    public void put(ShortcutKey key, ShortcutInfoCompat shortcut) {
-        if (shortcut.isPinned()) {
-            mPinnedShortcuts.put(key, shortcut);
-        } else {
-            mCachedShortcuts.put(key, shortcut);
-        }
-    }
-}
diff --git a/src/com/android/launcher3/shortcuts/ShortcutInfoCompat.java b/src/com/android/launcher3/shortcuts/ShortcutInfoCompat.java
index 325777d..e5bd002 100644
--- a/src/com/android/launcher3/shortcuts/ShortcutInfoCompat.java
+++ b/src/com/android/launcher3/shortcuts/ShortcutInfoCompat.java
@@ -16,12 +16,10 @@
 
 package com.android.launcher3.shortcuts;
 
-import android.annotation.TargetApi;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ShortcutInfo;
-import android.os.Build;
 import android.os.UserHandle;
 
 import com.android.launcher3.R;
@@ -31,7 +29,6 @@
  *
  * Not to be confused with {@link com.android.launcher3.ShortcutInfo}.
  */
-@TargetApi(Build.VERSION_CODES.N)
 public class ShortcutInfoCompat {
     private static final String INTENT_CATEGORY = "com.android.launcher3.DEEP_SHORTCUT";
     private static final String EXTRA_BADGEPKG = "badge_package";
@@ -42,7 +39,6 @@
         mShortcutInfo = shortcutInfo;
     }
 
-    @TargetApi(Build.VERSION_CODES.N)
     public Intent makeIntent() {
         return new Intent(Intent.ACTION_MAIN)
                 .addCategory(INTENT_CATEGORY)
diff --git a/src/com/android/launcher3/states/RotationHelper.java b/src/com/android/launcher3/states/RotationHelper.java
index 65103f6..fb41ea1 100644
--- a/src/com/android/launcher3/states/RotationHelper.java
+++ b/src/com/android/launcher3/states/RotationHelper.java
@@ -20,8 +20,6 @@
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 import static android.util.DisplayMetrics.DENSITY_DEVICE_STABLE;
 
-import static com.android.launcher3.Utilities.ATLEAST_NOUGAT;
-
 import android.app.Activity;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
@@ -39,15 +37,12 @@
     public static final String ALLOW_ROTATION_PREFERENCE_KEY = "pref_allowRotation";
 
     public static boolean getAllowRotationDefaultValue() {
-        if (ATLEAST_NOUGAT) {
-            // If the device was scaled, used the original dimensions to determine if rotation
-            // is allowed of not.
-            Resources res = Resources.getSystem();
-            int originalSmallestWidth = res.getConfiguration().smallestScreenWidthDp
-                    * res.getDisplayMetrics().densityDpi / DENSITY_DEVICE_STABLE;
-            return originalSmallestWidth >= 600;
-        }
-        return false;
+        // If the device was scaled, used the original dimensions to determine if rotation
+        // is allowed of not.
+        Resources res = Resources.getSystem();
+        int originalSmallestWidth = res.getConfiguration().smallestScreenWidthDp
+                * res.getDisplayMetrics().densityDpi / DENSITY_DEVICE_STABLE;
+        return originalSmallestWidth >= 600;
     }
 
     public static final int REQUEST_NONE = 0;
diff --git a/src/com/android/launcher3/touch/TouchEventTranslator.java b/src/com/android/launcher3/touch/TouchEventTranslator.java
index bf0c84c..3fcda90 100644
--- a/src/com/android/launcher3/touch/TouchEventTranslator.java
+++ b/src/com/android/launcher3/touch/TouchEventTranslator.java
@@ -23,7 +23,7 @@
 import android.view.MotionEvent.PointerCoords;
 import android.view.MotionEvent.PointerProperties;
 
-import com.android.launcher3.Utilities.Consumer;
+import java.util.function.Consumer;
 
 /**
  * To minimize the size of the MotionEvent, historic events are not copied and passed via the
diff --git a/src/com/android/launcher3/util/ConfigMonitor.java b/src/com/android/launcher3/util/ConfigMonitor.java
index 607afab..12280f8 100644
--- a/src/com/android/launcher3/util/ConfigMonitor.java
+++ b/src/com/android/launcher3/util/ConfigMonitor.java
@@ -29,9 +29,9 @@
 import android.view.Display;
 import android.view.WindowManager;
 
-import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.MainThreadExecutor;
-import com.android.launcher3.Utilities.Consumer;
+
+import java.util.function.Consumer;
 
 /**
  * {@link BroadcastReceiver} which watches configuration changes and
diff --git a/src/com/android/launcher3/util/LooperIdleLock.java b/src/com/android/launcher3/util/LooperIdleLock.java
index 35cac14..2896535 100644
--- a/src/com/android/launcher3/util/LooperIdleLock.java
+++ b/src/com/android/launcher3/util/LooperIdleLock.java
@@ -19,8 +19,6 @@
 import android.os.Looper;
 import android.os.MessageQueue;
 
-import com.android.launcher3.Utilities;
-
 /**
  * Utility class to block execution until the UI looper is idle.
  */
@@ -33,13 +31,7 @@
     public LooperIdleLock(Object lock, Looper looper) {
         mLock = lock;
         mIsLocked = true;
-        if (Utilities.ATLEAST_MARSHMALLOW) {
-            looper.getQueue().addIdleHandler(this);
-        } else {
-            // Looper.myQueue() only gives the current queue. Move the execution to the UI thread
-            // so that the IdleHandler is attached to the correct message queue.
-            new LooperExecutor(looper).execute(this);
-        }
+        looper.getQueue().addIdleHandler(this);
     }
 
     @Override
diff --git a/src/com/android/launcher3/util/PackageManagerHelper.java b/src/com/android/launcher3/util/PackageManagerHelper.java
index 0b3b632..d71bd15 100644
--- a/src/com/android/launcher3/util/PackageManagerHelper.java
+++ b/src/com/android/launcher3/util/PackageManagerHelper.java
@@ -37,13 +37,11 @@
 
 import com.android.launcher3.AppInfo;
 import com.android.launcher3.ItemInfo;
-import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAppWidgetInfo;
 import com.android.launcher3.PendingAddItemInfo;
 import com.android.launcher3.PromiseAppInfo;
 import com.android.launcher3.R;
 import com.android.launcher3.ShortcutInfo;
-import com.android.launcher3.Utilities;
 import com.android.launcher3.compat.LauncherAppsCompat;
 
 import java.net.URISyntaxException;
@@ -100,14 +98,7 @@
      * {@link android.app.admin.DevicePolicyManager#isPackageSuspended}.
      */
     public static boolean isAppSuspended(ApplicationInfo info) {
-        // The value of FLAG_SUSPENDED was reused by a hidden constant
-        // ApplicationInfo.FLAG_PRIVILEGED prior to N, so only check for suspended flag on N
-        // or later.
-        if (Utilities.ATLEAST_NOUGAT) {
-            return (info.flags & ApplicationInfo.FLAG_SUSPENDED) != 0;
-        } else {
-            return false;
-        }
+        return (info.flags & ApplicationInfo.FLAG_SUSPENDED) != 0;
     }
 
     /**
@@ -136,11 +127,6 @@
             return false;
         }
 
-        if (!Utilities.ATLEAST_MARSHMALLOW) {
-            // These checks are sufficient for below M devices.
-            return true;
-        }
-
         // On M and above also check AppOpsManager for compatibility mode permissions.
         if (TextUtils.isEmpty(AppOpsManager.permissionToOp(target.activityInfo.permission))) {
             // There is no app-op for this permission, which could have been disabled.
diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java
index 673b3cc..508695b 100644
--- a/src/com/android/launcher3/widget/BaseWidgetSheet.java
+++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java
@@ -161,7 +161,7 @@
 
     private static View createColorScrim(Context context) {
         View view = new View(context);
-        if (Utilities.ATLEAST_NOUGAT) view.forceHasOverlappingRendering(false);
+        view.forceHasOverlappingRendering(false);
 
         WallpaperColorInfo colors = WallpaperColorInfo.getInstance(context);
         int alpha = context.getResources().getInteger(R.integer.extracted_color_gradient_alpha);
diff --git a/src_shortcuts_overrides/com/android/launcher3/shortcuts/DeepShortcutManager.java b/src_shortcuts_overrides/com/android/launcher3/shortcuts/DeepShortcutManager.java
index e70aac6..6c0c429 100644
--- a/src_shortcuts_overrides/com/android/launcher3/shortcuts/DeepShortcutManager.java
+++ b/src_shortcuts_overrides/com/android/launcher3/shortcuts/DeepShortcutManager.java
@@ -16,7 +16,6 @@
 
 package com.android.launcher3.shortcuts;
 
-import android.annotation.TargetApi;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.LauncherApps;
@@ -30,7 +29,6 @@
 
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.LauncherSettings;
-import com.android.launcher3.Utilities;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -94,7 +92,6 @@
      * Gets all the manifest and dynamic shortcuts associated with the given package and user,
      * to be displayed in the shortcuts container on long press.
      */
-    @TargetApi(25)
     public List<ShortcutInfoCompat> queryForShortcutsContainer(ComponentName activity,
             UserHandle user) {
         return query(ShortcutQuery.FLAG_MATCH_MANIFEST | ShortcutQuery.FLAG_MATCH_DYNAMIC,
@@ -105,21 +102,18 @@
      * Removes the given shortcut from the current list of pinned shortcuts.
      * (Runs on background thread)
      */
-    @TargetApi(25)
     public void unpinShortcut(final ShortcutKey key) {
-        if (Utilities.ATLEAST_NOUGAT_MR1) {
-            String packageName = key.componentName.getPackageName();
-            String id = key.getId();
-            UserHandle user = key.user;
-            List<String> pinnedIds = extractIds(queryForPinnedShortcuts(packageName, user));
-            pinnedIds.remove(id);
-            try {
-                mLauncherApps.pinShortcuts(packageName, pinnedIds, user);
-                mWasLastCallSuccess = true;
-            } catch (SecurityException|IllegalStateException e) {
-                Log.w(TAG, "Failed to unpin shortcut", e);
-                mWasLastCallSuccess = false;
-            }
+        String packageName = key.componentName.getPackageName();
+        String id = key.getId();
+        UserHandle user = key.user;
+        List<String> pinnedIds = extractIds(queryForPinnedShortcuts(packageName, user));
+        pinnedIds.remove(id);
+        try {
+            mLauncherApps.pinShortcuts(packageName, pinnedIds, user);
+            mWasLastCallSuccess = true;
+        } catch (SecurityException|IllegalStateException e) {
+            Log.w(TAG, "Failed to unpin shortcut", e);
+            mWasLastCallSuccess = false;
         }
     }
 
@@ -127,51 +121,42 @@
      * Adds the given shortcut to the current list of pinned shortcuts.
      * (Runs on background thread)
      */
-    @TargetApi(25)
     public void pinShortcut(final ShortcutKey key) {
-        if (Utilities.ATLEAST_NOUGAT_MR1) {
-            String packageName = key.componentName.getPackageName();
-            String id = key.getId();
-            UserHandle user = key.user;
-            List<String> pinnedIds = extractIds(queryForPinnedShortcuts(packageName, user));
-            pinnedIds.add(id);
-            try {
-                mLauncherApps.pinShortcuts(packageName, pinnedIds, user);
-                mWasLastCallSuccess = true;
-            } catch (SecurityException|IllegalStateException e) {
-                Log.w(TAG, "Failed to pin shortcut", e);
-                mWasLastCallSuccess = false;
-            }
+        String packageName = key.componentName.getPackageName();
+        String id = key.getId();
+        UserHandle user = key.user;
+        List<String> pinnedIds = extractIds(queryForPinnedShortcuts(packageName, user));
+        pinnedIds.add(id);
+        try {
+            mLauncherApps.pinShortcuts(packageName, pinnedIds, user);
+            mWasLastCallSuccess = true;
+        } catch (SecurityException|IllegalStateException e) {
+            Log.w(TAG, "Failed to pin shortcut", e);
+            mWasLastCallSuccess = false;
         }
     }
 
-    @TargetApi(25)
     public void startShortcut(String packageName, String id, Rect sourceBounds,
           Bundle startActivityOptions, UserHandle user) {
-        if (Utilities.ATLEAST_NOUGAT_MR1) {
-            try {
-                mLauncherApps.startShortcut(packageName, id, sourceBounds,
-                        startActivityOptions, user);
-                mWasLastCallSuccess = true;
-            } catch (SecurityException|IllegalStateException e) {
-                Log.e(TAG, "Failed to start shortcut", e);
-                mWasLastCallSuccess = false;
-            }
+        try {
+            mLauncherApps.startShortcut(packageName, id, sourceBounds,
+                    startActivityOptions, user);
+            mWasLastCallSuccess = true;
+        } catch (SecurityException|IllegalStateException e) {
+            Log.e(TAG, "Failed to start shortcut", e);
+            mWasLastCallSuccess = false;
         }
     }
 
-    @TargetApi(25)
     public Drawable getShortcutIconDrawable(ShortcutInfoCompat shortcutInfo, int density) {
-        if (Utilities.ATLEAST_NOUGAT_MR1) {
-            try {
-                Drawable icon = mLauncherApps.getShortcutIconDrawable(
-                        shortcutInfo.getShortcutInfo(), density);
-                mWasLastCallSuccess = true;
-                return icon;
-            } catch (SecurityException|IllegalStateException e) {
-                Log.e(TAG, "Failed to get shortcut icon", e);
-                mWasLastCallSuccess = false;
-            }
+        try {
+            Drawable icon = mLauncherApps.getShortcutIconDrawable(
+                    shortcutInfo.getShortcutInfo(), density);
+            mWasLastCallSuccess = true;
+            return icon;
+        } catch (SecurityException|IllegalStateException e) {
+            Log.e(TAG, "Failed to get shortcut icon", e);
+            mWasLastCallSuccess = false;
         }
         return null;
     }
@@ -208,46 +193,38 @@
      *
      * TODO: Use the cache to optimize this so we don't make an RPC every time.
      */
-    @TargetApi(25)
     private List<ShortcutInfoCompat> query(int flags, String packageName,
             ComponentName activity, List<String> shortcutIds, UserHandle user) {
-        if (Utilities.ATLEAST_NOUGAT_MR1) {
-            ShortcutQuery q = new ShortcutQuery();
-            q.setQueryFlags(flags);
-            if (packageName != null) {
-                q.setPackage(packageName);
-                q.setActivity(activity);
-                q.setShortcutIds(shortcutIds);
-            }
-            List<ShortcutInfo> shortcutInfos = null;
-            try {
-                shortcutInfos = mLauncherApps.getShortcuts(q, user);
-                mWasLastCallSuccess = true;
-            } catch (SecurityException|IllegalStateException e) {
-                Log.e(TAG, "Failed to query for shortcuts", e);
-                mWasLastCallSuccess = false;
-            }
-            if (shortcutInfos == null) {
-                return Collections.EMPTY_LIST;
-            }
-            List<ShortcutInfoCompat> shortcutInfoCompats = new ArrayList<>(shortcutInfos.size());
-            for (ShortcutInfo shortcutInfo : shortcutInfos) {
-                shortcutInfoCompats.add(new ShortcutInfoCompat(shortcutInfo));
-            }
-            return shortcutInfoCompats;
-        } else {
+        ShortcutQuery q = new ShortcutQuery();
+        q.setQueryFlags(flags);
+        if (packageName != null) {
+            q.setPackage(packageName);
+            q.setActivity(activity);
+            q.setShortcutIds(shortcutIds);
+        }
+        List<ShortcutInfo> shortcutInfos = null;
+        try {
+            shortcutInfos = mLauncherApps.getShortcuts(q, user);
+            mWasLastCallSuccess = true;
+        } catch (SecurityException|IllegalStateException e) {
+            Log.e(TAG, "Failed to query for shortcuts", e);
+            mWasLastCallSuccess = false;
+        }
+        if (shortcutInfos == null) {
             return Collections.EMPTY_LIST;
         }
+        List<ShortcutInfoCompat> shortcutInfoCompats = new ArrayList<>(shortcutInfos.size());
+        for (ShortcutInfo shortcutInfo : shortcutInfos) {
+            shortcutInfoCompats.add(new ShortcutInfoCompat(shortcutInfo));
+        }
+        return shortcutInfoCompats;
     }
 
-    @TargetApi(25)
     public boolean hasHostPermission() {
-        if (Utilities.ATLEAST_NOUGAT_MR1) {
-            try {
-                return mLauncherApps.hasShortcutHostPermission();
-            } catch (SecurityException|IllegalStateException e) {
-                Log.e(TAG, "Failed to make shortcut manager call", e);
-            }
+        try {
+            return mLauncherApps.hasShortcutHostPermission();
+        } catch (SecurityException|IllegalStateException e) {
+            Log.e(TAG, "Failed to make shortcut manager call", e);
         }
         return false;
     }
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/dynamicui/WallpaperManagerCompatVL.java b/src_ui_overrides/com/android/launcher3/uioverrides/dynamicui/WallpaperManagerCompatVL.java
index 6808859..500fdc3 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/dynamicui/WallpaperManagerCompatVL.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/dynamicui/WallpaperManagerCompatVL.java
@@ -44,7 +44,6 @@
 import android.util.Log;
 import android.util.Pair;
 
-import com.android.launcher3.Utilities;
 import com.android.launcher3.icons.ColorExtractor;
 
 import java.io.IOException;
@@ -61,6 +60,8 @@
     private static final String ACTION_EXTRACTION_COMPLETE =
             "com.android.launcher3.uioverrides.dynamicui.WallpaperManagerCompatVL.EXTRACTION_COMPLETE";
 
+    public static final int WALLPAPER_COMPAT_JOB_ID = 1;
+
     private final ArrayList<OnColorsChangedListenerCompat> mListeners = new ArrayList<>();
 
     private final Context mContext;
@@ -122,7 +123,7 @@
     }
 
     private void reloadColors() {
-        JobInfo job = new JobInfo.Builder(Utilities.WALLPAPER_COMPAT_JOB_ID,
+        JobInfo job = new JobInfo.Builder(WALLPAPER_COMPAT_JOB_ID,
                 new ComponentName(mContext, ColorExtractionService.class))
                 .setMinimumLatency(0).build();
         ((JobScheduler) mContext.getSystemService(Context.JOB_SCHEDULER_SERVICE)).schedule(job);
@@ -137,9 +138,6 @@
     }
 
     private static final int getWallpaperId(Context context) {
-        if (!Utilities.ATLEAST_NOUGAT) {
-            return -1;
-        }
         return context.getSystemService(WallpaperManager.class).getWallpaperId(FLAG_SYSTEM);
     }
 
@@ -215,27 +213,25 @@
                 // For live wallpaper, extract colors from thumbnail
                 drawable = info.loadThumbnail(getPackageManager());
             } else {
-                if (Utilities.ATLEAST_NOUGAT) {
-                    try (ParcelFileDescriptor fd = wm.getWallpaperFile(FLAG_SYSTEM)) {
-                        BitmapRegionDecoder decoder = BitmapRegionDecoder
-                                .newInstance(fd.getFileDescriptor(), false);
+                try (ParcelFileDescriptor fd = wm.getWallpaperFile(FLAG_SYSTEM)) {
+                    BitmapRegionDecoder decoder = BitmapRegionDecoder
+                            .newInstance(fd.getFileDescriptor(), false);
 
-                        int requestedArea = decoder.getWidth() * decoder.getHeight();
-                        BitmapFactory.Options options = new BitmapFactory.Options();
+                    int requestedArea = decoder.getWidth() * decoder.getHeight();
+                    BitmapFactory.Options options = new BitmapFactory.Options();
 
-                        if (requestedArea > MAX_WALLPAPER_EXTRACTION_AREA) {
-                            double areaRatio =
-                                    (double) requestedArea / MAX_WALLPAPER_EXTRACTION_AREA;
-                            double nearestPowOf2 =
-                                    Math.floor(Math.log(areaRatio) / (2 * Math.log(2)));
-                            options.inSampleSize = (int) Math.pow(2, nearestPowOf2);
-                        }
-                        Rect region = new Rect(0, 0, decoder.getWidth(), decoder.getHeight());
-                        bitmap = decoder.decodeRegion(region, options);
-                        decoder.recycle();
-                    } catch (IOException | NullPointerException e) {
-                        Log.e(TAG, "Fetching partial bitmap failed, trying old method", e);
+                    if (requestedArea > MAX_WALLPAPER_EXTRACTION_AREA) {
+                        double areaRatio =
+                                (double) requestedArea / MAX_WALLPAPER_EXTRACTION_AREA;
+                        double nearestPowOf2 =
+                                Math.floor(Math.log(areaRatio) / (2 * Math.log(2)));
+                        options.inSampleSize = (int) Math.pow(2, nearestPowOf2);
                     }
+                    Rect region = new Rect(0, 0, decoder.getWidth(), decoder.getHeight());
+                    bitmap = decoder.decodeRegion(region, options);
+                    decoder.recycle();
+                } catch (IOException | NullPointerException e) {
+                    Log.e(TAG, "Fetching partial bitmap failed, trying old method", e);
                 }
                 if (bitmap == null) {
                     drawable = wm.getDrawable();
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index ebab122..24b5b02 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -18,7 +18,7 @@
     xmlns:tools="http://schemas.android.com/tools"
     package="com.android.launcher3.tests">
 
-    <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="21"
+    <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="25"
               tools:overrideLibrary="android.support.test.uiautomator.v18"/>
 
     <application android:debuggable="true">
diff --git a/tests/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithmTest.java b/tests/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithmTest.java
index afbedba..293b04a 100644
--- a/tests/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithmTest.java
+++ b/tests/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithmTest.java
@@ -20,15 +20,14 @@
 
 import android.content.ComponentName;
 
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
 import com.android.launcher3.AppInfo;
-import com.android.launcher3.Utilities;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
 /**
  * Unit tests for {@link DefaultAppSearchAlgorithm}
  */
@@ -78,9 +77,6 @@
 
     @Test
     public void testMatchesVN() {
-        if (!Utilities.ATLEAST_NOUGAT) {
-            return;
-        }
         assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("다운로드"), "다", MATCHER));
         assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("드라이브"), "드", MATCHER));
         assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("다운로드 드라이브"), "ㄷ", MATCHER));