Merge "Add aconfig feature flag for expressive theme in Gesture nav and Taskbar" into main
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index 36185b1..ea2dec1 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -116,7 +116,6 @@
             Settings.Secure.NAV_BAR_KIDS_MODE);
 
     private final Context mParentContext;
-    private final @Nullable Context mNavigationBarPanelContext;
     private final TaskbarNavButtonController mDefaultNavButtonController;
     private final ComponentCallbacks mDefaultComponentCallbacks;
 
@@ -247,11 +246,6 @@
         mParentContext = context;
         createWindowContext(context.getDisplayId());
         mAllAppsActionManager = allAppsActionManager;
-        Display display = context.getSystemService(DisplayManager.class).getDisplay(
-                getDefaultDisplayId());
-        mNavigationBarPanelContext = ENABLE_TASKBAR_NAVBAR_UNIFICATION
-                ? context.createWindowContext(display, TYPE_NAVIGATION_BAR_PANEL, null)
-                : null;
         if (enableTaskbarNoRecreate()) {
             createTaskbarRootLayout(getDefaultDisplayId());
         }
@@ -861,8 +855,14 @@
      * Creates a {@link TaskbarActivityContext} for the given display and adds it to the map.
      */
     private TaskbarActivityContext createTaskbarActivityContext(DeviceProfile dp, int displayId) {
+        Display display = mParentContext.getSystemService(DisplayManager.class).getDisplay(
+                displayId);
+        Context navigationBarPanelContext = ENABLE_TASKBAR_NAVBAR_UNIFICATION
+                ? mParentContext.createWindowContext(display, TYPE_NAVIGATION_BAR_PANEL, null)
+                : null;
+
         TaskbarActivityContext newTaskbar = new TaskbarActivityContext(getWindowContext(displayId),
-                mNavigationBarPanelContext, dp, mDefaultNavButtonController,
+                navigationBarPanelContext, dp, mDefaultNavButtonController,
                 mUnfoldProgressProvider, isDefaultDisplay(displayId),
                 SystemUiProxy.INSTANCE.get(getPrimaryWindowContext()));
 
diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java
index d2ff2cb..2157610 100644
--- a/src/com/android/launcher3/folder/FolderAnimationManager.java
+++ b/src/com/android/launcher3/folder/FolderAnimationManager.java
@@ -35,6 +35,7 @@
 import android.util.Property;
 import android.view.View;
 import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
 
 import com.android.launcher3.BubbleTextView;
 import com.android.launcher3.CellLayout;
@@ -79,9 +80,10 @@
     private final int mDuration;
     private final int mDelay;
 
-    private final TimeInterpolator mFolderInterpolator;
-    private final TimeInterpolator mLargeFolderPreviewItemOpenInterpolator;
-    private final TimeInterpolator mLargeFolderPreviewItemCloseInterpolator;
+    private final Interpolator mFolderOpenInterpolator;
+    private final Interpolator mFolderCloseInterpolator;
+    private final Interpolator mLargeFolderPreviewItemOpenInterpolator;
+    private final Interpolator mLargeFolderPreviewItemCloseInterpolator;
 
     private final PreviewItemDrawingParams mTmpParams = new PreviewItemDrawingParams(0, 0, 0);
     private final FolderGridOrganizer mPreviewVerifier;
@@ -108,7 +110,9 @@
         mDuration = res.getInteger(R.integer.config_materialFolderExpandDuration);
         mDelay = res.getInteger(R.integer.config_folderDelay);
 
-        mFolderInterpolator = AnimationUtils.loadInterpolator(mContext,
+        mFolderOpenInterpolator = AnimationUtils.loadInterpolator(mContext,
+                R.interpolator.standard_interpolator);
+        mFolderCloseInterpolator = AnimationUtils.loadInterpolator(mContext,
                 R.interpolator.standard_interpolator);
         mLargeFolderPreviewItemOpenInterpolator = AnimationUtils.loadInterpolator(mContext,
                 R.interpolator.large_folder_preview_item_open_interpolator);
@@ -252,6 +256,7 @@
                 (int) (left + (startRect.right / initialScale)) + extraRadius,
                 (int) (startRect.bottom / initialScale) + extraRadius);
         Rect contentEnd = new Rect(left, 0, left + lp.width, lp.height);
+        // animated contents of folder with the folder background
         play(a, shapeDelegate.createRevealAnimator(
                 mFolder.getContent(), contentStart, contentEnd, finalRadius, !mIsOpening));
 
@@ -332,7 +337,11 @@
         // We set the interpolator on all current child animators here, because the preview item
         // animators may use a different interpolator.
         for (Animator animator : a.getChildAnimations()) {
-            animator.setInterpolator(mFolderInterpolator);
+            animator.setInterpolator(
+                    mIsOpening
+                    ? mFolderOpenInterpolator
+                    : mFolderCloseInterpolator
+            );
         }
 
         int radiusDiff = scaledRadius - mPreviewBackground.getRadius();
@@ -467,7 +476,7 @@
         return mFolder.getItemCount() > MAX_NUM_ITEMS_IN_PREVIEW;
     }
 
