Adding support for using themed icons on workspace

Bug: 183641907
Test: Manual

Change-Id: Ieda7e73b3ae4dfe3009e3f23754aff5f8826a967
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 2ace796..3d044d6 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -317,7 +317,8 @@
 
     @UiThread
     protected void applyIconAndLabel(ItemInfoWithIcon info) {
-        FastBitmapDrawable iconDrawable = info.newIcon(getContext());
+        boolean useTheme = mDisplay == DISPLAY_WORKSPACE || mDisplay == DISPLAY_FOLDER;
+        FastBitmapDrawable iconDrawable = info.newIcon(getContext(), useTheme);
         mDotParams.color = IconPalette.getMutedColor(info.bitmap.color, 0.54f);
 
         setIcon(iconDrawable);
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index a799b4a..be5463e 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -74,9 +74,9 @@
 import com.android.launcher3.graphics.GridCustomizationsProvider;
 import com.android.launcher3.graphics.TintedDrawableSpan;
 import com.android.launcher3.icons.FastBitmapDrawable;
-import com.android.launcher3.icons.IconProvider;
 import com.android.launcher3.icons.LauncherIcons;
 import com.android.launcher3.icons.ShortcutCachingLogic;
+import com.android.launcher3.icons.ThemedIconDrawable.ThemedAdaptiveIcon;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.ItemInfoWithIcon;
 import com.android.launcher3.pm.ShortcutConfigActivityInfo;
@@ -596,13 +596,23 @@
      */
     public static Drawable getFullDrawable(Launcher launcher, ItemInfo info, int width, int height,
             Object[] outObj) {
+        Drawable icon = loadFullDrawableWithoutTheme(launcher, info, width, height, outObj);
+        if (icon instanceof ThemedAdaptiveIcon) {
+            icon = ((ThemedAdaptiveIcon) icon).getThemedDrawable(launcher);
+        }
+        return icon;
+    }
+
+    private static Drawable loadFullDrawableWithoutTheme(Launcher launcher, ItemInfo info,
+            int width, int height, Object[] outObj) {
         LauncherAppState appState = LauncherAppState.getInstance(launcher);
         if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
             LauncherActivityInfo activityInfo = launcher.getSystemService(LauncherApps.class)
                     .resolveActivity(info.getIntent(), info.user);
             outObj[0] = activityInfo;
-            return activityInfo == null ? null : new IconProvider(launcher).getIcon(
-                    activityInfo, launcher.getDeviceProfile().inv.fillResIconDpi);
+            return activityInfo == null ? null : LauncherAppState.getInstance(launcher)
+                    .getIconCache().getIconProvider().getIcon(
+                            activityInfo, launcher.getDeviceProfile().inv.fillResIconDpi);
         } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
             if (info instanceof PendingAddShortcutInfo) {
                 ShortcutConfigActivityInfo activityInfo =
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index bad8704..88476de 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -137,8 +137,8 @@
     public static final BooleanFlag MULTI_DB_GRID_MIRATION_ALGO = getDebugFlag(
             "MULTI_DB_GRID_MIRATION_ALGO", true, "Use the multi-db grid migration algorithm");
 
-    public static final BooleanFlag ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER = getDebugFlag(
-            "ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER", true, "Show launcher preview in grid picker");
+    public static final BooleanFlag ENABLE_THEMED_ICONS = getDebugFlag(
+            "ENABLE_THEMED_ICONS", false, "Enable themed icons on workspace");
 
     // Keep as DeviceFlag for remote disable in emergency.
     public static final BooleanFlag ENABLE_OVERVIEW_SELECTIONS = new DeviceFlag(
diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java
index d7f6cdb..575b8fd 100644
--- a/src/com/android/launcher3/dragndrop/DragController.java
+++ b/src/com/android/launcher3/dragndrop/DragController.java
@@ -22,7 +22,6 @@
 import static com.android.launcher3.Utilities.ATLEAST_Q;
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 
-import android.animation.ValueAnimator;
 import android.content.ComponentName;
 import android.content.res.Resources;
 import android.graphics.Point;
@@ -307,17 +306,12 @@
             mOptions.preDragCondition.onPreDragEnd(mDragObject, true /* dragStarted*/);
         }
         mIsInPreDrag = false;
+        mDragObject.dragView.onDragStart();
         for (DragListener listener : new ArrayList<>(mListeners)) {
             listener.onDragStart(mDragObject, mOptions);
         }
     }
 
-    public void addFirstFrameAnimationHelper(ValueAnimator anim) {
-        if (mDragObject != null && mDragObject.dragView != null) {
-            mDragObject.dragView.mFirstFrameAnimatorHelper.addTo(anim);
-        }
-    }
-
     public Optional<InstanceId> getLogInstanceId() {
         return Optional.ofNullable(mDragObject)
                 .map(dragObject -> dragObject.logInstanceId);
diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java
index 68a8af2..30ee9ec 100644
--- a/src/com/android/launcher3/dragndrop/DragView.java
+++ b/src/com/android/launcher3/dragndrop/DragView.java
@@ -51,7 +51,6 @@
 import androidx.dynamicanimation.animation.SpringAnimation;
 import androidx.dynamicanimation.animation.SpringForce;
 
-import com.android.launcher3.FirstFrameAnimatorHelper;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.LauncherState;
@@ -62,6 +61,7 @@
 import com.android.launcher3.icons.LauncherIcons;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.statemanager.StateManager.StateListener;
+import com.android.launcher3.util.RunnableList;
 import com.android.launcher3.util.Thunk;
 import com.android.launcher3.views.BaseDragLayer;
 
@@ -85,12 +85,13 @@
     private final float mScaleOnDrop;
     private final int[] mTempLoc = new int[2];
 
+    private final RunnableList mOnDragStartCallback = new RunnableList();
+
     private Point mDragVisualizeOffset = null;
     private Rect mDragRegion = null;
     private final Launcher mLauncher;
     private final DragLayer mDragLayer;
     @Thunk final DragController mDragController;
-    final FirstFrameAnimatorHelper mFirstFrameAnimatorHelper;
     private boolean mHasDrawn = false;
 
     final ValueAnimator mAnim;
@@ -136,7 +137,6 @@
         mLauncher = launcher;
         mDragLayer = launcher.getDragLayer();
         mDragController = launcher.getDragController();
-        mFirstFrameAnimatorHelper = new FirstFrameAnimatorHelper(this);
 
         mContent = content;
         mWidth = width;
@@ -276,7 +276,8 @@
                 }
                 mFgSpringDrawable.setBounds(bounds);
 
-                new Handler(Looper.getMainLooper()).post(() -> {
+                new Handler(Looper.getMainLooper()).post(() -> mOnDragStartCallback.add(() -> {
+                    // TODO: Consider fade-in animation
                     // Assign the variable on the UI thread to avoid race conditions.
                     mScaledMaskPath = mask;
                     // Avoid relayout as we do not care about children affecting layout
@@ -290,11 +291,18 @@
                         mBadge.setColorFilter(d.getColorFilter());
                     }
                     invalidate();
-                });
+                }));
             }
         });
     }
 
