Skip to content

Commit ef795ed

Browse files
authored
Add AOD hook (#253)
1 parent d40dfc1 commit ef795ed

1 file changed

Lines changed: 57 additions & 2 deletions

File tree

app/src/main/java/com/fankes/miui/notify/hook/entity/SystemUIHooker.kt

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ object SystemUIHooker : YukiBaseHooker() {
128128
/** MIUI 新版本存在的类 */
129129
private val NotificationStatClass by lazyClassOrNull("${PackageName.SYSTEMUI}.statusbar.notification.analytics.NotificationStat")
130130

131+
private val MiuiDozeServiceClass by lazyClassOrNull("com.android.keyguard.doze.MiuiDozeService")
132+
131133
/** 原生存在的类 */
132134
private val NotificationChildrenContainerClass by lazyClass("${PackageName.SYSTEMUI}.statusbar.notification.stack.NotificationChildrenContainer")
133135

@@ -475,7 +477,9 @@ object SystemUIHooker : YukiBaseHooker() {
475477
* @param iconDrawable 小图标 [Drawable]
476478
* @return [Pair] 回调小图标 - ([Drawable] 小图标,[Boolean] 是否替换)
477479
*/
478-
private fun compatStatusIcon(context: Context, nf: StatusBarNotification?, iconDrawable: Drawable?) = nf?.let { notifyInstance ->
480+
private fun compatStatusIcon(
481+
context: Context, nf: StatusBarNotification?, iconDrawable: Drawable?, tag: String = "Status Bar Icon"
482+
) = nf?.let { notifyInstance ->
479483
if (iconDrawable == null) return@let Pair(null, false)
480484
/** 判断是否不是灰度图标 */
481485
val isGrayscaleIcon = notifyInstance.isXmsf.not() && isGrayscaleIcon(context, iconDrawable)
@@ -490,7 +494,7 @@ object SystemUIHooker : YukiBaseHooker() {
490494
/** 是否为通知优化生效图标 */
491495
val isCustom = customTriple.first != null && customTriple.third.not()
492496
/** 打印日志 */
493-
loggerDebug(tag = "Status Bar Icon", context, notifyInstance, isCustom = isCustom, isGrayscaleIcon)
497+
loggerDebug(tag = tag, context, notifyInstance, isCustom = isCustom, isGrayscaleIcon)
494498
when {
495499
/** 处理自定义通知图标优化 */
496500
customTriple.first != null -> Pair(customTriple.first, true)
@@ -1289,5 +1293,56 @@ object SystemUIHooker : YukiBaseHooker() {
12891293
sbn.packageName == PackageName.SYSTEMUI && sbn.tag == "UNIMPORTANT"
12901294
} ?: false
12911295
}
1296+
@Suppress("LocalVariableName")
1297+
MiuiDozeServiceClass?.resolve()?.optional()?.apply {
1298+
firstMethodOrNull { name = "onPluginConnected" }?.hook()?.before {
1299+
val plugin = args(0).any()
1300+
?: return@before YLog.warn("AOD got null plugin")
1301+
val pluginClassLoader = plugin::class.java.classLoader
1302+
1303+
/**
1304+
* AOD 是插件,用传入的 ClassLoader 去解析
1305+
*/
1306+
val NotificationControllerClass = "com.miui.aod.notification.NotificationController".toClassOrNull(pluginClassLoader)
1307+
val NotificationDataClass = $$"com.miui.aod.notification.NotificationController$NotificationData".toClassOrNull(pluginClassLoader)
1308+
val NotificationDataIconDrawableField = NotificationDataClass?.resolve()?.firstFieldOrNull { name = "mIconDrawable" }
1309+
1310+
if (NotificationControllerClass == null || NotificationDataClass == null || NotificationDataIconDrawableField == null) {
1311+
return@before YLog.warn("AOD got null NotificationControllerClass or NotificationDataClass")
1312+
}
1313+
1314+
NotificationControllerClass.resolve().firstMethodOrNull {
1315+
name = "fillNotificationData"
1316+
parameters(
1317+
NotificationDataClass,
1318+
StatusBarNotification::class,
1319+
Boolean::class,
1320+
Boolean::class,
1321+
Boolean::class,
1322+
)
1323+
}?.hook()?.after {
1324+
val context = instance.asResolver().firstFieldOrNull { name = "mContext" }?.get<Context>()
1325+
?: return@after YLog.warn("fillNotificationData got null context")
1326+
1327+
val notificationData = args(0).any()
1328+
?: return@after YLog.warn("fillNotificationData got null notificationData")
1329+
val notifyInstance = args(1).cast<StatusBarNotification>()
1330+
?: return@after YLog.warn("fillNotificationData got null notifyInstance")
1331+
1332+
val iconDrawableField = notificationData.asResolver().firstFieldOrNull { name = "mIconDrawable" }
1333+
?: return@after YLog.warn("fillNotificationData got null iconDrawableField")
1334+
1335+
val smallIconDrawable = notifyInstance.notification?.smallIcon?.loadDrawable(context)
1336+
1337+
compatStatusIcon(context, notifyInstance, smallIconDrawable, "AOD Icon").also { pair ->
1338+
if (pair.second) {
1339+
iconDrawableField.set(pair.first)
1340+
} else {
1341+
iconDrawableField.set(smallIconDrawable)
1342+
}
1343+
}
1344+
}
1345+
}
1346+
}
12921347
}
12931348
}

0 commit comments

Comments
 (0)