Move color extraction utils to extractor class so each instance can
have its own set of temp variables.

- Pass in float[] param to not create new obj in each frame
  for dragging widget case.

Bug: 175329686
Bug: 187019711
Test: manual, verify
Change-Id: I4350fb7e66a80c73def5659fb41abc14d357e667
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index af625a5..1df9df6 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -195,6 +195,7 @@
 
     private final Rect mTempRect = new Rect();
     private final RectF mTempRectF = new RectF();
+    private final float[] mTmpFloatArray = new float[4];
 
     private static final Paint sPaint = new Paint();
 
@@ -1080,7 +1081,7 @@
 
             // Now get the rect in drag layer coordinates.
             getBoundsForViewInDragLayer(launcher.getDragLayer(), workspace, mTempRect, false,
-                    mTempRectF);
+                    mTmpFloatArray, mTempRectF);
             Utilities.setRect(mTempRectF, mTempRect);
             ((LauncherAppWidgetHostView) view).handleDrag(mTempRect, pageId);
         }
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index bff3cab..972a6e8 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -242,8 +242,8 @@
      * @param outRect The out rect where we return the bounds of {@param view} in drag layer coords.
      */
     public static void getBoundsForViewInDragLayer(BaseDragLayer dragLayer, View view,
-            Rect viewBounds, boolean ignoreTransform, RectF outRect) {
-        float[] points = sTmpFloatArray;
+            Rect viewBounds, boolean ignoreTransform, float[] recycle, RectF outRect) {
+        float[] points = recycle == null ? new float[4] : recycle;
         points[0] = viewBounds.left;
         points[1] = viewBounds.top;
         points[2] = viewBounds.right;
diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java
index 5684c5a..c63d69d 100644
--- a/src/com/android/launcher3/popup/ArrowPopup.java
+++ b/src/com/android/launcher3/popup/ArrowPopup.java
@@ -18,7 +18,6 @@
 
 import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
 import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS;
-import static com.android.launcher3.util.ColorExtractionUtils.getColorExtractionRect;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -748,7 +747,7 @@
                     View view = getChildAt(i);
                     if (view.getVisibility() == VISIBLE) {
                         RectF rf = new RectF();
-                        getColorExtractionRect(Launcher.getLauncher(getContext()),
+                        mColorExtractor.getExtractedRectForView(Launcher.getLauncher(getContext()),
                                 workspace.getCurrentPage(), view, rf);
                         if (rf.isEmpty()) {
                             numVisibleChild++;
diff --git a/src/com/android/launcher3/util/ColorExtractionUtils.java b/src/com/android/launcher3/util/ColorExtractionUtils.java
deleted file mode 100644
index b377ded..0000000
--- a/src/com/android/launcher3/util/ColorExtractionUtils.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2021 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;
-
-import android.content.res.Resources;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.view.View;
-
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.Launcher;
-import com.android.launcher3.Utilities;
-
-/**
- * Utility class used to map launcher views to wallpaper rect.
- */
-public class ColorExtractionUtils {
-
-    public static final String TAG = "ColorExtractionUtils";
-
-    private static final Rect sTempRect = new Rect();
-    private static final RectF sTempRectF = new RectF();
-
-    /**
-     * Takes a view and returns its rect that can be used by the wallpaper local color extractor.
-     *
-     * @param launcher Launcher class class.
-     * @param pageId The page the workspace item is on.
-     * @param v The view.
-     * @param colorExtractionRectOut The location rect, but converted to a format expected by the
-     *                               wallpaper local color extractor.
-     */
-    public static void getColorExtractionRect(Launcher launcher, int pageId, View v,
-            RectF colorExtractionRectOut) {
-        Rect viewRect = sTempRect;
-        viewRect.set(0, 0, v.getWidth(), v.getHeight());
-        Utilities.getBoundsForViewInDragLayer(launcher.getDragLayer(), v, viewRect, false,
-                sTempRectF);
-        Utilities.setRect(sTempRectF, viewRect);
-        getColorExtractionRect(launcher, pageId, viewRect, colorExtractionRectOut);
-    }
-
-    /**
-     * Takes a rect in drag layer coordinates and returns the rect that can be used by the wallpaper
-     * local color extractor.
-     *
-     * @param launcher Launcher class.
-     * @param pageId The page the workspace item is on.
-     * @param rectInDragLayer The relevant bounds of the view in drag layer coordinates.
-     * @param colorExtractionRectOut The location rect, but converted to a format expected by the
-     *                               wallpaper local color extractor.
-     */
-    public static void getColorExtractionRect(Launcher launcher, int pageId, Rect rectInDragLayer,
-            RectF colorExtractionRectOut) {
-        // If the view hasn't been measured and laid out, we cannot do this.
-        if (rectInDragLayer.isEmpty()) {
-            colorExtractionRectOut.setEmpty();
-            return;
-        }
-
-        Resources res = launcher.getResources();
-        DeviceProfile dp = launcher.getDeviceProfile().inv.getDeviceProfile(launcher);
-        float screenWidth = dp.widthPx;
-        float screenHeight = dp.heightPx;
-        int numScreens = launcher.getWorkspace().getNumPagesForWallpaperParallax();
-        pageId = Utilities.isRtl(res) ? numScreens - pageId - 1 : pageId;
-        float relativeScreenWidth = 1f / numScreens;
-
-        int[] dragLayerBounds = new int[2];
-        launcher.getDragLayer().getLocationOnScreen(dragLayerBounds);
-        // Translate from drag layer coordinates to screen coordinates.
-        int screenLeft = rectInDragLayer.left + dragLayerBounds[0];
-        int screenTop = rectInDragLayer.top + dragLayerBounds[1];
-        int screenRight = rectInDragLayer.right + dragLayerBounds[0];
-        int screenBottom = rectInDragLayer.bottom + dragLayerBounds[1];
-
-        // This is the position of the view relative to the wallpaper, as expected by the
-        // local color extraction of the WallpaperManager.
-        // The coordinate system is such that, on the horizontal axis, each screen has a
-        // distinct range on the [0,1] segment. So if there are 3 screens, they will have the
-        // ranges [0, 1/3], [1/3, 2/3] and [2/3, 1]. The position on the subrange should be
-        // the position of the view relative to the screen. For the vertical axis, this is
-        // simply the location of the view relative to the screen.
-        // Translate from drag layer coordinates to screen coordinates
-        colorExtractionRectOut.left = (screenLeft / screenWidth + pageId) * relativeScreenWidth;
-        colorExtractionRectOut.right = (screenRight / screenWidth + pageId) * relativeScreenWidth;
-        colorExtractionRectOut.top = screenTop / screenHeight;
-        colorExtractionRectOut.bottom = screenBottom / screenHeight;
-
-        if (colorExtractionRectOut.left < 0
-                || colorExtractionRectOut.right > 1
-                || colorExtractionRectOut.top < 0
-                || colorExtractionRectOut.bottom > 1) {
-            colorExtractionRectOut.setEmpty();
-        }
-    }
-}
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index 1ddd1ba..81581fa 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -234,7 +234,7 @@
         }
 
         Utilities.getBoundsForViewInDragLayer(launcher.getDragLayer(), v, outViewBounds,
-                ignoreTransform, outRect);
+                ignoreTransform, null /** recycle */, outRect);
     }
 
     /**
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
index 697c453..5deecd4 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
@@ -18,7 +18,6 @@
 
 import static com.android.launcher3.Utilities.getBoundsForViewInDragLayer;
 import static com.android.launcher3.Utilities.setRect;
-import static com.android.launcher3.util.ColorExtractionUtils.getColorExtractionRect;
 
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.Context;
@@ -102,6 +101,7 @@
     private final Rect mCurrentWidgetSize = new Rect();
     private final Rect mWidgetSizeAtDrag = new Rect();
 
+    private final float[] mTmpFloatArray = new float[4];
     private final RectF mTempRectF = new RectF();
     private final Rect mEnforcedRectangle = new Rect();
     private final float mEnforcedCornerRadius;
@@ -323,7 +323,7 @@
         if (!mIsInDragMode && getTag() instanceof LauncherAppWidgetInfo) {
             LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) getTag();
             getBoundsForViewInDragLayer(mLauncher.getDragLayer(), this, mCurrentWidgetSize, true,
-                    mTempRectF);
+                    mTmpFloatArray, mTempRectF);
             setRect(mTempRectF, mCurrentWidgetSize);
             updateColorExtraction(mCurrentWidgetSize,
                     mWorkspace.getPageIndexForScreenId(info.screenId));
@@ -357,7 +357,7 @@
      * @param pageId The workspace page the widget is on.
      */
     private void updateColorExtraction(Rect rectInDragLayer, int pageId) {
-        getColorExtractionRect(mLauncher, pageId, rectInDragLayer, mTempRectF);
+        mColorExtractor.getExtractedRectForViewRect(mLauncher, pageId, rectInDragLayer, mTempRectF);
 
         if (mTempRectF.isEmpty()) {
             return;
diff --git a/src/com/android/launcher3/widget/LocalColorExtractor.java b/src/com/android/launcher3/widget/LocalColorExtractor.java
index be4faea..8ae6b2e 100644
--- a/src/com/android/launcher3/widget/LocalColorExtractor.java
+++ b/src/com/android/launcher3/widget/LocalColorExtractor.java
@@ -19,11 +19,14 @@
 import android.app.WallpaperColors;
 import android.appwidget.AppWidgetHostView;
 import android.content.Context;
+import android.graphics.Rect;
 import android.graphics.RectF;
 import android.util.SparseIntArray;
+import android.view.View;
 
 import androidx.annotation.Nullable;
 
+import com.android.launcher3.Launcher;
 import com.android.launcher3.R;
 import com.android.launcher3.util.ResourceBasedOverride;
 
@@ -71,4 +74,33 @@
      * Updates the base context to contain the colors override
      */
     public void applyColorsOverride(Context base, WallpaperColors colors) { }
+
+    /**
+     * Takes a view and returns its rect that can be used by the wallpaper local color extractor.
+     *
+     * @param launcher Launcher class class.
+     * @param pageId The page the workspace item is on.
+     * @param v The view.
+     * @param colorExtractionRectOut The location rect, but converted to a format expected by the
+     *                               wallpaper local color extractor.
+     */
+    public void getExtractedRectForView(Launcher launcher, int pageId, View v,
+            RectF colorExtractionRectOut) {
+        // no-op
+    }
+
+    /**
+     * Takes a rect in drag layer coordinates and returns the rect that can be used by the wallpaper
+     * local color extractor.
+     *
+     * @param launcher Launcher class.
+     * @param pageId The page the workspace item is on.
+     * @param rectInDragLayer The relevant bounds of the view in drag layer coordinates.
+     * @param colorExtractionRectOut The location rect, but converted to a format expected by the
+     *                               wallpaper local color extractor.
+     */
+    public void getExtractedRectForViewRect(Launcher launcher, int pageId, Rect rectInDragLayer,
+            RectF colorExtractionRectOut) {
+        // no-op
+    }
 }