diff --git a/app/src/main/java/com/yifeplayte/wommo/hook/hooks/singlepackage/home/FakeNonDefaultIcon.kt b/app/src/main/java/com/yifeplayte/wommo/hook/hooks/singlepackage/home/FakeNonDefaultIcon.kt index 4b2c09d..4221b30 100644 --- a/app/src/main/java/com/yifeplayte/wommo/hook/hooks/singlepackage/home/FakeNonDefaultIcon.kt +++ b/app/src/main/java/com/yifeplayte/wommo/hook/hooks/singlepackage/home/FakeNonDefaultIcon.kt @@ -2,6 +2,7 @@ package com.yifeplayte.wommo.hook.hooks.singlepackage.home import android.graphics.Matrix import android.graphics.Path +import android.graphics.RectF import android.view.View import android.widget.FrameLayout import com.github.kyuubiran.ezxhelper.ClassUtils.invokeStaticMethodBestMatch @@ -12,54 +13,52 @@ import com.github.kyuubiran.ezxhelper.ObjectUtils.getObjectOrNullAs import com.github.kyuubiran.ezxhelper.ObjectUtils.invokeMethodBestMatch import com.github.kyuubiran.ezxhelper.finders.MethodFinder.`-Static`.methodFinder import com.yifeplayte.wommo.hook.hooks.BaseHook - +import java.lang.Thread.currentThread @Suppress("unused") object FakeNonDefaultIcon : BaseHook() { override val key = "fake_non_default_icon" private val clazzFolderPreviewIconView by lazy { loadClassOrNull("com.miui.home.launcher.folder.FolderPreviewIconView") } private val clazzPathDataIconUtil by lazy { loadClass("com.miui.home.launcher.PathDataIconUtil") } + private val clazzDeviceConfig by lazy { loadClass("com.miui.home.launcher.DeviceConfig") } override fun hook() { - loadClass("com.miui.home.launcher.DeviceConfig").methodFinder() - .filterByName("isDefaultIcon").single().createHook { - before { param -> - param.result = - Thread.currentThread().stackTrace.any { it.methodName == "isBlurSupported" } - } - } + clazzDeviceConfig.methodFinder().filterByName("isDefaultIcon").single().createHook { + returnConstant(currentThread().stackTrace.any { it.methodName == "isBlurSupported" }) + } loadClass("com.miui.home.recents.views.FloatingIconView").methodFinder() .filterByName("updateClipPath").single().createHook { before { param -> + val thisObject = param.thisObject val layoutParams = param.args[0] as FrameLayout.LayoutParams val scaleFactor = param.args[1] as Float - val animTarget = invokeMethodBestMatch(param.thisObject, "getAnimTarget") + val animTarget = invokeMethodBestMatch(thisObject, "getAnimTarget") if (clazzFolderPreviewIconView?.isInstance(animTarget) != true) return@before val iconImageView = invokeMethodBestMatch(animTarget!!, "getIconImageView") as? View ?: return@before param.result = null - val mClipPath = getObjectOrNullAs(param.thisObject, "mClipPath")!! + val mClipPath = getObjectOrNullAs(thisObject, "mClipPath")!! val mForegroundClipPath = - getObjectOrNullAs(param.thisObject, "mForegroundClipPath")!! + getObjectOrNullAs(thisObject, "mForegroundClipPath")!! val mIsAdaptiveIcon = - getObjectOrNullAs(param.thisObject, "mIsAdaptiveIcon")!! + getObjectOrNullAs(thisObject, "mIsAdaptiveIcon")!! val mScaleMatrixForClipPath = - getObjectOrNullAs(param.thisObject, "mScaleMatrixForClipPath")!! + getObjectOrNullAs(thisObject, "mScaleMatrixForClipPath")!! val mTaskCornerRadius = - getObjectOrNullAs(param.thisObject, "mTaskCornerRadius")!! + getObjectOrNullAs(thisObject, "mTaskCornerRadius")!! mClipPath.reset() mForegroundClipPath.reset() var iconVerticalEdge = if (invokeStaticMethodBestMatch( - loadClass("com.miui.home.launcher.DeviceConfig"), "isNewIcons" + clazzDeviceConfig, "isNewIcons" ) as Boolean ) 0f else { invokeMethodBestMatch( - param.thisObject, "getIconTransparentEdge" + thisObject, "getIconTransparentEdge" ) as Int * scaleFactor } var iconHorizontalEdge = iconVerticalEdge @@ -67,9 +66,8 @@ object FakeNonDefaultIcon : BaseHook() { val isSupportThemeAdaptiveIcon = invokeStaticMethodBestMatch( clazzPathDataIconUtil, "isSupportThemeAdaptiveIcon" ) as Boolean - val isDefaultIcon = invokeStaticMethodBestMatch( - loadClass("com.miui.home.launcher.DeviceConfig"), "isDefaultIcon" - ) as Boolean + val isDefaultIcon = + invokeStaticMethodBestMatch(clazzDeviceConfig, "isDefaultIcon") as Boolean if (isSupportThemeAdaptiveIcon && !isDefaultIcon && mIsAdaptiveIcon) { val iconWidth = iconImageView.width @@ -122,5 +120,126 @@ object FakeNonDefaultIcon : BaseHook() { ) } } + + loadClass("com.miui.home.recents.views.FloatingIconView2").methodFinder() + .filterByName("updateClipPath").singleOrNull()?.createHook { + before { param -> + val thisObject = param.thisObject + val layoutParams = param.args[0] as FrameLayout.LayoutParams + val scaleFactor = param.args[1] as Float + val cornerRadiusScale = param.args[2] as Float + val rectF = param.args[3] as RectF + + val animTarget = invokeMethodBestMatch(param.thisObject, "getAnimTarget") + if (clazzFolderPreviewIconView?.isInstance(animTarget) != true) return@before + val iconImageView = + invokeMethodBestMatch(animTarget!!, "getIconImageView") as? View + ?: return@before + param.result = null + + val mClipPath = getObjectOrNullAs(thisObject, "mClipPath")!! + val mForegroundClipPath = + getObjectOrNullAs(thisObject, "mForegroundClipPath")!! + val mIsAdaptiveIcon = + getObjectOrNullAs(thisObject, "mIsAdaptiveIcon")!! + val mScaleMatrixForClipPath = + getObjectOrNullAs(thisObject, "mScaleMatrixForClipPath")!! + val mTaskCornerRadius = + getObjectOrNullAs(thisObject, "mTaskCornerRadius")!! + val mUseSurfaceShade = + getObjectOrNullAs(thisObject, "mUseSurfaceShade")!! + val mShadeClipPath = getObjectOrNullAs(thisObject, "mShadeClipPath")!! + val mCurRectF = getObjectOrNullAs(thisObject, "mCurRectF")!! + val mShortcutIconImageViewRect = + getObjectOrNullAs(thisObject, "mShortcutIconImageViewRect")!! + + mClipPath.reset() + mForegroundClipPath.reset() + + var iconVerticalEdge = if (invokeStaticMethodBestMatch( + clazzDeviceConfig, "isNewIcons" + ) as Boolean + ) 0f else { + invokeMethodBestMatch( + thisObject, "getIconTransparentEdge" + ) as Int * scaleFactor + } + var iconHorizontalEdge = iconVerticalEdge + + if (mUseSurfaceShade) { + val shadeCornerRadius = + (layoutParams.width * cornerRadiusScale) / rectF.width() + mShadeClipPath.reset() + mShadeClipPath.addRoundRect( + iconVerticalEdge, + iconHorizontalEdge, + layoutParams.width - iconVerticalEdge, + layoutParams.height - iconHorizontalEdge, + shadeCornerRadius, + shadeCornerRadius, + Path.Direction.CW + ) + } + + val isSupportThemeAdaptiveIcon = invokeStaticMethodBestMatch( + clazzPathDataIconUtil, "isSupportThemeAdaptiveIcon" + ) as Boolean + val isDefaultIcon = + invokeStaticMethodBestMatch(clazzDeviceConfig, "isDefaultIcon") as Boolean + + if (isSupportThemeAdaptiveIcon && !isDefaultIcon && mIsAdaptiveIcon) { + val iconWidth = iconImageView.width + val iconHeight = iconImageView.height + + val isIconClipPathDataARect = invokeStaticMethodBestMatch( + clazzPathDataIconUtil, "isIconClipPathDataARect" + ) as Boolean + val pathFromPathDataForClipIcon = invokeStaticMethodBestMatch( + clazzPathDataIconUtil, "getPathFromPathDataForClipIcon" + ) as Path? + + if (isIconClipPathDataARect) { + iconHorizontalEdge = ((1.0f - invokeStaticMethodBestMatch( + clazzPathDataIconUtil, "getPathDataWidthPercent" + ) as Float) * iconWidth) / 2.0f + iconVerticalEdge = ((1.0f - invokeStaticMethodBestMatch( + clazzPathDataIconUtil, "getPathDataHeightPercent" + ) as Float) * iconHeight) / 2.0f + } else if (pathFromPathDataForClipIcon != null) { + mClipPath.set(pathFromPathDataForClipIcon) + val aspectRatio = (layoutParams.height / layoutParams.width).toFloat() + mScaleMatrixForClipPath.reset() + mScaleMatrixForClipPath.setScale( + iconWidth / 100.0f, (iconHeight / 100.0f) * aspectRatio + ) + mClipPath.transform(mScaleMatrixForClipPath) + return@before + } + } + + val newCornerRadius = + mTaskCornerRadius * mShortcutIconImageViewRect.width() / mCurRectF.width() + + mClipPath.addRoundRect( + iconHorizontalEdge, + iconVerticalEdge, + layoutParams.width - iconHorizontalEdge, + layoutParams.height - iconVerticalEdge, + newCornerRadius, + newCornerRadius, + Path.Direction.CW + ) + + mForegroundClipPath.addRoundRect( + iconHorizontalEdge, + iconVerticalEdge, + layoutParams.width - iconHorizontalEdge, + layoutParams.width - iconVerticalEdge, + newCornerRadius, + newCornerRadius, + Path.Direction.CW + ) + } + } } } \ No newline at end of file