Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ jobs:

steps:
- name: Checkout Repository
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
submodules: true

- name: Set up JDK 20
uses: actions/setup-java@v4
- name: Set up JDK
uses: actions/setup-java@v5
with:
java-version: "20"
java-version: "21"
distribution: "temurin"

- name: Build with Gradle and Sign
Expand Down
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ android {
isMinifyEnabled = true
isShrinkResources = true
vcsInfo.include = false
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}

Expand Down Expand Up @@ -127,7 +127,7 @@ fun getGitHeadRefsSuffix(project: Project): String {
// 示例:"90312cd9157587d11779ed7be776e3220050b308\n"
refFile.readText(Charsets.UTF_8).replace(Regex("""\s"""), "").subSequence(0, 7)
} else {
string.substring(0, 7)
string.take(7)
}
println("commit_id: $result")
return result.toString()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import com.highcapable.yukihookapi.hook.factory.constructor
import com.highcapable.yukihookapi.hook.factory.method
import com.highcapable.yukihookapi.hook.log.YLog
import com.highcapable.yukihookapi.hook.type.android.ActivityInfoClass
import com.highcapable.yukihookapi.hook.type.android.ComponentInfoClass
import com.highcapable.yukihookapi.hook.type.android.DrawableClass
import com.highcapable.yukihookapi.hook.type.java.FloatType
import com.highcapable.yukihookapi.hook.type.java.IntType
Expand Down Expand Up @@ -54,7 +55,7 @@ object NewSystemUIHooker: YukiBaseHooker() {
"com.android.launcher3.icons.IconProvider".toClass().method {
name = "getIcon"
paramCount(2)
param { IntType in it && ActivityInfoClass in it }
param { IntType in it && (ActivityInfoClass in it || ComponentInfoClass in it) }
}.give()!!
}
val normalizeAndWrapToAdaptiveIcon = HookManager {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ abstract class BaseHookHandler {
lateinit var baseHooker: YukiBaseHooker

val appContext get() = baseHooker.appContext
val appClassLoader get() = baseHooker.appClassLoader
val appUserId get() = baseHooker.appUserId
val appResources get() = baseHooker.appResources
val prefs get() = baseHooker.prefs

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.gswxxn.restoresplashscreen.hook.systemui

import android.content.pm.ActivityInfo
import android.content.pm.ApplicationInfo
import com.gswxxn.restoresplashscreen.data.DataConst
import com.gswxxn.restoresplashscreen.data.StartingWindowInfo
import com.gswxxn.restoresplashscreen.hook.NewSystemUIHooker
Expand All @@ -18,6 +19,7 @@ import kotlinx.coroutines.launch
object GenerateHookHandler: BaseHookHandler() {
var currentPackageName = ""
var currentActivity = ""
var currentApplicationInfo = null as ApplicationInfo?
var exceptCurrentApp = false
var isHooking = false

Expand All @@ -27,6 +29,7 @@ object GenerateHookHandler: BaseHookHandler() {
private fun resetCache() {
currentPackageName = ""
currentActivity = ""
currentApplicationInfo = null
isHooking = false
exceptCurrentApp = false

Expand Down Expand Up @@ -54,6 +57,7 @@ object GenerateHookHandler: BaseHookHandler() {
isHooking = true
currentPackageName = activityInfo.packageName
currentActivity = activityInfo.targetActivity ?: ""
currentApplicationInfo = activityInfo.applicationInfo
exceptCurrentApp = isExcept()

printLog(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ import com.gswxxn.restoresplashscreen.data.DataConst
import com.gswxxn.restoresplashscreen.hook.NewSystemUIHooker
import com.gswxxn.restoresplashscreen.hook.base.BaseHookHandler
import com.gswxxn.restoresplashscreen.hook.systemui.GenerateHookHandler.currentActivity
import com.gswxxn.restoresplashscreen.hook.systemui.GenerateHookHandler.currentApplicationInfo
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.MIUIIconsHelper
import com.gswxxn.restoresplashscreen.utils.YukiHelper.atLeastMIUI14
import com.gswxxn.restoresplashscreen.utils.YukiHelper.getDevPrefs
import com.gswxxn.restoresplashscreen.utils.YukiHelper.isColorOS
import com.gswxxn.restoresplashscreen.utils.YukiHelper.isMIUI
import com.gswxxn.restoresplashscreen.utils.YukiHelper.printLog
import com.gswxxn.restoresplashscreen.wrapper.TransparentAdaptiveIconDrawable
import com.highcapable.yukihookapi.hook.factory.current
Expand All @@ -53,7 +55,7 @@ object IconHookHandler : BaseHookHandler() {
private var currentUseBigMIUILagerIcon: Boolean? = null
private var currentIconDrawable: Drawable? = null
private val iconPackManager by lazy { IconPackManager(appContext!!, prefs.get(DataConst.ICON_PACK_PACKAGE_NAME)) }
private val miuiIcons by lazy { MIUIIconsHelper(appContext!!) }
private val miuiIcons by lazy { MIUIIconsHelper(appContext!!, appClassLoader!!) }

/**
* 重置当前应用的属性
Expand Down Expand Up @@ -173,25 +175,30 @@ object IconHookHandler : BaseHookHandler() {

// 不使用自带的图标缩放, 防止在 MIUI 上出现图标白边及图标错位
NewSystemUIHooker.Members.normalizeAndWrapToAdaptiveIcon.addBeforeHook {
val scale = instance.current()
.method { name = "getNormalizer"; superClass() }.call()!!.current()
.method { name = "getScale"; paramCount(4); superClass() }
.invoke<Float>(
args.first { it is Drawable },
args.first { it is RectF },
null,
null
)!!
args(args.indexOfFirst { it is FloatArray }).cast<FloatArray>()!![0] = scale

val oriDrawable = args.first { it is Drawable } as Drawable
val returnType = NewSystemUIHooker.Members.normalizeAndWrapToAdaptiveIcon.returnType

printLog("normalizeAndWrapToAdaptiveIcon(): avoid shrink icon by system ui")
result = if (returnType == AdaptiveIconDrawable::class.java)
TransparentAdaptiveIconDrawable(oriDrawable)
else
oriDrawable
if (Thread.currentThread().stackTrace.any { it.methodName == "makeSplashScreenContentView" }) {
printLog("normalizeAndWrapToAdaptiveIcon(): avoid shrink icon by system ui")
val boolShrinkNonAdaptiveIconsIndex = args.indexOfFirst { it is Boolean }
if (boolShrinkNonAdaptiveIconsIndex != -1) {
args(boolShrinkNonAdaptiveIconsIndex).setFalse()
} else {
val scale = instance.current(ignored = true)
.method { name = "getNormalizer"; superClass() }.call()?.current()
?.method { name = "getScale"; paramCount(4); superClass() }
?.invoke<Float>(
args.first { it is Drawable },
args.first { it is RectF },
null,
null
) ?: 0.92f
args(args.indexOfFirst { it is FloatArray }).cast<FloatArray>()!![0] = scale
val oriDrawable = args.first { it is Drawable } as Drawable
val returnType = NewSystemUIHooker.Members.normalizeAndWrapToAdaptiveIcon.returnType
result = if (returnType == AdaptiveIconDrawable::class.java)
TransparentAdaptiveIconDrawable(oriDrawable)
else
oriDrawable
}
}
}
NewSystemUIHooker.Members.createIconBitmap_BaseIconFactory.addBeforeHook {
args(0).cast<Drawable>()?.let { drawable ->
Expand Down Expand Up @@ -338,14 +345,18 @@ object IconHookHandler : BaseHookHandler() {
currentPackageName == "com.android.settings" && currentActivity == "com.android.settings.BackgroundApplicationsManager" ->
appContext!!.packageManager.getApplicationIcon("com.android.settings")

// isMIUI && miuiIcons.isSupportMIUIModeIcon && currentPackageName != "com.android.fileexplorer" -> { // 在 MIUI 上优先获取完美图标
// miuiIcons.getFancyIconDrawable(currentPackageName) ?:
// appContext!!.packageManager.getApplicationIcon(currentPackageName)
// }
isMIUI && miuiIcons.isSupportMIUIModeIcon && currentPackageName != "com.android.fileexplorer" -> { // 在 MIUI 上优先获取完美图标
miuiIcons.getFancyIconDrawable(
currentPackageName,
appUserId,
currentApplicationInfo,
appContext!!.packageManager
) ?: appContext!!.packageManager.getApplicationIcon(currentPackageName)
}

else -> appContext!!.packageManager.getApplicationIcon(currentPackageName)
}
}
return null
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.gswxxn.restoresplashscreen.ui

import android.content.Context
import android.content.Intent
import android.content.res.Configuration
import android.text.Editable
Expand Down Expand Up @@ -130,11 +129,11 @@ class ConfigAppsActivity : BaseActivity<ActivityConfigAppsBinding>(), CoroutineS
binding.searchEditText.apply {
// 焦点事件
setOnFocusChangeListener { v, hasFocus ->
val imm = v.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
val imm = v.context.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
if (hasFocus) {
showView(false, binding.appListTitle, binding.configDescription, binding.configTitleFilter, binding.overallSettings)
// 弹出软键盘
imm.showSoftInput(binding.searchEditText, InputMethodManager.SHOW_FORCED)
imm.showSoftInput(binding.searchEditText, 0)
} else {
// 隐藏软键盘
imm.hideSoftInputFromWindow(this.windowToken, 0)
Expand Down Expand Up @@ -162,7 +161,7 @@ class ConfigAppsActivity : BaseActivity<ActivityConfigAppsBinding>(), CoroutineS
cView = holder.root
cView.tag = holder
} else {
holder = cView?.tag as AdapterConfigBinding
holder = cView.tag as AdapterConfigBinding
}
getItem(position).also { item ->
// 设置图标
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,30 @@ package com.gswxxn.restoresplashscreen.utils

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.drawable.AdaptiveIconDrawable
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.graphics.drawable.Drawable
import android.graphics.drawable.LayerDrawable
import android.provider.Settings
import com.gswxxn.restoresplashscreen.hook.NewSystemUIHooker.hook
import com.gswxxn.restoresplashscreen.utils.GraphicUtils.getCenterDrawable
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.factory.toClassOrNull
import com.highcapable.yukihookapi.hook.log.YLog
import com.highcapable.yukihookapi.hook.type.android.ApplicationInfoClass
import com.highcapable.yukihookapi.hook.type.android.ContextClass
import com.highcapable.yukihookapi.hook.type.android.UserHandleClass
import com.highcapable.yukihookapi.hook.type.java.BooleanType
import com.highcapable.yukihookapi.hook.type.java.LongType
import com.highcapable.yukihookapi.hook.type.java.StringClass
import com.highcapable.yukihookapi.hook.type.java.JavaClass

/**
* 用于从 MIUI 桌面检索大图标的辅助类
*/
@SuppressLint("DiscouragedApi")
class MIUIIconsHelper(private val context: Context) {
class MIUIIconsHelper(private val context: Context, private val classLoader: ClassLoader) {
private val miuiHomeContext = context.createPackageContext(
"com.miui.home",
Context.CONTEXT_INCLUDE_CODE or Context.CONTEXT_IGNORE_SECURITY
Expand All @@ -32,10 +34,53 @@ class MIUIIconsHelper(private val context: Context) {
if (YukiHelper.atLeastMIUI14)
"com.miui.maml.util.LargeIconsHelper".toClass(miuiHomeContext.classLoader)
else null
private val appIconsHelper = "com.miui.maml.util.AppIconsHelper".toClass(miuiHomeContext.classLoader)
private val dependencyClazz by lazy {
"com.miui.systemui.MiuiDependency".toClassOrNull(classLoader)
?: "com.android.systemui.Dependency".toClassOrNull(classLoader)
}
private val mDependencyGet by lazy {
dependencyClazz?.method {
name = "get"
paramCount(1)
param(JavaClass)
}?.ignored()?.give()
}
private val interfacesImplManagerClazz by lazy {
"com.miui.systemui.interfacesmanager.InterfacesImplManager".toClassOrNull(classLoader)
}
private val mImplManagerGet by lazy {
interfacesImplManagerClazz?.method {
name = "getImpl"
paramCount(1)
param(JavaClass)
}?.give()
}
private val appIconsManagerClazz by lazy {
"com.miui.systemui.graphics.AppIconsManager".toClass(classLoader)
}
private val loadAppIcon by lazy {
appIconsManagerClazz.getDeclaredMethod("loadAppIcon",
StringClass, Int::class.java, ApplicationInfoClass, PackageManager::class.java
)
}
private val appIconsManager by lazy {
mDependencyGet?.invoke(null, appIconsManagerClazz)
?: mImplManagerGet?.invoke(null, appIconsManagerClazz)
}
private val drawableUtilsClazz by lazy {
"com.miui.utils.DrawableUtils".toClass(classLoader)
}
private val getFancyChildOrSelf by lazy {
drawableUtilsClazz.method {
name = "getFancyChildOrSelf"
paramCount(2)
param(Drawable::class.java, BooleanType)
}.ignored().give()
}

/** 当前是否启用 MIUI 完美图标 */
val isSupportMIUIModeIcon by lazy {
Settings.System.getInt(context.contentResolver, "key_miui_mod_icon_enable", 0) == 1
Settings.System.getInt(context.contentResolver, "key_miui_mod_icon_enable", 0) == 1 || getFancyChildOrSelf != null
}

init {
Expand Down Expand Up @@ -151,33 +196,18 @@ class MIUIIconsHelper(private val context: Context) {
* 从指定的应用程序包中获取完美的图标 Drawable
*
* @param packageName 要获取图标的应用程序包的包名。
* @param userId 应用程序的用户 ID。
* @param applicationInfo 应用程序的 ApplicationInfo 对象。
* @param packageManager 用于获取应用程序信息的 PackageManager 实例。
* @return 如果成功获取到完美图标,则返回一个 BitmapDrawable;如果发生错误,则返回 null。
*/
fun getFancyIconDrawable(packageName: String) = try {
val drawable = appIconsHelper.method {
name = "getIconDrawable"
param(ContextClass, StringClass, StringClass, LongType)
}.get().call(
context,
fun getFancyIconDrawable(packageName: String, userId: Int, applicationInfo: ApplicationInfo?, packageManager: PackageManager?) = try {
loadAppIcon.invoke(appIconsManager,
packageName,
null,
getCacheTime(packageName),
userId,
applicationInfo,
packageManager
)

if (drawable is AdaptiveIconDrawable && drawable.javaClass.name == "com.miui.maml.MamlAdaptiveIconDrawable"){
val layer0QuietDrawable = drawable.background.current().method { name = "getQuietDrawable" }.invoke<Drawable>()!!
val layerFancyDrawables = drawable.current().method { name = "getLayerFancyDrawables" }.invoke<ArrayList<Drawable>>()!!

layerFancyDrawables.add(0, layer0QuietDrawable)

getCenterDrawable(
LayerDrawable(layerFancyDrawables.toTypedArray()),
0.65f,
context.resources
)
} else if (drawable?.javaClass?.name == "com.miui.maml.FancyDrawable") {
drawable
} else null
} catch (e: Throwable) {
YLog.error(msg = "Failed to get FancyIconDrawable with package: $packageName", e = e)
null
Expand Down
14 changes: 7 additions & 7 deletions gradle/sweet-dependency/sweet-dependency-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ repositories:

plugins:
com.android.application:
version: 8.7.3
version: 8.13.0
org.jetbrains.kotlin.android:
version: 2.1.0
version: 2.1.21
org.jetbrains.kotlin.plugin.serialization:
version: 2.1.0
version: 2.1.21
com.google.devtools.ksp:
version: 2.1.0-1.0.29
version: 2.1.21-2.0.2

libraries:
de.robv.android.xposed:
Expand All @@ -44,12 +44,12 @@ libraries:
version: 1.0.0
androidx.compose.material3:
material3:
version: 1.3.1
version: 1.4.0
org.jetbrains.kotlinx:
kotlinx-coroutines-android:
version: 1.9.0
version: 1.10.2
kotlinx-serialization-json:
version: 1.7.3
version: 1.9.0
androidx.annotation:
annotation:
version: 1.9.1
Loading