-    private TimeInterpolator getPreviewItemInterpolator() {
+    private Interpolator getPreviewItemInterpolator() {
         if (isLargeFolder()) {
             // With larger folders, we want the preview items to reach their final positions faster
             // (when opening) and later (when closing) so that they appear aligned with the rest of
@@ -476,7 +485,7 @@
                     ? mLargeFolderPreviewItemOpenInterpolator
                     : mLargeFolderPreviewItemCloseInterpolator;
         }
-        return mFolderInterpolator;
+        return mIsOpening ? mFolderOpenInterpolator : mFolderCloseInterpolator;
     }
 
     private Animator getAnimator(View view, Property property, float v1, float v2) {
diff --git a/src/com/android/launcher3/graphics/GridCustomizationsProvider.java b/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
index 9edc386..80743af 100644
--- a/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
+++ b/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
@@ -55,6 +55,7 @@
 
 import java.lang.ref.WeakReference;
 import java.util.Collections;
+import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutionException;
@@ -148,13 +149,23 @@
                             KEY_SHAPE_KEY, KEY_SHAPE_TITLE, KEY_PATH, KEY_IS_DEFAULT});
                     String currentShapePath =
                             ThemeManager.INSTANCE.get(context).getIconState().getIconMask();
+                    Optional<IconShapeModel> selectedShape = ShapesProvider.INSTANCE.getIconShapes()
+                            .values()
+                            .stream()
+                            .filter(shape -> shape.getPathString().equals(currentShapePath))
+                            .findFirst();
+                    // Handle default for when current shape doesn't match new shapes.
+                    if (selectedShape.isEmpty()) {
+                        selectedShape = Optional.ofNullable(ShapesProvider.INSTANCE.getIconShapes()
+                                .get("circle"));
+                    }
+
                     for (IconShapeModel shape : ShapesProvider.INSTANCE.getIconShapes().values()) {
                         cursor.newRow()
                                 .add(KEY_SHAPE_KEY, shape.getKey())
                                 .add(KEY_SHAPE_TITLE, shape.getTitle())
                                 .add(KEY_PATH, shape.getPathString())
-                                .add(KEY_IS_DEFAULT,
-                                        shape.getPathString().equals(currentShapePath));
+                                .add(KEY_IS_DEFAULT, shape.equals(selectedShape.get()));
                     }
                     return cursor;
                 } else  {
diff --git a/src/com/android/launcher3/graphics/IconShape.kt b/src/com/android/launcher3/graphics/IconShape.kt
index e62936c..eac3440 100644
--- a/src/com/android/launcher3/graphics/IconShape.kt
+++ b/src/com/android/launcher3/graphics/IconShape.kt
@@ -38,6 +38,7 @@
 import androidx.graphics.shapes.Morph
 import androidx.graphics.shapes.RoundedPolygon
 import androidx.graphics.shapes.SvgPathParser
+import androidx.graphics.shapes.rectangle
 import androidx.graphics.shapes.toPath
 import androidx.graphics.shapes.transformed
 import com.android.launcher3.anim.RoundedRectRevealOutlineProvider
@@ -362,8 +363,8 @@
         }
 
         /**
-         * Creates a rounded rect with the start point at the center of the top edge. This ensures a
-         * better animation since our shape paths also start at top-center of the bounding box.
+         * Create RoundedRect using RoundedPolygon API. Ensures smoother animation morphing between
+         * generic polygon by using [RoundedPolygon.Companion.rectangle] directly.
          */
         fun createRoundedRect(
             left: Float,
@@ -372,27 +373,11 @@
             bottom: Float,
             cornerR: Float,
         ) =
-            RoundedPolygon(
-                vertices =
-                    floatArrayOf(
-                        // x1, y1
-                        (left + right) / 2,
-                        top,
-                        // x2, y2
-                        right,
-                        top,
-                        // x3, y3
-                        right,
-                        bottom,
-                        // x4, y4
-                        left,
-                        bottom,
-                        // x5, y5
-                        left,
-                        top,
-                    ),
-                centerX = (left + right) / 2,
-                centerY = (top + bottom) / 2,
+            RoundedPolygon.rectangle(
+                width = right - left,
+                height = bottom - top,
+                centerX = (right - left) / 2,
+                centerY = (bottom - top) / 2,
                 rounding = CornerRounding(cornerR),
             )
     }
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index 3ee029b..c1ee69b 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -853,8 +853,6 @@
                         + ", isArchived: " + activityInfo.getApplicationInfo().isArchived);
             }
         }
-        logASplit("Loading IconRequestInfo without iconBlob for AppInfo: "
-                + appInfo.getTargetComponent());
         return new IconRequestInfo<>(appInfo, activityInfo, false /* useLowResIcon= */);
     }
 
diff --git a/src/com/android/launcher3/shapes/ShapesProvider.kt b/src/com/android/launcher3/shapes/ShapesProvider.kt
index dfb7793..f1ea3a0 100644
--- a/src/com/android/launcher3/shapes/ShapesProvider.kt
+++ b/src/com/android/launcher3/shapes/ShapesProvider.kt
@@ -202,9 +202,9 @@
             )
         } else {
             mapOf(
-                "default" to
+                "circle" to
                     IconShapeModel(
-                        key = "default",
+                        key = "circle",
                         title = "circle",
                         pathString = "M50 0A50 50,0,1,1,50 100A50 50,0,1,1,50 0",
                     )