+    /**
+     * Called when pre-drag finishes for an icon
+     */
+    public void onDragStart() {
+        mOnDragStartCallback.executeAllAndDestroy();
+    }
+
     // TODO(b/183609936): This is only for LauncherAppWidgetHostView that is rendered in a drawable.
     // Once LauncherAppWidgetHostView is directly rendered in this view, removes this method.
     @Override
diff --git a/src/com/android/launcher3/folder/PreviewItemManager.java b/src/com/android/launcher3/folder/PreviewItemManager.java
index 8244f01..6adef01 100644
--- a/src/com/android/launcher3/folder/PreviewItemManager.java
+++ b/src/com/android/launcher3/folder/PreviewItemManager.java
@@ -400,7 +400,7 @@
             drawable.setLevel(item.getProgressLevel());
             p.drawable = drawable;
         } else {
-            p.drawable = item.newIcon(mContext);
+            p.drawable = item.newIcon(mContext, true);
         }
         p.drawable.setBounds(0, 0, mIconSize, mIconSize);
         p.item = item;
diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
index 31764c5..acfeeac 100644
--- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
+++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
@@ -20,7 +20,6 @@
 import static android.view.View.VISIBLE;
 
 import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER;
 import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems;
 import static com.android.launcher3.model.ModelUtils.getMissingHotseatRanks;
 import static com.android.launcher3.model.ModelUtils.sortWorkspaceItemsSpatially;
