refactor: migrate to YukiHookAPI new usage

This commit is contained in:
2023-10-07 21:02:34 +08:00
parent 97065494b0
commit f1fd3f2679
8 changed files with 232 additions and 271 deletions

View File

@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools">
package="com.fankes.miui.notify">
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

View File

@@ -27,7 +27,7 @@ package com.fankes.miui.notify.data
import android.content.Context import android.content.Context
import com.fankes.miui.notify.const.IconRuleSourceSyncType import com.fankes.miui.notify.const.IconRuleSourceSyncType
import com.highcapable.yukihookapi.hook.factory.prefs import com.highcapable.yukihookapi.hook.factory.prefs
import com.highcapable.yukihookapi.hook.log.loggerW import com.highcapable.yukihookapi.hook.log.YLog
import com.highcapable.yukihookapi.hook.param.PackageParam import com.highcapable.yukihookapi.hook.param.PackageParam
import com.highcapable.yukihookapi.hook.xposed.prefs.data.PrefsData import com.highcapable.yukihookapi.hook.xposed.prefs.data.PrefsData
@@ -127,7 +127,7 @@ object ConfigData {
private fun putString(data: PrefsData<String>, value: String) { private fun putString(data: PrefsData<String>, value: String) {
when (instance) { when (instance) {
is Context -> (instance as Context).prefs().edit { put(data, value) } is Context -> (instance as Context).prefs().edit { put(data, value) }
is PackageParam -> loggerW(msg = "Not support for this method") is PackageParam -> YLog.warn("Not support for this method")
else -> error("Unknown type for put prefs data") else -> error("Unknown type for put prefs data")
} }
} }
@@ -151,7 +151,7 @@ object ConfigData {
internal fun putInt(data: PrefsData<Int>, value: Int) { internal fun putInt(data: PrefsData<Int>, value: Int) {
when (instance) { when (instance) {
is Context -> (instance as Context).prefs().edit { put(data, value) } is Context -> (instance as Context).prefs().edit { put(data, value) }
is PackageParam -> loggerW(msg = "Not support for this method") is PackageParam -> YLog.warn("Not support for this method")
else -> error("Unknown type for put prefs data") else -> error("Unknown type for put prefs data")
} }
} }
@@ -175,7 +175,7 @@ object ConfigData {
internal fun putBoolean(data: PrefsData<Boolean>, value: Boolean) { internal fun putBoolean(data: PrefsData<Boolean>, value: Boolean) {
when (instance) { when (instance) {
is Context -> (instance as Context).prefs().edit { put(data, value) } is Context -> (instance as Context).prefs().edit { put(data, value) }
is PackageParam -> loggerW(msg = "Not support for this method") is PackageParam -> YLog.warn("Not support for this method")
else -> error("Unknown type for put prefs data") else -> error("Unknown type for put prefs data")
} }
} }

View File

@@ -32,10 +32,10 @@ import com.fankes.miui.notify.utils.factory.miuiVersion
import com.highcapable.yukihookapi.annotation.xposed.InjectYukiHookWithXposed import com.highcapable.yukihookapi.annotation.xposed.InjectYukiHookWithXposed
import com.highcapable.yukihookapi.hook.factory.configs import com.highcapable.yukihookapi.hook.factory.configs
import com.highcapable.yukihookapi.hook.factory.encase import com.highcapable.yukihookapi.hook.factory.encase
import com.highcapable.yukihookapi.hook.log.loggerW import com.highcapable.yukihookapi.hook.log.YLog
import com.highcapable.yukihookapi.hook.xposed.proxy.IYukiHookXposedInit import com.highcapable.yukihookapi.hook.xposed.proxy.IYukiHookXposedInit
@InjectYukiHookWithXposed(isUsingResourcesHook = false) @InjectYukiHookWithXposed
object HookEntry : IYukiHookXposedInit { object HookEntry : IYukiHookXposedInit {
override fun onInit() = configs { override fun onInit() = configs {
@@ -51,10 +51,10 @@ object HookEntry : IYukiHookXposedInit {
loadApp(PackageName.SYSTEMUI) { loadApp(PackageName.SYSTEMUI) {
ConfigData.init(instance = this) ConfigData.init(instance = this)
when { when {
isNotMIUI -> loggerW(msg = "Aborted Hook -> This System is not MIUI") isNotMIUI -> YLog.warn("Aborted Hook -> This System is not MIUI")
isLowerAndroidP -> loggerW(msg = "Aborted Hook -> This System is lower than Android P") isLowerAndroidP -> YLog.warn("Aborted Hook -> This System is lower than Android P")
isNotSupportMiuiVersion -> loggerW(msg = "Aborted Hook -> This MIUI Version ${miuiVersion.ifBlank { "unknown" }} not supported") isNotSupportMiuiVersion -> YLog.warn("Aborted Hook -> This MIUI Version ${miuiVersion.ifBlank { "unknown" }} not supported")
ConfigData.isEnableModule.not() -> loggerW(msg = "Aborted Hook -> Hook Closed") ConfigData.isEnableModule.not() -> YLog.warn("Aborted Hook -> Hook Closed")
else -> loadHooker(SystemUIHooker) else -> loadHooker(SystemUIHooker)
} }
} }

View File

@@ -75,15 +75,14 @@ import com.fankes.miui.notify.utils.tool.IconAdaptationTool
import com.fankes.miui.notify.utils.tool.SystemUITool import com.fankes.miui.notify.utils.tool.SystemUITool
import com.highcapable.yukihookapi.hook.bean.VariousClass import com.highcapable.yukihookapi.hook.bean.VariousClass
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
import com.highcapable.yukihookapi.hook.factory.MembersType import com.highcapable.yukihookapi.hook.factory.constructor
import com.highcapable.yukihookapi.hook.factory.current import com.highcapable.yukihookapi.hook.factory.current
import com.highcapable.yukihookapi.hook.factory.extends import com.highcapable.yukihookapi.hook.factory.extends
import com.highcapable.yukihookapi.hook.factory.field import com.highcapable.yukihookapi.hook.factory.field
import com.highcapable.yukihookapi.hook.factory.hasField import com.highcapable.yukihookapi.hook.factory.hasField
import com.highcapable.yukihookapi.hook.factory.injectModuleAppResources import com.highcapable.yukihookapi.hook.factory.injectModuleAppResources
import com.highcapable.yukihookapi.hook.factory.method import com.highcapable.yukihookapi.hook.factory.method
import com.highcapable.yukihookapi.hook.log.loggerD import com.highcapable.yukihookapi.hook.log.YLog
import com.highcapable.yukihookapi.hook.log.loggerW
import com.highcapable.yukihookapi.hook.type.android.ContextClass import com.highcapable.yukihookapi.hook.type.android.ContextClass
import com.highcapable.yukihookapi.hook.type.android.DrawableClass import com.highcapable.yukihookapi.hook.type.android.DrawableClass
import com.highcapable.yukihookapi.hook.type.android.ImageViewClass import com.highcapable.yukihookapi.hook.type.android.ImageViewClass
@@ -98,72 +97,85 @@ import top.defaults.drawabletoolbox.DrawableBuilder
object SystemUIHooker : YukiBaseHooker() { object SystemUIHooker : YukiBaseHooker() {
/** MIUI 新版本存在的类 */ /** MIUI 新版本存在的类 */
private const val SystemUIApplicationClass = "${PackageName.SYSTEMUI}.SystemUIApplication" private val SystemUIApplicationClass by lazyClassOrNull("${PackageName.SYSTEMUI}.SystemUIApplication")
/** MIUI 新版本存在的类 */ /** MIUI 新版本存在的类 */
private const val MiuiNotificationViewWrapperClass = "${PackageName.SYSTEMUI}.statusbar.notification.row.wrapper.MiuiNotificationViewWrapper" private val MiuiNotificationViewWrapperClass
by lazyClassOrNull("${PackageName.SYSTEMUI}.statusbar.notification.row.wrapper.MiuiNotificationViewWrapper")
/** MIUI 新版本存在的类 */ /** MIUI 新版本存在的类 */
private const val MiuiNotificationChildrenContainerClass = private val MiuiNotificationChildrenContainerClass
"${PackageName.SYSTEMUI}.statusbar.notification.stack.MiuiNotificationChildrenContainer" by lazyClassOrNull("${PackageName.SYSTEMUI}.statusbar.notification.stack.MiuiNotificationChildrenContainer")
/** MIUI 新版本存在的类 */ /** MIUI 新版本存在的类 */
private const val NotificationHeaderViewWrapperInjectorClass = private val NotificationHeaderViewWrapperInjectorClass
"${PackageName.SYSTEMUI}.statusbar.notification.row.wrapper.NotificationHeaderViewWrapperInjector" by lazyClassOrNull("${PackageName.SYSTEMUI}.statusbar.notification.row.wrapper.NotificationHeaderViewWrapperInjector")
/** MIUI 新版本存在的类 */ /** MIUI 新版本存在的类 */
private const val NotificationStatClass = "${PackageName.SYSTEMUI}.statusbar.notification.analytics.NotificationStat" private val NotificationStatClass by lazyClassOrNull("${PackageName.SYSTEMUI}.statusbar.notification.analytics.NotificationStat")
/** 原生存在的类 */ /** 原生存在的类 */
private const val NotificationChildrenContainerClass = "${PackageName.SYSTEMUI}.statusbar.notification.stack.NotificationChildrenContainer" private val NotificationChildrenContainerClass by lazyClass("${PackageName.SYSTEMUI}.statusbar.notification.stack.NotificationChildrenContainer")
/** 原生存在的类 */ /** 原生存在的类 */
private const val NotificationIconAreaControllerClass = "${PackageName.SYSTEMUI}.statusbar.phone.NotificationIconAreaController" private val NotificationIconAreaControllerClass by lazyClass("${PackageName.SYSTEMUI}.statusbar.phone.NotificationIconAreaController")
/** 原生存在的类 */ /** 原生存在的类 */
private const val ContrastColorUtilClass = "com.android.internal.util.ContrastColorUtil" private val ContrastColorUtilClass by lazyClass("com.android.internal.util.ContrastColorUtil")
/** 原生存在的类 */ /** 原生存在的类 */
private const val StatusBarIconViewClass = "${PackageName.SYSTEMUI}.statusbar.StatusBarIconView" private val StatusBarIconViewClass by lazyClass("${PackageName.SYSTEMUI}.statusbar.StatusBarIconView")
/** 原生存在的类 */ /** 原生存在的类 */
private const val NotificationIconContainerClass = "${PackageName.SYSTEMUI}.statusbar.phone.NotificationIconContainer" private val NotificationIconContainerClass by lazyClass("${PackageName.SYSTEMUI}.statusbar.phone.NotificationIconContainer")
/** 根据多个版本存在不同的包名相同的类 */ /** 根据多个版本存在不同的包名相同的类 */
private val StatusBarNotificationPresenterClass = VariousClass( private val StatusBarNotificationPresenterClass by lazyClass(
VariousClass(
"${PackageName.SYSTEMUI}.statusbar.phone.StatusBarNotificationPresenter", "${PackageName.SYSTEMUI}.statusbar.phone.StatusBarNotificationPresenter",
"${PackageName.SYSTEMUI}.statusbar.phone.StatusBar" "${PackageName.SYSTEMUI}.statusbar.phone.StatusBar"
) )
)
/** 根据多个版本存在不同的包名相同的类 */ /** 根据多个版本存在不同的包名相同的类 */
private val ExpandableNotificationRowClass = VariousClass( private val ExpandableNotificationRowClass by lazyClass(
VariousClass(
"${PackageName.SYSTEMUI}.statusbar.notification.row.ExpandableNotificationRow", "${PackageName.SYSTEMUI}.statusbar.notification.row.ExpandableNotificationRow",
"${PackageName.SYSTEMUI}.statusbar.ExpandableNotificationRow" "${PackageName.SYSTEMUI}.statusbar.ExpandableNotificationRow"
) )
)
/** 根据多个版本存在不同的包名相同的类 */ /** 根据多个版本存在不同的包名相同的类 */
private val NotificationViewWrapperClass = VariousClass( private val NotificationViewWrapperClass by lazyClass(
VariousClass(
"${PackageName.SYSTEMUI}.statusbar.notification.row.wrapper.NotificationViewWrapper", "${PackageName.SYSTEMUI}.statusbar.notification.row.wrapper.NotificationViewWrapper",
"${PackageName.SYSTEMUI}.statusbar.notification.NotificationViewWrapper" "${PackageName.SYSTEMUI}.statusbar.notification.NotificationViewWrapper"
) )
)
/** 根据多个版本存在不同的包名相同的类 */ /** 根据多个版本存在不同的包名相同的类 */
private val NotificationHeaderViewWrapperClass = VariousClass( private val NotificationHeaderViewWrapperClass by lazyClass(
VariousClass(
"${PackageName.SYSTEMUI}.statusbar.notification.row.wrapper.NotificationHeaderViewWrapper", "${PackageName.SYSTEMUI}.statusbar.notification.row.wrapper.NotificationHeaderViewWrapper",
"${PackageName.SYSTEMUI}.statusbar.notification.NotificationHeaderViewWrapper" "${PackageName.SYSTEMUI}.statusbar.notification.NotificationHeaderViewWrapper"
) )
/** 根据多个版本存在不同的包名相同的类 */
private val NotificationUtilClass = VariousClass(
"${PackageName.SYSTEMUI}.statusbar.notification.NotificationUtil",
"${PackageName.SYSTEMUI}.miui.statusbar.notification.NotificationUtil"
) )
/** 根据多个版本存在不同的包名相同的类 */ /** 根据多个版本存在不同的包名相同的类 */
private val ExpandedNotificationClass = VariousClass( private val NotificationUtilClass by lazyClass(
VariousClass(
"${PackageName.SYSTEMUI}.statusbar.notification.NotificationUtil",
"${PackageName.SYSTEMUI}.miui.statusbar.notification.NotificationUtil"
)
)
/** 根据多个版本存在不同的包名相同的类 */
private val ExpandedNotificationClass by lazyClass(
VariousClass(
"${PackageName.SYSTEMUI}.statusbar.notification.ExpandedNotification", "${PackageName.SYSTEMUI}.statusbar.notification.ExpandedNotification",
"${PackageName.SYSTEMUI}.miui.statusbar.ExpandedNotification" "${PackageName.SYSTEMUI}.miui.statusbar.ExpandedNotification"
) )
)
/** 缓存的通知图标优化数组 */ /** 缓存的通知图标优化数组 */
private var iconDatas = ArrayList<IconDataBean>() private var iconDatas = ArrayList<IconDataBean>()
@@ -194,20 +206,19 @@ object SystemUIHooker : YukiBaseHooker() {
* @return [Context] or null * @return [Context] or null
*/ */
private val globalContext private val globalContext
get() = SystemUIApplicationClass.toClassOrNull()?.method { name = "getContext" }?.ignored()?.get()?.invoke<Context?>() ?: appContext get() = SystemUIApplicationClass?.method { name = "getContext" }?.ignored()?.get()?.invoke<Context?>() ?: appContext
/** /**
* 是否为 MIUI 样式通知栏 - 旧版 - 新版一律返回 false * 是否为 MIUI 样式通知栏 - 旧版 - 新版一律返回 false
* @return [Boolean] * @return [Boolean]
*/ */
private val isShowMiuiStyle private val isShowMiuiStyle get() = NotificationUtilClass.method { name = "showMiuiStyle" }.ignored().get().boolean()
get() = NotificationUtilClass.toClassOrNull()?.method { name = "showMiuiStyle" }?.ignored()?.get()?.boolean() ?: false
/** /**
* 是否没有单独的 MIUI 通知栏样式 * 是否没有单独的 MIUI 通知栏样式
* @return [Boolean] * @return [Boolean]
*/ */
private val isNotHasAbsoluteMiuiStyle get() = MiuiNotificationViewWrapperClass.hasClass().not() private val isNotHasAbsoluteMiuiStyle get() = MiuiNotificationViewWrapperClass == null
/** /**
* 获取状态栏通知图标透明度 * 获取状态栏通知图标透明度
@@ -259,7 +270,7 @@ object SystemUIHooker : YukiBaseHooker() {
* @param isGrayscale 是否为灰度图标 * @param isGrayscale 是否为灰度图标
*/ */
private fun loggerDebug(tag: String, context: Context, nf: StatusBarNotification?, isCustom: Boolean, isGrayscale: Boolean) { private fun loggerDebug(tag: String, context: Context, nf: StatusBarNotification?, isCustom: Boolean, isGrayscale: Boolean) {
if (ConfigData.isEnableModuleLog) loggerD( if (ConfigData.isEnableModuleLog) YLog.debug(
msg = "(Processing $tag) ↓\n" + msg = "(Processing $tag) ↓\n" +
"[Title]: ${nf?.notification?.extras?.getString(Notification.EXTRA_TITLE)}\n" + "[Title]: ${nf?.notification?.extras?.getString(Notification.EXTRA_TITLE)}\n" +
"[Content]: ${nf?.notification?.extras?.getString(Notification.EXTRA_TEXT)}\n" + "[Content]: ${nf?.notification?.extras?.getString(Notification.EXTRA_TEXT)}\n" +
@@ -283,7 +294,7 @@ object SystemUIHooker : YukiBaseHooker() {
*/ */
private fun isGrayscaleIcon(context: Context, drawable: Drawable) = private fun isGrayscaleIcon(context: Context, drawable: Drawable) =
if (ConfigData.isEnableColorIconCompat.not()) safeOfFalse { if (ConfigData.isEnableColorIconCompat.not()) safeOfFalse {
ContrastColorUtilClass.toClass().let { ContrastColorUtilClass.let {
it.method { it.method {
name = "isGrayscaleIcon" name = "isGrayscaleIcon"
param(DrawableClass) param(DrawableClass)
@@ -331,7 +342,7 @@ object SystemUIHooker : YukiBaseHooker() {
/** 刷新状态栏小图标 */ /** 刷新状态栏小图标 */
private fun refreshStatusBarIcons() = runInSafe { private fun refreshStatusBarIcons() = runInSafe {
StatusBarIconViewClass.toClassOrNull()?.field { name = "mNotification" }?.also { result -> StatusBarIconViewClass.field { name = "mNotification" }.also { result ->
notificationIconContainer?.children?.forEach { notificationIconContainer?.children?.forEach {
/** 得到通知实例 */ /** 得到通知实例 */
val nf = result.get(it).cast<StatusBarNotification>() ?: return val nf = result.get(it).cast<StatusBarNotification>() ?: return
@@ -479,7 +490,7 @@ object SystemUIHooker : YukiBaseHooker() {
/** 获取通知小图标 */ /** 获取通知小图标 */
val iconDrawable = notifyInstance.notification.smallIcon.loadDrawable(context) val iconDrawable = notifyInstance.notification.smallIcon.loadDrawable(context)
?: return@let loggerW(msg = "compatNotifyIcon got null smallIcon") ?: return@let YLog.warn("compatNotifyIcon got null smallIcon")
/** 判断图标风格 */ /** 判断图标风格 */
val isGrayscaleIcon = notifyInstance.isXmsf.not() && isGrayscaleIcon(context, iconDrawable) val isGrayscaleIcon = notifyInstance.isXmsf.not() && isGrayscaleIcon(context, iconDrawable)
@@ -556,11 +567,11 @@ object SystemUIHooker : YukiBaseHooker() {
private fun ImageView.isGrayscaleIcon(): Boolean { private fun ImageView.isGrayscaleIcon(): Boolean {
/** 获取 [StatusBarNotification] 实例 */ /** 获取 [StatusBarNotification] 实例 */
val notifyInstance = current().field { name = "mNotification" }.cast<StatusBarNotification>() val notifyInstance = current().field { name = "mNotification" }.cast<StatusBarNotification>()
?: return loggerW(msg = "isGrayscaleIcon got null mNotification").let { false } ?: return YLog.warn("isGrayscaleIcon got null mNotification").let { false }
/** 获取通知小图标 */ /** 获取通知小图标 */
val iconDrawable = notifyInstance.notification?.smallIcon?.loadDrawable(context) val iconDrawable = notifyInstance.notification?.smallIcon?.loadDrawable(context)
?: return loggerW(msg = "isGrayscaleIcon got null smallIcon").let { false } ?: return YLog.warn("isGrayscaleIcon got null smallIcon").let { false }
/** 判断是否不是灰度图标 */ /** 判断是否不是灰度图标 */
val isGrayscaleIcon = notifyInstance.isXmsf.not() && isGrayscaleIcon(context, iconDrawable) val isGrayscaleIcon = notifyInstance.isXmsf.not() && isGrayscaleIcon(context, iconDrawable)
@@ -620,8 +631,8 @@ object SystemUIHooker : YukiBaseHooker() {
if (isNotHasAbsoluteMiuiStyle && isShowMiuiStyle) return if (isNotHasAbsoluteMiuiStyle && isShowMiuiStyle) return
/** 获取小图标 */ /** 获取小图标 */
val iconImageView = NotificationHeaderViewWrapperClass.toClassOrNull() val iconImageView = NotificationHeaderViewWrapperClass
?.field { name = "mIcon" }?.get(wrapper)?.cast<ImageView>() ?: return .field { name = "mIcon" }.get(wrapper).cast<ImageView>() ?: return
/** 获取 [ExpandableNotificationRowClass] */ /** 获取 [ExpandableNotificationRowClass] */
val rowPair = wrapper.getRowPair() val rowPair = wrapper.getRowPair()
@@ -654,13 +665,13 @@ object SystemUIHooker : YukiBaseHooker() {
* 从父类中得到 mRow 变量 - [ExpandableNotificationRowClass] * 从父类中得到 mRow 变量 - [ExpandableNotificationRowClass]
* 获取其中的得到通知方法 * 获取其中的得到通知方法
*/ */
val row = NotificationViewWrapperClass.toClassOrNull()?.field { val row = NotificationViewWrapperClass.field {
name = "mRow" name = "mRow"
}?.get(this)?.any()?.also { }.get(this).any()?.also {
isExpanded = ExpandableNotificationRowClass.toClassOrNull()?.method { isExpanded = ExpandableNotificationRowClass.method {
name = "isExpanded" name = "isExpanded"
returnType = BooleanType returnType = BooleanType
}?.get(it)?.boolean() ?: false }.get(it).boolean()
} }
return Pair(isExpanded, row) return Pair(isExpanded, row)
} }
@@ -670,15 +681,15 @@ object SystemUIHooker : YukiBaseHooker() {
* @return [StatusBarNotification] or null * @return [StatusBarNotification] or null
*/ */
private fun Any?.getSbn() = private fun Any?.getSbn() =
ExpandableNotificationRowClass.toClassOrNull() ExpandableNotificationRowClass
?.method { name = "getEntry" } .method { name = "getEntry" }
?.get(this)?.call()?.let { .get(this).call()
it.javaClass.method { ?.current(ignored = true)
name = "getSbn" ?.method { name = "getSbn" }
}.ignored().get(it).invoke<StatusBarNotification>() ?.invoke<StatusBarNotification>()
} ?: ExpandableNotificationRowClass.toClassOrNull() ?: ExpandableNotificationRowClass
?.method { name = "getStatusBarNotification" } .method { name = "getStatusBarNotification" }
?.get(this)?.invoke<StatusBarNotification>() .get(this).invoke<StatusBarNotification>()
/** /**
* 根据当前 [ImageView] 的父布局克隆一个新的 [ImageView] * 根据当前 [ImageView] 的父布局克隆一个新的 [ImageView]
@@ -775,18 +786,14 @@ object SystemUIHooker : YukiBaseHooker() {
/** 缓存图标数据 */ /** 缓存图标数据 */
cachingIconDatas() cachingIconDatas()
/** 注入 MIUI 自己增加的一个工具类 */ /** 注入 MIUI 自己增加的一个工具类 */
NotificationUtilClass.hook { NotificationUtilClass.apply {
/** 强制回写系统的状态栏图标样式为原生 */ /** 强制回写系统的状态栏图标样式为原生 */
injectMember {
method { method {
name { it == "shouldSubstituteSmallIcon" || it == "shouldSubstituteSmallIconForStatusBarNotification" } name { it == "shouldSubstituteSmallIcon" || it == "shouldSubstituteSmallIconForStatusBarNotification" }
param { it[0] extends StatusBarNotificationClass } param { it[0] extends StatusBarNotificationClass }
}.all() }.hookAll().replaceToFalse()
replaceToFalse()
}
/** 强制回写系统的状态栏图标样式为原生 */
injectMember {
var isUseLegacy = false var isUseLegacy = false
/** 强制回写系统的状态栏图标样式为原生 */
method { method {
name = "getSmallIcon" name = "getSmallIcon"
param { it[0] extends StatusBarNotificationClass && it[1] == IntType } param { it[0] extends StatusBarNotificationClass && it[1] == IntType }
@@ -799,8 +806,7 @@ object SystemUIHooker : YukiBaseHooker() {
name = "getSmallIcon" name = "getSmallIcon"
param(ContextClass, ExpandedNotificationClass) param(ContextClass, ExpandedNotificationClass)
}.onFind { isUseLegacy = true } }.onFind { isUseLegacy = true }
} }.hook().after {
afterHook {
(globalContext ?: args().first().cast())?.also { context -> (globalContext ?: args().first().cast())?.also { context ->
val expandedNf = args(if (isUseLegacy) 1 else 0).cast<StatusBarNotification?>() val expandedNf = args(if (isUseLegacy) 1 else 0).cast<StatusBarNotification?>()
/** Hook 状态栏小图标 */ /** Hook 状态栏小图标 */
@@ -812,16 +818,13 @@ object SystemUIHooker : YukiBaseHooker() {
} }
} }
} }
}
/** 注入状态栏通知图标容器管理实例 */ /** 注入状态栏通知图标容器管理实例 */
NotificationIconAreaControllerClass.hook { NotificationIconAreaControllerClass.apply {
/** Hook 深色图标模式改变 */ /** Hook 深色图标模式改变 */
injectMember {
method { method {
name = "onDarkChanged" name = "onDarkChanged"
paramCount { it > 0 } paramCount { it > 0 }
} }.hook().after {
afterHook {
field { name = "mNotificationIcons" }.get(instance).cast<ViewGroup>()?.also { field { name = "mNotificationIcons" }.get(instance).cast<ViewGroup>()?.also {
/** 重新设置通知图标容器实例 */ /** 重新设置通知图标容器实例 */
notificationIconContainer = it notificationIconContainer = it
@@ -838,11 +841,10 @@ object SystemUIHooker : YukiBaseHooker() {
} }
} }
} }
}
/** Hook 更新通知图标事件 */ /** Hook 更新通知图标事件 */
injectMember { method {
method { name { it == "updateNotificationIcons" || it == "onChanged" } }.all() name { it == "updateNotificationIcons" || it == "onChanged" }
afterHook { }.hookAll().after {
field { name = "mNotificationIcons" }.get(instance).cast<ViewGroup>()?.also { field { name = "mNotificationIcons" }.get(instance).cast<ViewGroup>()?.also {
/** 重新设置通知图标容器实例 */ /** 重新设置通知图标容器实例 */
notificationIconContainer = it notificationIconContainer = it
@@ -852,12 +854,8 @@ object SystemUIHooker : YukiBaseHooker() {
} }
} }
} }
}
/** 注入状态栏通知图标实例 */ /** 注入状态栏通知图标实例 */
StatusBarIconViewClass.hook { StatusBarIconViewClass.method {
/** 注册广播 */
injectMember {
method {
name = "setNotification" name = "setNotification"
param(StatusBarNotificationClass) param(StatusBarNotificationClass)
}.remedys { }.remedys {
@@ -865,33 +863,23 @@ object SystemUIHooker : YukiBaseHooker() {
name = "setNotification" name = "setNotification"
param(ExpandedNotificationClass) param(ExpandedNotificationClass)
} }
} }.hook().after {
afterHook {
/** 注册壁纸颜色监听 */ /** 注册壁纸颜色监听 */
if (args().first().any() != null) instance<ImageView>().also { registerWallpaperColorChanged(it) } if (args().first().any() != null) instance<ImageView>().also { registerWallpaperColorChanged(it) }
} }
}
}
/** 注入通知控制器实例 */ /** 注入通知控制器实例 */
StatusBarNotificationPresenterClass.hook { StatusBarNotificationPresenterClass.constructor().hookAll().after { notificationPresenter = instance }
injectMember {
allMembers(MembersType.CONSTRUCTOR)
afterHook { notificationPresenter = instance }
}
}
/** 注入状态栏通知图标容器实例 */ /** 注入状态栏通知图标容器实例 */
NotificationIconContainerClass.hook { NotificationIconContainerClass.apply {
injectMember { method {
method { name = "applyIconStates" } name = "applyIconStates"
afterHook { updateStatusBarIconAlpha(instance()) } }.hook().after { updateStatusBarIconAlpha(instance()) }
} method {
injectMember { name = "resetViewStates"
method { name = "resetViewStates" } }.hook().after { updateStatusBarIconAlpha(instance()) }
afterHook { updateStatusBarIconAlpha(instance()) } method {
} name = "calculateIconTranslations"
injectMember { }.hook().after {
method { name = "calculateIconTranslations" }
afterHook {
/** 缓存实例 */ /** 缓存实例 */
notificationIconContainer = instance<ViewGroup>() notificationIconContainer = instance<ViewGroup>()
/** 修复部分开发版状态栏图标只能显示一个的问题 */ /** 修复部分开发版状态栏图标只能显示一个的问题 */
@@ -900,52 +888,43 @@ object SystemUIHooker : YukiBaseHooker() {
instance<ViewGroup>().layoutParams.width = 9999 instance<ViewGroup>().layoutParams.width = 9999
} }
} }
} method {
injectMember { name = "updateState"
method { name = "updateState" } }.hook {
beforeHook { before {
val maxStaticIconsField = field { name = "MAX_STATIC_ICONS" }.get(instance) val maxStaticIconsField = NotificationIconContainerClass.field { name = "MAX_STATIC_ICONS" }.get(instance)
if (statusBarMaxStaticIcons == -1) statusBarMaxStaticIcons = maxStaticIconsField.int() if (statusBarMaxStaticIcons == -1) statusBarMaxStaticIcons = maxStaticIconsField.int()
/** 解除状态栏通知图标个数限制 */ /** 解除状态栏通知图标个数限制 */
if (isShowNotificationIcons && ConfigData.isEnableLiftedStatusIconCount) if (isShowNotificationIcons && ConfigData.isEnableLiftedStatusIconCount)
maxStaticIconsField.set(ConfigData.liftedStatusIconCount.let { if (it in 0..100) it else 5 }) maxStaticIconsField.set(ConfigData.liftedStatusIconCount.let { if (it in 0..100) it else 5 })
else maxStaticIconsField.set(if (isShowNotificationIcons) statusBarMaxStaticIcons else 0) else maxStaticIconsField.set(if (isShowNotificationIcons) statusBarMaxStaticIcons else 0)
} }
}.by { NotificationIconContainerClass.toClassOrNull()?.hasField { name = "MAX_STATIC_ICONS" } ?: false } }.by { NotificationIconContainerClass.hasField { name = "MAX_STATIC_ICONS" } }
/** 旧版方法 - 新版不存在 */ /** 旧版方法 - 新版不存在 */
injectMember {
method { method {
name = "setMaxStaticIcons" name = "setMaxStaticIcons"
param(IntType) param(IntType)
} }.ignored().hook().before { isShowNotificationIcons = args().first().int() > 0 }
beforeHook { isShowNotificationIcons = args().first().int() > 0 }
}.ignoredNoSuchMemberFailure()
/** 新版方法 - 旧版不存在 */ /** 新版方法 - 旧版不存在 */
injectMember {
method { method {
name = "miuiShowNotificationIcons" name = "miuiShowNotificationIcons"
param(BooleanType) param(BooleanType)
} }.ignored().hook().before { isShowNotificationIcons = args().first().boolean() }
beforeHook { isShowNotificationIcons = args().first().boolean() }
}.ignoredNoSuchMemberFailure()
} }
/** 注入原生通知包装纸实例 */ /** 注入原生通知包装纸实例 */
NotificationHeaderViewWrapperClass.hook { NotificationHeaderViewWrapperClass.apply {
injectMember { method {
method { name { it == "resolveHeaderViews" || it == "handleHeaderViews" || it == "resolveViews" } } name { it == "resolveHeaderViews" || it == "handleHeaderViews" || it == "resolveViews" }
afterHook { hookNotificationViewWrapper(instance) } }.hook().after { hookNotificationViewWrapper(instance) }
} method {
injectMember { name = "onContentUpdated"
method { name = "onContentUpdated" } }.hook().after { hookNotificationViewWrapper(instance) }
afterHook { hookNotificationViewWrapper(instance) }
}
} }
/** 修改 MIUI 风格通知栏的通知图标 */ /** 修改 MIUI 风格通知栏的通知图标 */
MiuiNotificationViewWrapperClass.hook { MiuiNotificationViewWrapperClass?.apply {
/** 替换通知小图标 */ method {
injectMember { name = "handleAppIcon"
method { name = "handleAppIcon" } }.hook().replaceUnit {
replaceUnit {
field { name = "mAppIcon" }.get(instance).cast<ImageView>()?.clone { field { name = "mAppIcon" }.get(instance).cast<ImageView>()?.clone {
compatNotifyIcon( compatNotifyIcon(
context = context, context = context,
@@ -956,27 +935,22 @@ object SystemUIHooker : YukiBaseHooker() {
} }
} }
} }
}.ignoredHookClassNotFoundFailure()
/** 修改 MIUI 风格通知栏的通知图标 - 折叠通知 */ /** 修改 MIUI 风格通知栏的通知图标 - 折叠通知 */
MiuiNotificationChildrenContainerClass.hook { MiuiNotificationChildrenContainerClass?.apply {
/** 替换通知小图标 */ /** 替换通知小图标 */
injectMember {
method { method {
name = "updateAppIcon" name = "updateAppIcon"
param(BooleanType) param(BooleanType)
} }.hook().after {
afterHook {
field { name = "mAppIcon" }.get(instance).cast<ImageView>()?.apply { field { name = "mAppIcon" }.get(instance).cast<ImageView>()?.apply {
compatNotifyIcon(context, NotificationChildrenContainerClass.toClassOrNull()?.field { compatNotifyIcon(context, NotificationChildrenContainerClass.field {
name = "mContainingNotification" name = "mContainingNotification"
}?.get(instance)?.any()?.getSbn(), iconView = this, isUseMaterial3Style = true) }.get(instance).any()?.getSbn(), iconView = this, isUseMaterial3Style = true)
} }
} }
} }
}.ignoredHookClassNotFoundFailure()
/** 干掉下拉通知图标自动设置回 APP 图标的方法 */ /** 干掉下拉通知图标自动设置回 APP 图标的方法 */
NotificationHeaderViewWrapperInjectorClass.hook { NotificationHeaderViewWrapperInjectorClass?.apply {
injectMember {
method { method {
name = "setAppIcon" name = "setAppIcon"
param(ContextClass, ImageViewClass, ExpandedNotificationClass) param(ContextClass, ImageViewClass, ExpandedNotificationClass)
@@ -985,17 +959,12 @@ object SystemUIHooker : YukiBaseHooker() {
name = "setAppIcon" name = "setAppIcon"
param(ImageViewClass, ExpandedNotificationClass) param(ImageViewClass, ExpandedNotificationClass)
} }
} }.ignored().hook().intercept()
intercept()
}.ignoredNoSuchMemberFailure()
injectMember {
method { method {
name = "resetIconBgAndPaddings" name = "resetIconBgAndPaddings"
param(ImageViewClass, ExpandedNotificationClass) param(ImageViewClass, ExpandedNotificationClass)
}.ignored().hook().intercept()
} }
intercept()
}.ignoredNoSuchMemberFailure()
}.ignoredHookClassNotFoundFailure()
/** /**
* 尝试修复从 MIUI 14 开始出现的一个崩溃问题 * 尝试修复从 MIUI 14 开始出现的一个崩溃问题
* 由于模块注入推送的通知没有对 [StatusBarNotification] 设置 TAG 会导致其空指针 * 由于模块注入推送的通知没有对 [StatusBarNotification] 设置 TAG 会导致其空指针
@@ -1007,13 +976,10 @@ object SystemUIHooker : YukiBaseHooker() {
* } * }
* ``` * ```
*/ */
NotificationStatClass.hook { NotificationStatClass?.method {
injectMember {
method {
name = "isUnimportantEntry" name = "isUnimportantEntry"
paramCount = 1 paramCount = 1
} }?.ignored()?.hook()?.replaceAny {
replaceAny {
args().first().current(ignored = true).method { args().first().current(ignored = true).method {
name = "getSbn" name = "getSbn"
superClass() superClass()
@@ -1021,7 +987,5 @@ object SystemUIHooker : YukiBaseHooker() {
sbn.packageName == PackageName.SYSTEMUI && sbn.tag == "UNIMPORTANT" sbn.packageName == PackageName.SYSTEMUI && sbn.tag == "UNIMPORTANT"
} ?: false } ?: false
} }
}.ignoredNoSuchMemberFailure()
}.ignoredHookClassNotFoundFailure()
} }
} }

View File

@@ -20,7 +20,7 @@
* *
* This file is created by fankes on 2022/1/7. * This file is created by fankes on 2022/1/7.
*/ */
@file:Suppress("unused", "OPT_IN_USAGE", "EXPERIMENTAL_API_USAGE") @file:Suppress("unused")
package com.fankes.miui.notify.utils.factory package com.fankes.miui.notify.utils.factory
@@ -38,7 +38,6 @@ import androidx.viewbinding.ViewBinding
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.progressindicator.CircularProgressIndicator import com.google.android.material.progressindicator.CircularProgressIndicator
import com.highcapable.yukihookapi.YukiHookAPI import com.highcapable.yukihookapi.YukiHookAPI
import com.highcapable.yukihookapi.annotation.CauseProblemsApi
import com.highcapable.yukihookapi.hook.factory.method import com.highcapable.yukihookapi.hook.factory.method
import com.highcapable.yukihookapi.hook.type.android.LayoutInflaterClass import com.highcapable.yukihookapi.hook.type.android.LayoutInflaterClass
@@ -181,7 +180,6 @@ class DialogBuilder<VB : ViewBinding>(val context: Context, private val bindingC
fun cancel() = dialogInstance?.cancel() fun cancel() = dialogInstance?.cancel()
/** 显示对话框 */ /** 显示对话框 */
@CauseProblemsApi
fun show() = runInSafe { fun show() = runInSafe {
/** 若当前自定义 View 的对话框没有调用 [binding] 将会对其手动调用一次以确保显示布局 */ /** 若当前自定义 View 的对话框没有调用 [binding] 将会对其手动调用一次以确保显示布局 */
if (bindingClass != null) binding if (bindingClass != null) binding

View File

@@ -24,7 +24,7 @@
package com.fankes.miui.notify.utils.factory package com.fankes.miui.notify.utils.factory
import com.highcapable.yukihookapi.hook.log.loggerE import com.highcapable.yukihookapi.hook.log.YLog
/** /**
* 忽略异常返回值 * 忽略异常返回值
@@ -79,5 +79,5 @@ inline fun <T> safeOf(default: T, result: () -> T) = try {
* @param block 正常回调 * @param block 正常回调
*/ */
inline fun <T> T.runInSafe(msg: String = "", block: () -> Unit) { inline fun <T> T.runInSafe(msg: String = "", block: () -> Unit) {
runCatching(block).onFailure { if (msg.isNotBlank()) loggerE(msg = msg, e = it) } runCatching(block).onFailure { if (msg.isNotBlank()) YLog.error(msg, it) }
} }

View File

@@ -50,7 +50,7 @@ import com.fankes.miui.notify.utils.factory.openBrowser
import com.fankes.miui.notify.utils.factory.safeOfNull import com.fankes.miui.notify.utils.factory.safeOfNull
import com.fankes.miui.notify.utils.factory.showDialog import com.fankes.miui.notify.utils.factory.showDialog
import com.fankes.miui.notify.utils.factory.snake import com.fankes.miui.notify.utils.factory.snake
import com.highcapable.yukihookapi.hook.log.loggerD import com.highcapable.yukihookapi.hook.log.YLog
import okhttp3.Call import okhttp3.Call
import okhttp3.Callback import okhttp3.Callback
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
@@ -477,11 +477,11 @@ object IconRuleManagerTool {
get() = object : X509TrustManager { get() = object : X509TrustManager {
override fun checkClientTrusted(chain: Array<X509Certificate?>?, authType: String?) { override fun checkClientTrusted(chain: Array<X509Certificate?>?, authType: String?) {
loggerD(msg = "TrustX509 --> $authType") YLog.debug("TrustX509 --> $authType")
} }
override fun checkServerTrusted(chain: Array<X509Certificate?>?, authType: String?) { override fun checkServerTrusted(chain: Array<X509Certificate?>?, authType: String?) {
loggerD(msg = "TrustX509 --> $authType") YLog.debug("TrustX509 --> $authType")
} }
override fun getAcceptedIssuers() = arrayOf<X509Certificate>() override fun getAcceptedIssuers() = arrayOf<X509Certificate>()

View File

@@ -40,8 +40,8 @@ import com.fankes.miui.notify.utils.factory.snake
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.highcapable.yukihookapi.YukiHookAPI import com.highcapable.yukihookapi.YukiHookAPI
import com.highcapable.yukihookapi.hook.factory.dataChannel import com.highcapable.yukihookapi.hook.factory.dataChannel
import com.highcapable.yukihookapi.hook.log.YukiHookLogger import com.highcapable.yukihookapi.hook.log.YLog
import com.highcapable.yukihookapi.hook.log.YukiLoggerData import com.highcapable.yukihookapi.hook.log.data.YLogData
import com.highcapable.yukihookapi.hook.param.PackageParam import com.highcapable.yukihookapi.hook.param.PackageParam
import com.highcapable.yukihookapi.hook.xposed.channel.data.ChannelData import com.highcapable.yukihookapi.hook.xposed.channel.data.ChannelData
import java.util.Locale import java.util.Locale
@@ -55,7 +55,7 @@ object SystemUITool {
private val CALL_MODULE_REFRESH_RESULT = ChannelData("call_module_refresh_result", false) private val CALL_MODULE_REFRESH_RESULT = ChannelData("call_module_refresh_result", false)
/** 当前全部调试日志 */ /** 当前全部调试日志 */
private var debugLogs = ArrayList<YukiLoggerData>() private var debugLogs = listOf<YLogData>()
/** 当前启动器实例 */ /** 当前启动器实例 */
private var launcher: ActivityResultLauncher<String>? = null private var launcher: ActivityResultLauncher<String>? = null
@@ -102,7 +102,7 @@ object SystemUITool {
"[Android Version]: ${Build.VERSION.RELEASE}\n" + "[Android Version]: ${Build.VERSION.RELEASE}\n" +
"[Android API Level]: ${Build.VERSION.SDK_INT}\n" + "[Android API Level]: ${Build.VERSION.SDK_INT}\n" +
"[MIUI Version]: $miuiFullVersion\n" + "[MIUI Version]: $miuiFullVersion\n" +
"[System Locale]: ${Locale.getDefault()}\n\n" + YukiHookLogger.contents(debugLogs).trim() "[System Locale]: ${Locale.getDefault()}\n\n" + YLog.contents(debugLogs).trim()
activity.contentResolver?.openOutputStream(e)?.apply { write(content.toByteArray()) }?.close() activity.contentResolver?.openOutputStream(e)?.apply { write(content.toByteArray()) }?.close()
activity.snake(msg = "导出完成") activity.snake(msg = "导出完成")
} ?: activity.snake(msg = "已取消操作") } ?: activity.snake(msg = "已取消操作")