diff --git a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java index b25f99905d..37b8dc7bd8 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java +++ b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java @@ -51,7 +51,7 @@ import com.android.launcher3.anim.AnimatedFloat; import com.android.launcher3.anim.AnimatorListeners; import com.android.launcher3.celllayout.CellLayoutLayoutParams; import com.android.launcher3.celllayout.DelegatedCellDrawing; -import com.android.launcher3.graphics.IconShape; +import com.android.launcher3.graphics.ThemeManager; import com.android.launcher3.icons.FastBitmapDrawable; import com.android.launcher3.icons.IconNormalizer; import com.android.launcher3.icons.LauncherIcons; @@ -142,7 +142,7 @@ public class PredictedAppIcon extends DoubleShadowBubbleTextView { int shadowSize = context.getResources().getDimensionPixelSize( R.dimen.blur_size_thin_outline); mShadowFilter = new BlurMaskFilter(shadowSize, BlurMaskFilter.Blur.OUTER); - mShapePath = IconShape.INSTANCE.get(context).getShape().getPath(mNormalizedIconSize); + mShapePath = ThemeManager.INSTANCE.get(context).getIconShape().getPath(mNormalizedIconSize); } @Override diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java index e6b34574a9..03dd943f50 100644 --- a/src/com/android/launcher3/BubbleTextView.java +++ b/src/com/android/launcher3/BubbleTextView.java @@ -75,8 +75,8 @@ import com.android.launcher3.dot.DotInfo; import com.android.launcher3.dragndrop.DragOptions.PreDragCondition; import com.android.launcher3.dragndrop.DraggableView; import com.android.launcher3.folder.FolderIcon; -import com.android.launcher3.graphics.IconShape; import com.android.launcher3.graphics.PreloadIconDrawable; +import com.android.launcher3.graphics.ShapeDelegate; import com.android.launcher3.icons.DotRenderer; import com.android.launcher3.icons.FastBitmapDrawable; import com.android.launcher3.icons.IconCache.ItemInfoUpdateReceiver; @@ -724,7 +724,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, if (!mForceHideDot && (hasDot() || mDotParams.scale > 0)) { getIconBounds(mDotParams.iconBounds); Utilities.scaleRectAboutCenter(mDotParams.iconBounds, - IconShape.INSTANCE.get(getContext()).getNormalizationScale()); + ShapeDelegate.getNormalizationScale()); final int scrollX = getScrollX(); final int scrollY = getScrollY(); canvas.translate(scrollX, scrollY); @@ -775,7 +775,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, getIconBounds(mRunningAppIconBounds); Utilities.scaleRectAboutCenter( mRunningAppIconBounds, - IconShape.INSTANCE.get(getContext()).getNormalizationScale()); + ShapeDelegate.getNormalizationScale()); final boolean isMinimized = mRunningAppState == RunningAppState.MINIMIZED; final int indicatorTop = mRunningAppIconBounds.bottom + mRunningAppIndicatorTopMargin; diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index 3b283c3cb0..f34add8d3f 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -52,7 +52,7 @@ import androidx.core.content.res.ResourcesCompat; import com.android.launcher3.CellLayout.ContainerType; import com.android.launcher3.DevicePaddings.DevicePadding; import com.android.launcher3.folder.ClippedFolderIconLayoutRule; -import com.android.launcher3.graphics.IconShape; +import com.android.launcher3.graphics.ThemeManager; import com.android.launcher3.icons.DotRenderer; import com.android.launcher3.icons.IconNormalizer; import com.android.launcher3.model.data.ItemInfo; @@ -388,7 +388,7 @@ public class DeviceProfile { /** TODO: Once we fully migrate to staged split, remove "isMultiWindowMode" */ DeviceProfile(Context context, InvariantDeviceProfile inv, Info info, - WindowManagerProxy wmProxy, IconShape iconShape, WindowBounds windowBounds, + WindowManagerProxy wmProxy, ThemeManager themeManager, WindowBounds windowBounds, SparseArray dotRendererCache, boolean isMultiWindowMode, boolean transposeLayoutWithOrientation, boolean isMultiDisplay, boolean isGestureMode, @NonNull final ViewScaleProvider viewScaleProvider, @@ -846,8 +846,8 @@ public class DeviceProfile { dimensionOverrideProvider.accept(this); // This is done last, after iconSizePx is calculated above. - mDotRendererWorkSpace = createDotRenderer(iconShape, iconSizePx, dotRendererCache); - mDotRendererAllApps = createDotRenderer(iconShape, allAppsIconSizePx, dotRendererCache); + mDotRendererWorkSpace = createDotRenderer(themeManager, iconSizePx, dotRendererCache); + mDotRendererAllApps = createDotRenderer(themeManager, allAppsIconSizePx, dotRendererCache); } /** @@ -869,12 +869,12 @@ public class DeviceProfile { } private static DotRenderer createDotRenderer( - @NonNull IconShape iconShape, int size, @NonNull SparseArray cache) { + @NonNull ThemeManager themeManager, int size, @NonNull SparseArray cache) { DotRenderer renderer = cache.get(size); if (renderer == null) { renderer = new DotRenderer( size, - iconShape.getShape().getPath(DEFAULT_DOT_SIZE), + themeManager.getIconShape().getPath(DEFAULT_DOT_SIZE), DEFAULT_DOT_SIZE); cache.put(size, renderer); } @@ -2478,7 +2478,7 @@ public class DeviceProfile { private final InvariantDeviceProfile mInv; private final Info mInfo; private final WindowManagerProxy mWMProxy; - private final IconShape mIconShape; + private final ThemeManager mThemeManager; private WindowBounds mWindowBounds; private boolean mIsMultiDisplay; @@ -2495,12 +2495,12 @@ public class DeviceProfile { private boolean mIsTransientTaskbar; public Builder(Context context, InvariantDeviceProfile inv, Info info, - WindowManagerProxy wmProxy, IconShape iconShape) { + WindowManagerProxy wmProxy, ThemeManager themeManager) { mContext = context; mInv = inv; mInfo = info; mWMProxy = wmProxy; - mIconShape = iconShape; + mThemeManager = themeManager; mIsTransientTaskbar = info.isTransientTaskbar(); } @@ -2581,7 +2581,7 @@ public class DeviceProfile { if (mOverrideProvider == null) { mOverrideProvider = DEFAULT_DIMENSION_PROVIDER; } - return new DeviceProfile(mContext, mInv, mInfo, mWMProxy, mIconShape, + return new DeviceProfile(mContext, mInv, mInfo, mWMProxy, mThemeManager, mWindowBounds, mDotRendererCache, mIsMultiWindowMode, mTransposeLayoutWithOrientation, mIsMultiDisplay, mIsGestureMode, mViewScaleProvider, mOverrideProvider, mIsTransientTaskbar); diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java index 4107c8fdea..c2d6df52a3 100644 --- a/src/com/android/launcher3/InvariantDeviceProfile.java +++ b/src/com/android/launcher3/InvariantDeviceProfile.java @@ -57,7 +57,7 @@ import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.dagger.ApplicationContext; import com.android.launcher3.dagger.LauncherAppComponent; import com.android.launcher3.dagger.LauncherAppSingleton; -import com.android.launcher3.graphics.IconShape; +import com.android.launcher3.graphics.ThemeManager; import com.android.launcher3.icons.DotRenderer; import com.android.launcher3.logging.FileLog; import com.android.launcher3.model.DeviceGridState; @@ -136,7 +136,7 @@ public class InvariantDeviceProfile { private final DisplayController mDisplayController; private final WindowManagerProxy mWMProxy; private final LauncherPrefs mPrefs; - private final IconShape mIconShape; + private final ThemeManager mThemeManager; /** * Number of icons per row and column in the workspace. @@ -260,12 +260,12 @@ public class InvariantDeviceProfile { LauncherPrefs prefs, DisplayController dc, WindowManagerProxy wmProxy, - IconShape iconShape, + ThemeManager themeManager, DaggerSingletonTracker lifeCycle) { mDisplayController = dc; mWMProxy = wmProxy; mPrefs = prefs; - mIconShape = iconShape; + mThemeManager = themeManager; String gridName = prefs.get(GRID_NAME); initGrid(context, gridName); @@ -490,7 +490,7 @@ public class InvariantDeviceProfile { } DeviceProfile.Builder newDPBuilder(Context context, Info info) { - return new DeviceProfile.Builder(context, this, info, mWMProxy, mIconShape); + return new DeviceProfile.Builder(context, this, info, mWMProxy, mThemeManager); } public void addOnChangeListener(OnIDPChangeListener listener) { diff --git a/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java b/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java index 35ae68f903..31d0da08db 100644 --- a/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java +++ b/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java @@ -20,7 +20,6 @@ import android.content.Context; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherPrefs; -import com.android.launcher3.graphics.IconShape; import com.android.launcher3.graphics.ThemeManager; import com.android.launcher3.icons.LauncherIcons.IconPool; import com.android.launcher3.model.ItemInstallQueue; @@ -57,7 +56,6 @@ public interface LauncherBaseAppComponent { ApiWrapper getApiWrapper(); CustomWidgetManager getCustomWidgetManager(); DynamicResource getDynamicResource(); - IconShape getIconShape(); InstallSessionHelper getInstallSessionHelper(); ItemInstallQueue getItemInstallQueue(); RefreshRateTracker getRefreshRateTracker(); diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java index 072673d1ea..bff323ceb3 100644 --- a/src/com/android/launcher3/dragndrop/DragView.java +++ b/src/com/android/launcher3/dragndrop/DragView.java @@ -60,7 +60,7 @@ import androidx.dynamicanimation.animation.SpringForce; import com.android.app.animation.Interpolators; import com.android.launcher3.R; import com.android.launcher3.Utilities; -import com.android.launcher3.graphics.IconShape; +import com.android.launcher3.graphics.ThemeManager; import com.android.launcher3.icons.FastBitmapDrawable; import com.android.launcher3.icons.LauncherIcons; import com.android.launcher3.model.data.ItemInfo; @@ -274,9 +274,9 @@ public abstract class DragView extends Fram Utilities.scaleRectAboutCenter(shrunkBounds, 0.98f); adaptiveIcon.setBounds(shrunkBounds); - IconShape iconShape = IconShape.INSTANCE.get(getContext()); + ThemeManager themeManager = ThemeManager.INSTANCE.get(getContext()); final Path mask = (adaptiveIcon instanceof FolderAdaptiveIcon - ? iconShape.getFolderShape() : iconShape.getShape()) + ? themeManager.getFolderShape() : themeManager.getIconShape()) .getPath(shrunkBounds); mTranslateX = new SpringFloatValue(DragView.this, diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java index 215761083b..d2354c18e1 100644 --- a/src/com/android/launcher3/folder/FolderAnimationManager.java +++ b/src/com/android/launcher3/folder/FolderAnimationManager.java @@ -46,8 +46,8 @@ import com.android.launcher3.Utilities; import com.android.launcher3.anim.PropertyResetListener; import com.android.launcher3.apppairs.AppPairIcon; import com.android.launcher3.celllayout.CellLayoutLayoutParams; -import com.android.launcher3.graphics.IconShape; -import com.android.launcher3.graphics.IconShape.ShapeDelegate; +import com.android.launcher3.graphics.ShapeDelegate; +import com.android.launcher3.graphics.ThemeManager; import com.android.launcher3.util.Themes; import com.android.launcher3.views.BaseDragLayer; @@ -237,7 +237,7 @@ public class FolderAnimationManager { } play(a, getAnimator(mFolder.mFooter, ALPHA, 0, 1f), footerStartDelay, footerAlphaDuration); - ShapeDelegate shapeDelegate = IconShape.INSTANCE.get(mContext).getFolderShape(); + ShapeDelegate shapeDelegate = ThemeManager.INSTANCE.get(mContext).getFolderShape(); // Create reveal animator for the folder background play(a, shapeDelegate.createRevealAnimator( mFolder, startRect, endRect, finalRadius, !mIsOpening)); diff --git a/src/com/android/launcher3/folder/PreviewBackground.java b/src/com/android/launcher3/folder/PreviewBackground.java index 77fa355803..ba8a290392 100644 --- a/src/com/android/launcher3/folder/PreviewBackground.java +++ b/src/com/android/launcher3/folder/PreviewBackground.java @@ -47,8 +47,8 @@ import com.android.launcher3.CellLayout; import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; import com.android.launcher3.celllayout.DelegatedCellDrawing; -import com.android.launcher3.graphics.IconShape; -import com.android.launcher3.graphics.IconShape.ShapeDelegate; +import com.android.launcher3.graphics.ShapeDelegate; +import com.android.launcher3.graphics.ThemeManager; import com.android.launcher3.util.Themes; import com.android.launcher3.views.ActivityContext; @@ -260,7 +260,7 @@ public class PreviewBackground extends DelegatedCellDrawing { } private ShapeDelegate getShape() { - return IconShape.INSTANCE.get(mContext).getFolderShape(); + return ThemeManager.INSTANCE.get(mContext).getFolderShape(); } public void drawShadow(Canvas canvas) { diff --git a/src/com/android/launcher3/graphics/PreloadIconDrawable.java b/src/com/android/launcher3/graphics/PreloadIconDrawable.java index 50d6d1c4d6..3bd9fb54ca 100644 --- a/src/com/android/launcher3/graphics/PreloadIconDrawable.java +++ b/src/com/android/launcher3/graphics/PreloadIconDrawable.java @@ -119,7 +119,7 @@ public class PreloadIconDrawable extends FastBitmapDrawable { IconPalette.getPreloadProgressColor(context, info.bitmap.color), getPreloadColors(context), Utilities.isDarkTheme(context), - IconShape.INSTANCE.get(context).getShape().getPath(DEFAULT_PATH_SIZE) + ThemeManager.INSTANCE.get(context).getIconShape().getPath(DEFAULT_PATH_SIZE) ); } diff --git a/src/com/android/launcher3/graphics/IconShape.kt b/src/com/android/launcher3/graphics/ShapeDelegate.kt similarity index 81% rename from src/com/android/launcher3/graphics/IconShape.kt rename to src/com/android/launcher3/graphics/ShapeDelegate.kt index eac34406c2..df0c8f9aa6 100644 --- a/src/com/android/launcher3/graphics/IconShape.kt +++ b/src/com/android/launcher3/graphics/ShapeDelegate.kt @@ -42,78 +42,38 @@ import androidx.graphics.shapes.rectangle import androidx.graphics.shapes.toPath import androidx.graphics.shapes.transformed import com.android.launcher3.anim.RoundedRectRevealOutlineProvider -import com.android.launcher3.dagger.LauncherAppComponent -import com.android.launcher3.dagger.LauncherAppSingleton -import com.android.launcher3.graphics.ThemeManager.ThemeChangeListener import com.android.launcher3.icons.GraphicsUtils import com.android.launcher3.icons.IconNormalizer.normalizeAdaptiveIcon -import com.android.launcher3.util.DaggerSingletonObject -import com.android.launcher3.util.DaggerSingletonTracker import com.android.launcher3.views.ClipPathView -import javax.inject.Inject /** Abstract representation of the shape of an icon shape */ -@LauncherAppSingleton -class IconShape -@Inject -constructor(private val themeManager: ThemeManager, lifeCycle: DaggerSingletonTracker) { +interface ShapeDelegate { - val normalizationScale = - normalizeAdaptiveIcon( - AdaptiveIconDrawable(null, ColorDrawable(Color.BLACK)), - AREA_CALC_SIZE, - ) + fun getPath(pathSize: Float = DEFAULT_PATH_SIZE) = + Path().apply { addToPath(this, 0f, 0f, pathSize / 2) } - var shape: ShapeDelegate = pickBestShape(themeManager.iconState.iconMask) - private set - - var folderShape: ShapeDelegate = - themeManager.iconState.run { - if (folderShapeMask == iconMask || folderShapeMask.isEmpty()) shape - else pickBestShape(folderShapeMask) + fun getPath(bounds: Rect) = + Path().apply { + addToPath( + this, + bounds.left.toFloat(), + bounds.top.toFloat(), + // Radius is half of the average size of the icon + (bounds.width() + bounds.height()) / 4f, + ) } - private set - init { - val changeListener = ThemeChangeListener { - shape = pickBestShape(themeManager.iconState.iconMask) - folderShape = - themeManager.iconState.run { - if (folderShapeMask == iconMask || folderShapeMask.isEmpty()) shape - else pickBestShape(folderShapeMask) - } - } - themeManager.addChangeListener(changeListener) - lifeCycle.addCloseable { themeManager.removeChangeListener(changeListener) } - } + fun drawShape(canvas: Canvas, offsetX: Float, offsetY: Float, radius: Float, paint: Paint) - interface ShapeDelegate { - fun getPath(pathSize: Float = DEFAULT_PATH_SIZE) = - Path().apply { addToPath(this, 0f, 0f, pathSize / 2) } + fun addToPath(path: Path, offsetX: Float, offsetY: Float, radius: Float) - fun getPath(bounds: Rect) = - Path().apply { - addToPath( - this, - bounds.left.toFloat(), - bounds.top.toFloat(), - // Radius is half of the average size of the icon - (bounds.width() + bounds.height()) / 4f, - ) - } - - fun drawShape(canvas: Canvas, offsetX: Float, offsetY: Float, radius: Float, paint: Paint) - - fun addToPath(path: Path, offsetX: Float, offsetY: Float, radius: Float) - - fun createRevealAnimator( - target: T, - startRect: Rect, - endRect: Rect, - endRadius: Float, - isReversed: Boolean, - ): ValueAnimator where T : View, T : ClipPathView - } + fun createRevealAnimator( + target: T, + startRect: Rect, + endRect: Rect, + endRadius: Float, + isReversed: Boolean, + ): ValueAnimator where T : View, T : ClipPathView class Circle : RoundedSquare(1f) { @@ -179,10 +139,15 @@ constructor(private val themeManager: ThemeManager, lifeCycle: DaggerSingletonTr } .createRevealAnimator(target, isReversed) } + + override fun equals(other: Any?) = + other is RoundedSquare && other.radiusRatio == radiusRatio + + override fun hashCode() = radiusRatio.hashCode() } /** Generic shape delegate with pathString in bounds [0, 0, 100, 100] */ - class GenericPathShape(pathString: String) : ShapeDelegate { + data class GenericPathShape(private val pathString: String) : ShapeDelegate { private val poly = RoundedPolygon( features = SvgPathParser.parseFeatures(pathString), @@ -287,7 +252,6 @@ constructor(private val themeManager: ThemeManager, lifeCycle: DaggerSingletonTr } companion object { - @JvmField var INSTANCE = DaggerSingletonObject(LauncherAppComponent::getIconShape) const val TAG = "IconShape" const val DEFAULT_PATH_SIZE = 100f @@ -312,7 +276,6 @@ constructor(private val themeManager: ThemeManager, lifeCycle: DaggerSingletonTr } } - @VisibleForTesting fun pickBestShape(shapeStr: String): ShapeDelegate { val baseShape = if (shapeStr.isNotEmpty()) { @@ -332,7 +295,6 @@ constructor(private val themeManager: ThemeManager, lifeCycle: DaggerSingletonTr return pickBestShape(baseShape, shapeStr) } - @VisibleForTesting fun pickBestShape(baseShape: Path, shapeStr: String): ShapeDelegate { val calcAreaDiff = areaDiffCalculator(baseShape) @@ -380,5 +342,12 @@ constructor(private val themeManager: ThemeManager, lifeCycle: DaggerSingletonTr centerY = (bottom - top) / 2, rounding = CornerRounding(cornerR), ) + + @JvmStatic + val normalizationScale = + normalizeAdaptiveIcon( + AdaptiveIconDrawable(null, ColorDrawable(Color.BLACK)), + AREA_CALC_SIZE, + ) } } diff --git a/src/com/android/launcher3/graphics/ThemeManager.kt b/src/com/android/launcher3/graphics/ThemeManager.kt index e767290d8d..4a0ff8c58c 100644 --- a/src/com/android/launcher3/graphics/ThemeManager.kt +++ b/src/com/android/launcher3/graphics/ThemeManager.kt @@ -25,6 +25,7 @@ import com.android.launcher3.LauncherPrefs.Companion.backedUpItem import com.android.launcher3.dagger.ApplicationContext import com.android.launcher3.dagger.LauncherAppComponent import com.android.launcher3.dagger.LauncherAppSingleton +import com.android.launcher3.graphics.ShapeDelegate.Companion.pickBestShape import com.android.launcher3.icons.IconThemeController import com.android.launcher3.icons.mono.MonoIconThemeController import com.android.launcher3.shapes.ShapesProvider @@ -46,19 +47,25 @@ constructor( ) { /** Representation of the current icon state */ - var iconState = parseIconState() + var iconState = parseIconState(null) private set var isMonoThemeEnabled set(value) = prefs.put(THEMED_ICONS, value) get() = prefs.get(THEMED_ICONS) - val themeController: IconThemeController? + val themeController get() = iconState.themeController - val isIconThemeEnabled: Boolean + val isIconThemeEnabled get() = themeController != null + val iconShape + get() = iconState.iconShape + + val folderShape + get() = iconState.folderShape + private val listeners = CopyOnWriteArrayList() init { @@ -80,7 +87,7 @@ constructor( } protected fun verifyIconState() { - val newState = parseIconState() + val newState = parseIconState(iconState) if (newState == iconState) return iconState = newState @@ -91,7 +98,7 @@ constructor( fun removeChangeListener(listener: ThemeChangeListener) = listeners.remove(listener) - private fun parseIconState(): IconState { + private fun parseIconState(oldState: IconState?): IconState { val shapeModel = prefs.get(PREF_ICON_SHAPE).let { shapeOverride -> ShapesProvider.iconShapes.values.firstOrNull { it.key == shapeOverride } @@ -102,11 +109,27 @@ constructor( CONFIG_ICON_MASK_RES_ID == Resources.ID_NULL -> "" else -> context.resources.getString(CONFIG_ICON_MASK_RES_ID) } + + val iconShape = + if (oldState != null && oldState.iconMask == iconMask) oldState.iconShape + else pickBestShape(iconMask) + + val folderShapeMask = shapeModel?.folderPathString ?: iconMask + val folderShape = + when { + oldState != null && oldState.folderShapeMask == folderShapeMask -> + oldState.folderShape + folderShapeMask == iconMask || folderShapeMask.isEmpty() -> iconShape + else -> pickBestShape(folderShapeMask) + } + return IconState( iconMask = iconMask, - folderShapeMask = shapeModel?.folderPathString ?: iconMask, + folderShapeMask = folderShapeMask, themeController = createThemeController(), iconScale = shapeModel?.iconScale ?: 1f, + iconShape = iconShape, + folderShape = folderShape, ) } @@ -120,6 +143,8 @@ constructor( val themeController: IconThemeController?, val themeCode: String = themeController?.themeID ?: "no-theme", val iconScale: Float = 1f, + val iconShape: ShapeDelegate, + val folderShape: ShapeDelegate, ) { fun toUniqueId() = "${iconMask.hashCode()},$themeCode" } diff --git a/src/com/android/launcher3/icons/LauncherIconProvider.java b/src/com/android/launcher3/icons/LauncherIconProvider.java index 482360cb0b..836b7d1c00 100644 --- a/src/com/android/launcher3/icons/LauncherIconProvider.java +++ b/src/com/android/launcher3/icons/LauncherIconProvider.java @@ -30,7 +30,7 @@ import androidx.annotation.Nullable; import com.android.launcher3.R; import com.android.launcher3.config.FeatureFlags; -import com.android.launcher3.graphics.IconShape; +import com.android.launcher3.graphics.ShapeDelegate; import com.android.launcher3.graphics.ThemeManager; import com.android.launcher3.util.ApiWrapper; @@ -54,13 +54,13 @@ public class LauncherIconProvider extends IconProvider { private Map mThemedIconMap; private final ApiWrapper mApiWrapper; - private final IconShape mIconShape; + private final ThemeManager mThemeManager; public LauncherIconProvider(Context context) { super(context); - setIconThemeSupported(ThemeManager.INSTANCE.get(context).isMonoThemeEnabled()); + mThemeManager = ThemeManager.INSTANCE.get(context); mApiWrapper = ApiWrapper.INSTANCE.get(context); - mIconShape = IconShape.INSTANCE.get(context); + setIconThemeSupported(mThemeManager.isMonoThemeEnabled()); } /** @@ -91,7 +91,7 @@ public class LauncherIconProvider extends IconProvider { @Override protected Drawable loadAppInfoIcon(ApplicationInfo info, Resources resources, int density) { // Tries to load the round icon res, if the app defines it as an adaptive icon - if (mIconShape.getShape() instanceof IconShape.Circle) { + if (mThemeManager.getIconShape() instanceof ShapeDelegate.Circle) { int roundIconRes = mApiWrapper.getRoundIconRes(info); if (roundIconRes != 0 && roundIconRes != info.icon) { try { diff --git a/src/com/android/launcher3/icons/LauncherIcons.kt b/src/com/android/launcher3/icons/LauncherIcons.kt index d173fd657c..6c018e87eb 100644 --- a/src/com/android/launcher3/icons/LauncherIcons.kt +++ b/src/com/android/launcher3/icons/LauncherIcons.kt @@ -27,7 +27,6 @@ import com.android.launcher3.InvariantDeviceProfile import com.android.launcher3.dagger.ApplicationContext import com.android.launcher3.dagger.LauncherAppSingleton import com.android.launcher3.dagger.LauncherComponentProvider.appComponent -import com.android.launcher3.graphics.IconShape import com.android.launcher3.graphics.ThemeManager import com.android.launcher3.pm.UserCache import com.android.launcher3.util.UserIconInfo @@ -46,9 +45,8 @@ class LauncherIcons internal constructor( @ApplicationContext context: Context, idp: InvariantDeviceProfile, - themeManager: ThemeManager, + private var themeManager: ThemeManager, private var userCache: UserCache, - private var iconShape: IconShape, @Assisted private val pool: ConcurrentLinkedQueue, ) : BaseIconFactory(context, idp.fillResIconDpi, idp.iconBitmapSize), AutoCloseable { @@ -70,7 +68,7 @@ internal constructor( public override fun getShapePath(drawable: AdaptiveIconDrawable, iconBounds: Rect): Path { if (!Flags.enableLauncherIconShapes()) return drawable.iconMask - return iconShape.shape.getPath(iconBounds) + return themeManager.iconShape.getPath(iconBounds) } override fun drawAdaptiveIcon( diff --git a/src/com/android/launcher3/views/ClipIconView.java b/src/com/android/launcher3/views/ClipIconView.java index f90a3e4dd1..ddf18dfbaa 100644 --- a/src/com/android/launcher3/views/ClipIconView.java +++ b/src/com/android/launcher3/views/ClipIconView.java @@ -47,7 +47,8 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.dragndrop.FolderAdaptiveIcon; -import com.android.launcher3.graphics.IconShape; +import com.android.launcher3.graphics.ShapeDelegate; +import com.android.launcher3.graphics.ThemeManager; /** * A view used to draw both layers of an {@link AdaptiveIconDrawable}. @@ -174,7 +175,7 @@ public class ClipIconView extends View implements ClipPathView { if (mIsAdaptiveIcon) { if (!isOpening && progress >= shapeProgressStart) { if (mRevealAnimator == null) { - mRevealAnimator = IconShape.INSTANCE.get(getContext()).getShape() + mRevealAnimator = ThemeManager.INSTANCE.get(getContext()).getIconShape() .createRevealAnimator(this, mStartRevealRect, mOutline, mTaskCornerRadius, !isOpening); mRevealAnimator.addListener(forEndCallback(() -> mRevealAnimator = null)); @@ -259,7 +260,7 @@ public class ClipIconView extends View implements ClipPathView { if (!isFolderIcon) { Utilities.scaleRectAboutCenter(mStartRevealRect, - IconShape.INSTANCE.get(getContext()).getNormalizationScale()); + ShapeDelegate.getNormalizationScale()); } if (dp.isLandscape) { diff --git a/tests/multivalentTests/src/com/android/launcher3/FakeInvariantDeviceProfileTest.kt b/tests/multivalentTests/src/com/android/launcher3/FakeInvariantDeviceProfileTest.kt index 060c28c8e2..f855c51f8e 100644 --- a/tests/multivalentTests/src/com/android/launcher3/FakeInvariantDeviceProfileTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/FakeInvariantDeviceProfileTest.kt @@ -71,7 +71,7 @@ abstract class FakeInvariantDeviceProfileTest { inv, info, context.appComponent.wmProxy, - context.appComponent.iconShape, + context.appComponent.themeManager, windowBounds, SparseArray(), /*isMultiWindowMode=*/ false, diff --git a/tests/multivalentTests/src/com/android/launcher3/graphics/IconShapeTest.kt b/tests/multivalentTests/src/com/android/launcher3/graphics/ShapeDelegateTest.kt similarity index 93% rename from tests/multivalentTests/src/com/android/launcher3/graphics/IconShapeTest.kt rename to tests/multivalentTests/src/com/android/launcher3/graphics/ShapeDelegateTest.kt index 311676a34b..7e38f0e0ea 100644 --- a/tests/multivalentTests/src/com/android/launcher3/graphics/IconShapeTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/graphics/ShapeDelegateTest.kt @@ -28,13 +28,13 @@ import android.view.View import androidx.core.graphics.PathParser import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.launcher3.graphics.IconShape.Circle -import com.android.launcher3.graphics.IconShape.Companion.AREA_CALC_SIZE -import com.android.launcher3.graphics.IconShape.Companion.AREA_DIFF_THRESHOLD -import com.android.launcher3.graphics.IconShape.Companion.areaDiffCalculator -import com.android.launcher3.graphics.IconShape.Companion.pickBestShape -import com.android.launcher3.graphics.IconShape.GenericPathShape -import com.android.launcher3.graphics.IconShape.RoundedSquare +import com.android.launcher3.graphics.ShapeDelegate.Circle +import com.android.launcher3.graphics.ShapeDelegate.Companion.AREA_CALC_SIZE +import com.android.launcher3.graphics.ShapeDelegate.Companion.AREA_DIFF_THRESHOLD +import com.android.launcher3.graphics.ShapeDelegate.Companion.areaDiffCalculator +import com.android.launcher3.graphics.ShapeDelegate.Companion.pickBestShape +import com.android.launcher3.graphics.ShapeDelegate.GenericPathShape +import com.android.launcher3.graphics.ShapeDelegate.RoundedSquare import com.android.launcher3.icons.GraphicsUtils import com.android.launcher3.views.ClipPathView import com.google.common.truth.Truth.assertThat @@ -43,7 +43,7 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) -class IconShapeTest { +class ShapeDelegateTest { @Test fun `areaDiffCalculator increases with outwards shape`() { diff --git a/tests/multivalentTests/src/com/android/launcher3/shapes/ShapesProviderTest.kt b/tests/multivalentTests/src/com/android/launcher3/shapes/ShapesProviderTest.kt index 2b8896ec9e..508c9a492d 100644 --- a/tests/multivalentTests/src/com/android/launcher3/shapes/ShapesProviderTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/shapes/ShapesProviderTest.kt @@ -22,7 +22,7 @@ import androidx.core.graphics.PathParser import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.launcher3.Flags.FLAG_ENABLE_LAUNCHER_ICON_SHAPES -import com.android.launcher3.graphics.IconShape.GenericPathShape +import com.android.launcher3.graphics.ShapeDelegate.GenericPathShape import com.android.systemui.shared.Flags.FLAG_NEW_CUSTOMIZATION_PICKER_UI import org.junit.Rule import org.junit.Test