Fixing jank in folder animation.

This continues ag/6410337

Bug: 69236787
Test: Manual
Change-Id: Iac9f7ab21bf3741846b9721d4c8235e8fc49f7fb
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index fe6bbc0..3eb01e6 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -48,6 +48,9 @@
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 
+import androidx.annotation.IntDef;
+import androidx.core.view.ViewCompat;
+
 import com.android.launcher3.LauncherSettings.Favorites;
 import com.android.launcher3.accessibility.DragAndDropAccessibilityDelegate;
 import com.android.launcher3.accessibility.FolderAccessibilityHelper;
@@ -75,9 +78,6 @@
 import java.util.Comparator;
 import java.util.Stack;
 
-import androidx.annotation.IntDef;
-import androidx.core.view.ViewCompat;
-
 public class CellLayout extends ViewGroup implements Transposable {
     public static final int WORKSPACE_ACCESSIBILITY_DRAG = 2;
     public static final int FOLDER_ACCESSIBILITY_DRAG = 1;
@@ -360,6 +360,10 @@
         mShortcutsAndWidgets.setLayerType(hasLayer ? LAYER_TYPE_HARDWARE : LAYER_TYPE_NONE, sPaint);
     }
 
+    public boolean isHardwareLayerEnabled() {
+        return mShortcutsAndWidgets.getLayerType() == LAYER_TYPE_HARDWARE;
+    }
+
     public void setCellDimensions(int width, int height) {
         mFixedCellWidth = mCellWidth = width;
         mFixedCellHeight = mCellHeight = height;
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index f2eae17..389e852 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -24,6 +24,7 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.annotation.SuppressLint;
+import android.appwidget.AppWidgetHostView;
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Canvas;
@@ -61,8 +62,10 @@
 import com.android.launcher3.OnAlarmListener;
 import com.android.launcher3.PagedView;
 import com.android.launcher3.R;
-import com.android.launcher3.WorkspaceItemInfo;
+import com.android.launcher3.ShortcutAndWidgetContainer;
+import com.android.launcher3.Workspace;
 import com.android.launcher3.Workspace.ItemOperator;
+import com.android.launcher3.WorkspaceItemInfo;
 import com.android.launcher3.accessibility.AccessibleDragListenerAdapter;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.dragndrop.DragController;
@@ -121,6 +124,7 @@
     private static final int REORDER_DELAY = 250;
     private static final int ON_EXIT_CLOSE_DELAY = 400;
     private static final Rect sTempRect = new Rect();
+    private static final int MIN_FOLDERS_FOR_HARDWARE_OPTIMIZATION = 10;
 
     private static String sDefaultFolderName;
     private static String sHintText;
@@ -430,21 +434,44 @@
         if (mCurrentAnimator != null && mCurrentAnimator.isRunning()) {
             mCurrentAnimator.cancel();
         }
+        final Workspace workspace = mLauncher.getWorkspace();
+        final CellLayout currentCellLayout =
+                (CellLayout) workspace.getChildAt(workspace.getCurrentPage());
+        final boolean useHardware = shouldUseHardwareLayerForAnimation(currentCellLayout);
+        final boolean wasHardwareAccelerated = currentCellLayout.isHardwareLayerEnabled();
+
         a.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationStart(Animator animation) {
+                if (useHardware) {
+                    currentCellLayout.enableHardwareLayer(true);
+                }
                 mState = STATE_ANIMATING;
                 mCurrentAnimator = a;
             }
 
             @Override
             public void onAnimationEnd(Animator animation) {
+                if (useHardware) {
+                    currentCellLayout.enableHardwareLayer(wasHardwareAccelerated);
+                }
                 mCurrentAnimator = null;
             }
         });
         a.start();
     }
 
+    private boolean shouldUseHardwareLayerForAnimation(CellLayout currentCellLayout) {
+        int folderCount = 0;
+        final ShortcutAndWidgetContainer container = currentCellLayout.getShortcutsAndWidgets();
+        for (int i = container.getChildCount() - 1; i >= 0; --i) {
+            final View child = container.getChildAt(i);
+            if (child instanceof AppWidgetHostView) return false;
+            if (child instanceof FolderIcon) ++folderCount;
+        }
+        return folderCount >= MIN_FOLDERS_FOR_HARDWARE_OPTIMIZATION;
+    }
+
     /**
      * Opens the user folder described by the specified tag. The opening of the folder
      * is animated relative to the specified View. If the View is null, no animation