Skip to content

Commit

Permalink
feat: 支持在 Splash Screen 上显示 MIUI 桌面大图标
Browse files Browse the repository at this point in the history
  • Loading branch information
GSWXXN committed Sep 1, 2023
1 parent e531ca9 commit 28ba10b
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ package com.gswxxn.restoresplashscreen.data
*
* [NotDrawRoundCorner] 不绘制圆角
* [RoundCorner] 绘制圆角图标
* [MIUIWidget] 绘制小部件圆角
* [Circle] 绘制圆形图标
*/
enum class RoundDegree {
NotDrawRoundCorner,
RoundCorner,
MIUIWidget,
Circle
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import com.gswxxn.restoresplashscreen.hook.systemui.GenerateHookHandler.currentA
import com.gswxxn.restoresplashscreen.hook.systemui.GenerateHookHandler.currentPackageName
import com.gswxxn.restoresplashscreen.utils.GraphicUtils
import com.gswxxn.restoresplashscreen.utils.IconPackManager
import com.gswxxn.restoresplashscreen.utils.LargeIconsHelper
import com.gswxxn.restoresplashscreen.utils.YukiHelper.atLeastMIUI14
import com.gswxxn.restoresplashscreen.utils.YukiHelper.printLog
import com.highcapable.yukihookapi.hook.factory.current
import com.highcapable.yukihookapi.hook.factory.field
Expand All @@ -28,7 +30,9 @@ object IconHookHandler: BaseHookHandler() {
var currentIconDominantColor: Int? = null
private var currentActualBitmapIconSize = 0
private var currentIsNeedShrinkIcon = false
private var currentUseMIUILagerIcon = false
private val iconPackManager by lazy { IconPackManager(appContext!!, prefs.get(DataConst.ICON_PACK_PACKAGE_NAME)) }
private val largeIcons by lazy { LargeIconsHelper(appContext!!) }

/**
* 重置当前应用的属性
Expand All @@ -37,6 +41,7 @@ object IconHookHandler: BaseHookHandler() {
currentIconDominantColor = null
currentActualBitmapIconSize = 0
currentIsNeedShrinkIcon = false
currentUseMIUILagerIcon = false
}

/** 开始 Hook */
Expand All @@ -63,7 +68,11 @@ object IconHookHandler: BaseHookHandler() {

// 执行缩小图标
NewSystemUIHooker.Members.createIconDrawable?.addBeforeHook {
if (currentIsNeedShrinkIcon) {
if (currentUseMIUILagerIcon) {
val mFinalIconSize = instance.current().field { name = "mFinalIconSize" }
mFinalIconSize.set((mFinalIconSize.int() * 1.35).toInt())
printLog("createIconDrawable(): execute enlarge icon")
} else if (currentIsNeedShrinkIcon) {
val mFinalIconSize = instance.current().field { name = "mFinalIconSize" }
mFinalIconSize.set((mFinalIconSize.int() / 1.5).toInt())
printLog("createIconDrawable(): execute shrink icon")
Expand Down Expand Up @@ -118,12 +127,27 @@ object IconHookHandler: BaseHookHandler() {
return ColorDrawable(Color.TRANSPARENT)
}

/**
* 替换获取图标方式
*
* 使用 Context.packageManager.getApplicationIcon() 的方式获取图标
*/
if (enableReplaceIcon || currentPackageName == "com.android.settings") {
if (atLeastMIUI14) {
// MIUI 大图标
largeIcons.getOriginLargeIconDrawable(currentPackageName, "2x2")?.let {
iconDrawable = it
currentUseMIUILagerIcon = true
printLog("getIcon(): use MIUI Large Icon")
}
} else if (iconPackPackageName != "None") {
// 使用图标包
iconDrawable = when {
currentPackageName == "com.android.contacts" && currentActivity == "com.android.contacts.activities.PeopleActivity" ->
iconPackManager.getIconByComponentName("ComponentInfo{com.android.contacts/com.android.contacts.activities.TwelveKeyDialer}")
else -> iconPackManager.getIconByPackageName(currentPackageName)
} ?: iconDrawable
printLog("getIcon(): use Icon Pack")
} else if (enableReplaceIcon || currentPackageName == "com.android.settings") {
/**
* 替换获取图标方式
*
* 使用 Context.packageManager.getApplicationIcon() 的方式获取图标
*/
iconDrawable = when {
currentPackageName == "com.android.contacts" && currentActivity == "com.android.contacts.activities.PeopleActivity" ->
appContext!!.packageManager.getActivityIcon(
Expand All @@ -132,22 +156,11 @@ object IconHookHandler: BaseHookHandler() {
currentPackageName == "com.android.settings" && currentActivity == "com.android.settings.BackgroundApplicationsManager" ->
appContext!!.packageManager.getApplicationIcon("com.android.settings")
else -> appContext!!.packageManager.getApplicationIcon(currentPackageName)

}
printLog("getIcon(): replace way of getting icon")
}
printLog("getIcon(): ${if (enableReplaceIcon || currentPackageName == "com.android.settings") "" else "Not"} replace way of getting icon")

// 使用图标包
if (iconPackPackageName != "None") {
iconDrawable = when {
currentPackageName == "com.android.contacts" && currentActivity == "com.android.contacts.activities.PeopleActivity" ->
iconPackManager.getIconByComponentName("ComponentInfo{com.android.contacts/com.android.contacts.activities.TwelveKeyDialer}")
else -> iconPackManager.getIconByPackageName(currentPackageName)
} ?: iconDrawable
}
printLog("getIcon(): ${if (iconPackPackageName != "None") "" else "Not"} use Icon Pack")

val bitmap = GraphicUtils.drawable2Bitmap(iconDrawable, iconSize)
val bitmap = GraphicUtils.drawable2Bitmap(iconDrawable, if (currentUseMIUILagerIcon) iconSize * 2 else iconSize)

// 判断是否需要缩小图标
when (shrinkIconType) {
Expand All @@ -158,12 +171,14 @@ object IconHookHandler: BaseHookHandler() {
}
printLog("getIcon(): currentIsNeedShrinkIcon: $currentIsNeedShrinkIcon")


// 绘制图标圆角
if (isDrawIconRoundCorner) {
if (currentUseMIUILagerIcon) {
iconDrawable = BitmapDrawable(appResources, GraphicUtils.roundBitmapByShader(bitmap, RoundDegree.MIUIWidget))
printLog("getIcon(): draw MIUI large icon round corner")
} else if (isDrawIconRoundCorner) {
iconDrawable = BitmapDrawable(appResources, GraphicUtils.roundBitmapByShader(bitmap, RoundDegree.RoundCorner))
printLog("getIcon(): draw icon round corner")
}
printLog("getIcon(): ${if (isDrawIconRoundCorner) "" else "Not"} draw icon round corner")

// 获取图标颜色
currentIconDominantColor = GraphicUtils.getBgColor(bitmap,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ object GraphicUtils {
val radius = when (roundDegree) {
RoundDegree.RoundCorner -> bitmap.width / 4
RoundDegree.Circle -> bitmap.width / 2
RoundDegree.MIUIWidget -> bitmap.width / 10
else -> 0
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.gswxxn.restoresplashscreen.utils

import android.content.Context
import android.graphics.drawable.Drawable
import com.highcapable.yukihookapi.hook.factory.current
import com.highcapable.yukihookapi.hook.factory.field
import com.highcapable.yukihookapi.hook.factory.method
import com.highcapable.yukihookapi.hook.factory.toClass
import com.highcapable.yukihookapi.hook.log.loggerE
import com.highcapable.yukihookapi.hook.type.android.UserHandleClass

/**
* 用于从 MIUI 桌面检索大图标的辅助类
*/
class LargeIconsHelper(private val context: Context) {
private val miuiHomeContext = context.createPackageContext(
"com.miui.home",
Context.CONTEXT_INCLUDE_CODE or Context.CONTEXT_IGNORE_SECURITY
)
private val largeIconsHelperClazz = "com.miui.maml.util.LargeIconsHelper".toClass(miuiHomeContext.classLoader)

/**
* 获取指定包名和大小的原始大图标
*
* @param packageName 应用程序的包名
* @param size 图标的大小, 如 "1x2", "2x1", "2x2"
* @return 原始大图标可绘制对象,如果未找到则为 null
*/
fun getOriginLargeIconDrawable(packageName: String, size: String ) = try {
largeIconsHelperClazz.method { name = "getOriginLargeIconDrawable" }.get().call(
context,
packageName,
context.packageManager.getLaunchIntentForPackage(packageName)!!.component!!.className,
"desktop",
"",
size,
0L,
UserHandleClass.field { name = "OWNER" }.get().any()
)!!.current().method { name = "getDrawable" }.invoke<Drawable>()
} catch (e: Throwable) {
loggerE(e = e)
null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.gswxxn.restoresplashscreen.utils

import android.content.Context
import com.gswxxn.restoresplashscreen.data.DataConst
import com.gswxxn.restoresplashscreen.hook.NewSystemUIHooker.toClass
import com.gswxxn.restoresplashscreen.hook.base.BaseHookHandler
import com.gswxxn.restoresplashscreen.utils.CommonUtils.toMap
import com.highcapable.yukihookapi.YukiHookAPI
Expand All @@ -10,7 +11,9 @@ import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
import com.highcapable.yukihookapi.hook.factory.current
import com.highcapable.yukihookapi.hook.factory.dataChannel
import com.highcapable.yukihookapi.hook.factory.hasClass
import com.highcapable.yukihookapi.hook.factory.method
import com.highcapable.yukihookapi.hook.log.loggerI
import com.highcapable.yukihookapi.hook.type.java.StringClass
import com.highcapable.yukihookapi.hook.xposed.prefs.data.PrefsData

/**
Expand Down Expand Up @@ -98,6 +101,22 @@ object YukiHelper {
*/
val isMIUI by lazy { "android.miui.R".hasClass() }

/**
* 检测 MIUI 版本是否至少为 14
*
* @return [Boolean] 是否符合条件
*/
val atLeastMIUI14 by lazy {
isMIUI && try {
"android.os.SystemProperties".toClass().method {
name = "get"
param(StringClass)
}.get().invoke<String>("ro.miui.ui.version.code") ?: ""
} catch (e: Throwable) {
""
}.toInt() >= 14
}

/**
* 当前设备是否是 ColorOS 定制 Android 系统
* @return [Boolean] 是否符合条件
Expand Down

0 comments on commit 28ba10b

Please sign in to comment.