@@ -118,7 +117,7 @@
  *   4) Measure and draw the view on a canvas
  */
 @TargetApi(Build.VERSION_CODES.O)
-public class LauncherPreviewRenderer extends ContextThemeWrapper
+public class LauncherPreviewRenderer extends ContextWrapper
         implements ActivityContext, WorkspaceLayoutManager, LayoutInflater.Factory2 {
 
     private static final String TAG = "LauncherPreviewRenderer";
@@ -220,7 +219,7 @@
     private final CellLayout mWorkspace;
 
     public LauncherPreviewRenderer(Context context, InvariantDeviceProfile idp, boolean migrated) {
-        super(context, R.style.AppTheme);
+        super(context);
         mUiHandler = new Handler(Looper.getMainLooper());
         mContext = context;
         mIdp = idp;
@@ -271,14 +270,6 @@
         return mRootView;
     }
 
-    public boolean shouldShowRealLauncherPreview() {
-        return ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER.get();
-    }
-
-    public boolean shouldShowQsb() {
-        return FeatureFlags.QSB_ON_FIRST_SCREEN;
-    }
-
     @Override
     public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
         if ("TextClock".equals(name)) {
@@ -402,107 +393,88 @@
     }
 
     private void populate() {
-        if (shouldShowRealLauncherPreview()) {
-            WorkspaceFetcher fetcher;
-            PreviewContext previewContext = null;
-            if (mMigrated) {
-                previewContext = new PreviewContext(mContext, mIdp);
-                LauncherAppState appForPreview = new LauncherAppState(
-                        previewContext, null /* iconCacheFileName */);
-                fetcher = new WorkspaceItemsInfoFromPreviewFetcher(appForPreview);
-                MODEL_EXECUTOR.execute(fetcher);
-            } else {
-                fetcher = new WorkspaceItemsInfoFetcher();
-                LauncherAppState.getInstance(mContext).getModel().enqueueModelUpdateTask(
-                        (LauncherModel.ModelUpdateTask) fetcher);
-            }
-            WorkspaceResult workspaceResult = fetcher.get();
-            if (previewContext != null) {
-                previewContext.onDestroy();
-            }
-
-            if (workspaceResult == null) {
-                return;
-            }
-
-            // Separate the items that are on the current screen, and the other remaining items.
-            ArrayList<ItemInfo> currentWorkspaceItems = new ArrayList<>();
-            ArrayList<ItemInfo> otherWorkspaceItems = new ArrayList<>();
-            ArrayList<LauncherAppWidgetInfo> currentAppWidgets = new ArrayList<>();
-            ArrayList<LauncherAppWidgetInfo> otherAppWidgets = new ArrayList<>();
-            filterCurrentWorkspaceItems(0 /* currentScreenId */,
-                    workspaceResult.mWorkspaceItems, currentWorkspaceItems,
-                    otherWorkspaceItems);
-            filterCurrentWorkspaceItems(0 /* currentScreenId */, workspaceResult.mAppWidgets,
-                    currentAppWidgets, otherAppWidgets);
-            sortWorkspaceItemsSpatially(mIdp, currentWorkspaceItems);
-            for (ItemInfo itemInfo : currentWorkspaceItems) {
-                switch (itemInfo.itemType) {
-                    case Favorites.ITEM_TYPE_APPLICATION:
-                    case Favorites.ITEM_TYPE_SHORTCUT:
-                    case Favorites.ITEM_TYPE_DEEP_SHORTCUT:
-                        inflateAndAddIcon((WorkspaceItemInfo) itemInfo);
-                        break;
-                    case Favorites.ITEM_TYPE_FOLDER:
-                        inflateAndAddFolder((FolderInfo) itemInfo);
-                        break;
-                    default:
-                        break;
-                }
-            }
-            for (ItemInfo itemInfo : currentAppWidgets) {
-                switch (itemInfo.itemType) {
-                    case Favorites.ITEM_TYPE_APPWIDGET:
-                    case Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:
-                        if (mMigrated) {
-                            inflateAndAddWidgets((LauncherAppWidgetInfo) itemInfo,
-                                    workspaceResult.mWidgetProvidersMap);
-                        } else {
-                            inflateAndAddWidgets((LauncherAppWidgetInfo) itemInfo,
-                                    workspaceResult.mWidgetsModel);
-                        }
-                        break;
-                    default:
-                        break;
-                }
-            }
-            IntArray ranks = getMissingHotseatRanks(currentWorkspaceItems,
-                    mDp.numShownHotseatIcons);
-            List<ItemInfo> predictions = workspaceResult.mHotseatPredictions == null
-                    ? Collections.emptyList() : workspaceResult.mHotseatPredictions.items;
-            int count = Math.min(ranks.size(), predictions.size());
-            for (int i = 0; i < count; i++) {
-                int rank = ranks.get(i);
-                WorkspaceItemInfo itemInfo =
-                        new WorkspaceItemInfo((WorkspaceItemInfo) predictions.get(i));
-                itemInfo.container = CONTAINER_HOTSEAT_PREDICTION;
-                itemInfo.rank = rank;
-                itemInfo.cellX = mHotseat.getCellXFromOrder(rank);
-                itemInfo.cellY = mHotseat.getCellYFromOrder(rank);
-                itemInfo.screenId = rank;
-                inflateAndAddPredictedIcon(itemInfo);
-            }
+        WorkspaceFetcher fetcher;
+        PreviewContext previewContext = null;
+        if (mMigrated) {
+            previewContext = new PreviewContext(mContext, mIdp);
+            LauncherAppState appForPreview = new LauncherAppState(
+                    previewContext, null /* iconCacheFileName */);
+            fetcher = new WorkspaceItemsInfoFromPreviewFetcher(appForPreview);
+            MODEL_EXECUTOR.execute(fetcher);
         } else {
-            // Add hotseat icons
-            for (int i = 0; i < mDp.numShownHotseatIcons; i++) {
-                WorkspaceItemInfo info = new WorkspaceItemInfo(mWorkspaceItemInfo);
-                info.container = Favorites.CONTAINER_HOTSEAT;
-                info.screenId = i;
-                inflateAndAddIcon(info);
+            fetcher = new WorkspaceItemsInfoFetcher();
+            LauncherAppState.getInstance(mContext).getModel().enqueueModelUpdateTask(
+                    (LauncherModel.ModelUpdateTask) fetcher);
+        }
+        WorkspaceResult workspaceResult = fetcher.get();
+        if (previewContext != null) {
+            previewContext.onDestroy();
+        }
+
+        if (workspaceResult == null) {
+            return;
+        }
+
+        // Separate the items that are on the current screen, and the other remaining items.
+        ArrayList<ItemInfo> currentWorkspaceItems = new ArrayList<>();
+        ArrayList<ItemInfo> otherWorkspaceItems = new ArrayList<>();
+        ArrayList<LauncherAppWidgetInfo> currentAppWidgets = new ArrayList<>();
+        ArrayList<LauncherAppWidgetInfo> otherAppWidgets = new ArrayList<>();
+        filterCurrentWorkspaceItems(0 /* currentScreenId */,
+                workspaceResult.mWorkspaceItems, currentWorkspaceItems,
+                otherWorkspaceItems);
+        filterCurrentWorkspaceItems(0 /* currentScreenId */, workspaceResult.mAppWidgets,
+                currentAppWidgets, otherAppWidgets);
+        sortWorkspaceItemsSpatially(mIdp, currentWorkspaceItems);
+        for (ItemInfo itemInfo : currentWorkspaceItems) {
+            switch (itemInfo.itemType) {
+                case Favorites.ITEM_TYPE_APPLICATION:
+                case Favorites.ITEM_TYPE_SHORTCUT:
+                case Favorites.ITEM_TYPE_DEEP_SHORTCUT:
+                    inflateAndAddIcon((WorkspaceItemInfo) itemInfo);
+                    break;
+                case Favorites.ITEM_TYPE_FOLDER:
+                    inflateAndAddFolder((FolderInfo) itemInfo);
+                    break;
+                default:
+                    break;
             }
-            // Add workspace icons
-            for (int i = 0; i < mIdp.numColumns; i++) {
-                WorkspaceItemInfo info = new WorkspaceItemInfo(mWorkspaceItemInfo);
-                info.container = Favorites.CONTAINER_DESKTOP;
-                info.screenId = 0;
-                info.cellX = i;
-                info.cellY = mIdp.numRows - 1;
-                inflateAndAddIcon(info);
+        }
+        for (ItemInfo itemInfo : currentAppWidgets) {
+            switch (itemInfo.itemType) {
+                case Favorites.ITEM_TYPE_APPWIDGET:
+                case Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:
+                    if (mMigrated) {
+                        inflateAndAddWidgets((LauncherAppWidgetInfo) itemInfo,
+                                workspaceResult.mWidgetProvidersMap);
+                    } else {
+                        inflateAndAddWidgets((LauncherAppWidgetInfo) itemInfo,
+                                workspaceResult.mWidgetsModel);
+                    }
+                    break;
+                default:
+                    break;
             }
         }
+        IntArray ranks = getMissingHotseatRanks(currentWorkspaceItems,
+                mDp.numShownHotseatIcons);
+        List<ItemInfo> predictions = workspaceResult.mHotseatPredictions == null
+                ? Collections.emptyList() : workspaceResult.mHotseatPredictions.items;
+        int count = Math.min(ranks.size(), predictions.size());
+        for (int i = 0; i < count; i++) {
+            int rank = ranks.get(i);
+            WorkspaceItemInfo itemInfo =
+                    new WorkspaceItemInfo((WorkspaceItemInfo) predictions.get(i));
+            itemInfo.container = CONTAINER_HOTSEAT_PREDICTION;
+            itemInfo.rank = rank;
+            itemInfo.cellX = mHotseat.getCellXFromOrder(rank);
+            itemInfo.cellY = mHotseat.getCellYFromOrder(rank);
+            itemInfo.screenId = rank;
+            inflateAndAddPredictedIcon(itemInfo);
+        }
 
         // Add first page QSB
-        if (shouldShowQsb()) {
+        if (FeatureFlags.QSB_ON_FIRST_SCREEN) {
             View qsb = mHomeElementInflater.inflate(
                     R.layout.search_container_workspace, mWorkspace, false);
             CellLayout.LayoutParams lp =
diff --git a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
index fdc3a94..6193570 100644
--- a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
+++ b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
@@ -20,6 +20,7 @@
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
 
+import android.app.WallpaperColors;
 import android.content.Context;
 import android.hardware.display.DisplayManager;
 import android.os.Bundle;
@@ -28,18 +29,23 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.Messenger;
+import android.view.ContextThemeWrapper;
 import android.view.Display;
 import android.view.SurfaceControlViewHost;
 import android.view.View;
 import android.view.animation.AccelerateDecelerateInterpolator;
 
 import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.R;
 import com.android.launcher3.model.GridSizeMigrationTask;
 import com.android.launcher3.model.GridSizeMigrationTaskV2;
+import com.android.launcher3.util.Themes;
+import com.android.launcher3.widget.LocalColorExtractor;
 
 import java.util.concurrent.TimeUnit;
 
 /** Render preview using surface view. */
+@SuppressWarnings("NewApi")
 public class PreviewSurfaceRenderer implements IBinder.DeathRecipient {
 
     private static final int FADE_IN_ANIMATION_DURATION = 200;
@@ -50,6 +56,7 @@
     private static final String KEY_DISPLAY_ID = "display_id";
     private static final String KEY_SURFACE_PACKAGE = "surface_package";
     private static final String KEY_CALLBACK = "callback";
+    private static final String KEY_COLORS = "wallpaper_colors";
 
     private final Context mContext;
     private final InvariantDeviceProfile mIdp;
@@ -57,6 +64,7 @@
     private final int mWidth;
     private final int mHeight;
     private final Display mDisplay;
+    private final WallpaperColors mWallpaperColors;
 
     private SurfaceControlViewHost mSurfaceControlViewHost;
 
@@ -68,6 +76,8 @@
         if (gridName == null) {
             gridName = InvariantDeviceProfile.getCurrentGridName(context);
         }
+        mWallpaperColors = bundle.getParcelable(KEY_COLORS);
+
         mIdp = new InvariantDeviceProfile(context, gridName);
 
         mHostToken = bundle.getBinder(KEY_HOST_TOKEN);
@@ -100,6 +110,19 @@
         MODEL_EXECUTOR.post(() -> {
             final boolean success = doGridMigrationIfNecessary();
 
+            final Context inflationContext;
+            if (mWallpaperColors != null) {
+                // Workaround to create a themed context
+                Context context = mContext.createDisplayContext(mDisplay);
+                LocalColorExtractor.newInstance(mContext)
+                        .applyColorsOverride(context, mWallpaperColors);
+
+                inflationContext = new ContextThemeWrapper(context,
+                        Themes.getActivityThemeRes(context, mWallpaperColors.getColorHints()));
+            } else {
+                inflationContext = new ContextThemeWrapper(mContext,  R.style.AppTheme);
+            }
+
             MAIN_EXECUTOR.post(() -> {
                 // If mSurfaceControlViewHost is null due to any reason (e.g. binder died,
                 // happening when user leaves the preview screen before preview rendering finishes),
@@ -109,7 +132,8 @@
                     return;
                 }
 
-                View view = new LauncherPreviewRenderer(mContext, mIdp, success).getRenderedView();
+                View view = new LauncherPreviewRenderer(inflationContext, mIdp, success)
+                        .getRenderedView();
                 // This aspect scales the view to fit in the surface and centers it
                 final float scale = Math.min(mWidth / (float) view.getMeasuredWidth(),
                         mHeight / (float) view.getMeasuredHeight());
diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java
index a2c0f5c..bc93a1e 100644
--- a/src/com/android/launcher3/icons/IconCache.java
+++ b/src/com/android/launcher3/icons/IconCache.java
@@ -52,7 +52,6 @@
 import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.pm.UserCache;
 import com.android.launcher3.shortcuts.ShortcutKey;
-import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.InstantAppResolver;
 import com.android.launcher3.util.PackageUserKey;
 import com.android.launcher3.util.Preconditions;
@@ -94,7 +93,7 @@
         mLauncherApps = mContext.getSystemService(LauncherApps.class);
         mUserManager = UserCache.INSTANCE.get(mContext);
         mInstantAppResolver = InstantAppResolver.newInstance(mContext);
-        mIconProvider = new IconProvider(context);
+        mIconProvider = new IconProvider(context, true /* supportsIconTheme */);
     }
 
     @Override
@@ -107,8 +106,12 @@
         return mInstantAppResolver.isInstantApp(info);
     }
 
+    public IconProvider getIconProvider() {
+        return mIconProvider;
+    }
+
     @Override
-    protected BaseIconFactory getIconFactory() {
+    public BaseIconFactory getIconFactory() {
         return LauncherIcons.obtain(mContext);
     }
 
@@ -333,15 +336,6 @@
                 + ",flags_asi:" + FeatureFlags.APP_SEARCH_IMPROVEMENTS.get();
     }
 
-    @Override
-    protected boolean getEntryFromDB(ComponentKey cacheKey, CacheEntry entry, boolean lowRes) {
-        if (mIconProvider.isClockIcon(cacheKey)) {
-            // For clock icon, we always load the dynamic icon
-            return false;
-        }
-        return super.getEntryFromDB(cacheKey, entry, lowRes);
-    }
-
     /**
      * Interface for receiving itemInfo with high-res icon.
      */
diff --git a/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java b/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java
index 93de35a..8fc3977 100644
--- a/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java
+++ b/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java
@@ -20,6 +20,7 @@
 import android.content.pm.LauncherActivityInfo;
 import android.os.UserHandle;
 
+import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.R;
 import com.android.launcher3.icons.cache.CachingLogic;
 import com.android.launcher3.util.ResourceBasedOverride;
@@ -56,8 +57,8 @@
     @Override
     public BitmapInfo loadIcon(Context context, LauncherActivityInfo object) {
         try (LauncherIcons li = LauncherIcons.obtain(context)) {
-            return li.createBadgedIconBitmap(new IconProvider(context)
-                            .getIcon(object, li.mFillResIconDpi),
+            return li.createBadgedIconBitmap(LauncherAppState.getInstance(context)
+                            .getIconCache().getIconProvider().getIcon(object, li.mFillResIconDpi),
                     object.getUser(), object.getApplicationInfo().targetSdkVersion);
         }
     }
diff --git a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
index 76b2ab0..0754c29 100644
--- a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
+++ b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
@@ -16,6 +16,8 @@
 
 package com.android.launcher3.model.data;
 
+import static com.android.launcher3.config.FeatureFlags.ENABLE_THEMED_ICONS;
+
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -223,7 +225,15 @@
      * Returns a FastBitmapDrawable with the icon.
      */
     public FastBitmapDrawable newIcon(Context context) {
-        FastBitmapDrawable drawable = bitmap.newIcon(context);
+        return newIcon(context, false);
+    }
+
+    /**
+     * Returns a FastBitmapDrawable with the icon and context theme applied
+     */
+    public FastBitmapDrawable newIcon(Context context, boolean applyTheme) {
+        FastBitmapDrawable drawable = applyTheme && ENABLE_THEMED_ICONS.get()
+                ? bitmap.newThemedIcon(context) : bitmap.newIcon(context);
         drawable.setIsDisabled(isDisabled());
         return drawable;
     }
diff --git a/src/com/android/launcher3/widget/LocalColorExtractor.java b/src/com/android/launcher3/widget/LocalColorExtractor.java
index 097158b..be4faea 100644
--- a/src/com/android/launcher3/widget/LocalColorExtractor.java
+++ b/src/com/android/launcher3/widget/LocalColorExtractor.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher3.widget;
 
+import android.app.WallpaperColors;
 import android.appwidget.AppWidgetHostView;
 import android.content.Context;
 import android.graphics.RectF;
@@ -43,7 +44,10 @@
         void onColorsChanged(RectF rect, SparseIntArray extractedColors);
     }
 
-    static LocalColorExtractor newInstance(Context context) {
+    /**
+     * Creates a new instance of LocalColorExtractor
+     */
+    public static LocalColorExtractor newInstance(Context context) {
         return Overrides.getObject(LocalColorExtractor.class, context.getApplicationContext(),
                 R.string.local_colors_extraction_class);
     }
@@ -62,4 +66,9 @@
     public void removeLocations() {
         // no-op
     }
+
+    /**
+     * Updates the base context to contain the colors override
+     */
+    public void applyColorsOverride(Context base, WallpaperColors colors) { }
 }