diff --git a/app/src/main/java/com/fankes/coloros/notify/hook/entity/SystemUIHooker.kt b/app/src/main/java/com/fankes/coloros/notify/hook/entity/SystemUIHooker.kt index 1c99762..f17f141 100644 --- a/app/src/main/java/com/fankes/coloros/notify/hook/entity/SystemUIHooker.kt +++ b/app/src/main/java/com/fankes/coloros/notify/hook/entity/SystemUIHooker.kt @@ -44,6 +44,7 @@ import android.widget.ImageView import androidx.core.graphics.drawable.toBitmap import androidx.core.graphics.drawable.toDrawable import androidx.core.view.children +import androidx.core.view.setPadding import com.fankes.coloros.notify.R import com.fankes.coloros.notify.bean.IconDataBean import com.fankes.coloros.notify.const.PackageName @@ -136,6 +137,12 @@ object SystemUIHooker : YukiBaseHooker() { /** ColorOS 存在的类 - 旧版本不存在 */ private val OplusNotificationSmallIconUtilClass by lazyClassOrNull("com.oplus.systemui.statusbar.notification.util.OplusNotificationSmallIconUtil") + /** ColorOS 存在的类 - 旧版本不存在 */ + private val OplusNotificationHeaderViewWrapperExImpClass by lazyClassOrNull("com.oplus.systemui.statusbar.notification.row.wrapper.OplusNotificationHeaderViewWrapperExImp") + + /** ColorOS 存在的类 - 旧版本不存在 */ + private val OplusNotificationGroupTemplateWrapperClass by lazyClassOrNull("com.oplus.systemui.notification.row.oplusgroup.OplusNotificationGroupTemplateWrapper") + /** 根据多个版本存在不同的包名相同的类 */ private val OplusNotificationIconAreaControllerClass by lazyClass( VariousClass( @@ -276,6 +283,17 @@ object SystemUIHooker : YukiBaseHooker() { parameterCount = 2 } != null + /** + * 判断通知是否为新版本 + * @return [Boolean] + */ + private val isNewNotification + get() = OplusNotificationHeaderViewWrapperExImpClass?.resolve()?.optional(silent = true) + ?.firstMethodOrNull { + name = "proxyOnContentUpdated" + parameterCount = 1 + } != null + /** * 打印日志 * @param tag 标识 @@ -314,6 +332,7 @@ object SystemUIHooker : YukiBaseHooker() { /** 刷新状态栏小图标 */ private fun refreshStatusBarIcons() = runInSafe { + if (isNewNotification) return@runInSafe val nfField = StatusBarIconViewClass.resolve().optional().firstFieldOrNull { name = "mNotification" } val sRadiusField = StatusBarIconViewClass.resolve().optional(silent = true).firstFieldOrNull { name = "sIconRadiusFraction" @@ -533,11 +552,11 @@ object SystemUIHooker : YukiBaseHooker() { .solidColor(newApplyColor) .build() setColorFilter(newStyle) - setPadding(2.dp(context), 2.dp(context), 2.dp(context), 2.dp(context)) + setPadding(2.dp(context)) } else { background = null setColorFilter(oldApplyColor) - setPadding(0, 0, 0, 0) + setPadding(0) } } else -> iconView.apply { @@ -599,7 +618,7 @@ object SystemUIHooker : YukiBaseHooker() { } } /** 清除图标间距 */ - setPadding(0, 0, 0, 0) + setPadding(0) /** 清除背景 */ background = null /** 清除着色 */ @@ -767,46 +786,6 @@ object SystemUIHooker : YukiBaseHooker() { } /** 注入通知控制器实例 */ StatusBarNotificationPresenterClass.resolve().optional().constructor {}.hookAll().after { notificationPresenter = instance } - /** 注入状态栏通知图标容器实例 */ - OplusNotificationIconAreaControllerClass.resolve().optional().apply { - var way = 0 - (firstMethodOrNull { - name = "updateIconsForLayout" - parameterCount = 10 - } ?: firstMethodOrNull { - /** ColorOS 14 */ - name = "updateIconsForLayout" - parameterCount = 5 - } ?: firstMethodOrNull { - name = "updateIconsForLayout" - parameterCount = 1 - }?.apply { way = 1 } - ?: firstMethodOrNull { - name = "updateIconsForLayout" - }?.apply { way = 2 })?.hook()?.after { - when (way) { - 2 -> notificationIconContainer = OplusNotificationIconAreaControllerClass.resolve().optional() - .firstMethodOrNull { name = "getNotificationIcons" } - ?.of(instance)?.invoke() - 1 -> { - notificationIconInstances.clear() - firstFieldOrNull { name = "mLastToShow" }?.of(instance)?.get>() - ?.takeIf { it.isNotEmpty() }?.forEach { notificationIconInstances.add(it) } - } - else -> notificationIconContainer = args(index = 1).cast() - } - } - } - /** 注入状态栏通知图标容器实例 */ - (LegacyNotificationIconAreaControllerImpl ?: NotificationIconAreaControllerClass) - .resolve().optional().apply { - firstMethodOrNull { - name = "updateIconsForLayout" - parameterCount = 8 - }?.hook()?.after { - notificationIconContainer = args(index = 1).cast() - } - } /** 替换通知面板背景 - 新版本 */ if (!isOldNotificationBackground) OplusNotificationBackgroundViewClass?.resolve()?.optional()?.apply { @@ -876,25 +855,32 @@ object SystemUIHooker : YukiBaseHooker() { }?.of(holder)?.invokeQuietly()?.performClick() } } - /** 替换通知图标和样式 */ - NotificationHeaderViewWrapperClass.resolve().optional().apply { - method { - name { it == "resolveHeaderViews" || it == "onContentUpdated" } - }.hookAll().after { - firstFieldOrNull { name = "mIcon" }?.of(instance)?.get()?.apply { - ExpandableNotificationRowClass.resolve().optional() - .firstMethodOrNull { name = "getEntry" } - ?.of(NotificationViewWrapperClass.resolve().optional().firstFieldOrNull { - name = "mRow" - }?.of(instance)?.get())?.invokeQuietly()?.let { - it.asResolver().optional().firstMethodOrNull { - name = "getSbn" - }?.invoke() - }.also { nf -> - nf?.notification?.also { - it.smallIcon.loadDrawable(context)?.also { iconDrawable -> - /** 执行替换 */ - fun doParse() { + + if (isNewNotification) { + /** 替换通知图标和样式 */ + OplusNotificationHeaderViewWrapperExImpClass?.resolve()?.optional()?.apply { + firstMethodOrNull { + name = "proxyOnContentUpdated" + parameterCount = 1 + }?.hook()?.after { + val mBase = instance.asResolver().optional().firstMethodOrNull { + name = "getBase" + emptyParameters() + }?.invokeQuietly() + val imageView = mBase?.asResolver()?.optional()?.firstFieldOrNull { + name = "mIcon" + type = ImageView::class + }?.getQuietly() + imageView?.apply { + ExpandableNotificationRowClass.resolve().optional() + .firstMethodOrNull { name = "getEntry" } + ?.of(args[0])?.invokeQuietly()?.let { + it.asResolver().optional().firstMethodOrNull { + name = "getSbn" + }?.invoke() + }.also { nf -> + nf?.notification?.also { + it.smallIcon.loadDrawable(context)?.also { iconDrawable -> compatNotifyIcon( context = context, nf = nf, @@ -905,12 +891,132 @@ object SystemUIHooker : YukiBaseHooker() { iconView = this ) } - doParse() - /** 延迟重新设置防止部分机型的系统重新设置图标出现图标着色后黑白块问题 */ - delayedRun(ms = 1500) { doParse() } } } + } + } + } + + OplusNotificationGroupTemplateWrapperClass?.resolve()?.optional()?.apply { + firstMethodOrNull { + name = "initIcon" + }?.hook()?.before { + val instanceContext = firstFieldOrNull { + name = "context" + }?.of(instance)?.get() as Context? + if (instanceContext == null) + return@before + resultNull() + NotificationHeaderViewWrapperClass.resolve().optional().firstFieldOrNull { name = "mIcon" }?.of(instance)?.get()?.apply { + ExpandableNotificationRowClass.resolve().optional() + .firstMethodOrNull { name = "getEntry" } + ?.of(NotificationViewWrapperClass.resolve().optional().firstFieldOrNull { + name = "mRow" + }?.of(instance)?.get())?.invokeQuietly()?.let { + it.asResolver().optional().firstMethodOrNull { + name = "getSbn" + }?.invoke() + }.also { nf -> + val context = StatusBarNotification::class.resolve().firstMethod { + name = "getPackageContext" + }.of(nf).invoke(instanceContext) + if (context == null) return@also + + nf?.notification?.also { + it.smallIcon.loadDrawable(context)?.also { iconDrawable -> + compatNotifyIcon( + context = context, + nf = nf, + isGrayscaleIcon = isGrayscaleIcon(context, iconDrawable), + packageName = context.packageName, + drawable = iconDrawable, + iconColor = it.color, + iconView = this + ) + } + } + } + } + } + } + } else { + /** 注入状态栏通知图标容器实例 */ + OplusNotificationIconAreaControllerClass.resolve().optional().apply { + var way = 0 + (firstMethodOrNull { + name = "updateIconsForLayout" + parameterCount = 10 + } ?: firstMethodOrNull { + /** ColorOS 14 */ + name = "updateIconsForLayout" + parameterCount = 5 + } ?: firstMethodOrNull { + name = "updateIconsForLayout" + parameterCount = 1 + }?.apply { way = 1 } + ?: firstMethodOrNull { + name = "updateIconsForLayout" + }?.apply { way = 2 })?.hook()?.after { + when (way) { + 2 -> notificationIconContainer = OplusNotificationIconAreaControllerClass.resolve().optional() + .firstMethodOrNull { name = "getNotificationIcons" } + ?.of(instance)?.invoke() + 1 -> { + notificationIconInstances.clear() + firstFieldOrNull { name = "mLastToShow" }?.of(instance)?.get>() + ?.takeIf { it.isNotEmpty() }?.forEach { notificationIconInstances.add(it) } } + else -> notificationIconContainer = args(index = 1).cast() + } + } + } + /** 注入状态栏通知图标容器实例 */ + (LegacyNotificationIconAreaControllerImpl ?: NotificationIconAreaControllerClass) + .resolve().optional().apply { + firstMethodOrNull { + name = "updateIconsForLayout" + parameterCount = 8 + }?.hook()?.after { + notificationIconContainer = args(index = 1).cast() + } + } + + /** 替换通知图标和样式 */ + NotificationHeaderViewWrapperClass.resolve().optional().apply { + method { + name { it == "resolveHeaderViews" || it == "onContentUpdated" } + }.hookAll().after { + firstFieldOrNull { name = "mIcon" }?.of(instance)?.get()?.apply { + ExpandableNotificationRowClass.resolve().optional() + .firstMethodOrNull { name = "getEntry" } + ?.of(NotificationViewWrapperClass.resolve().optional().firstFieldOrNull { + name = "mRow" + }?.of(instance)?.get())?.invokeQuietly()?.let { + it.asResolver().optional().firstMethodOrNull { + name = "getSbn" + }?.invoke() + }.also { nf -> + nf?.notification?.also { + it.smallIcon.loadDrawable(context)?.also { iconDrawable -> + /** 执行替换 */ + fun doParse() { + compatNotifyIcon( + context = context, + nf = nf, + isGrayscaleIcon = isGrayscaleIcon(context, iconDrawable), + packageName = context.packageName, + drawable = iconDrawable, + iconColor = it.color, + iconView = this + ) + } + doParse() + /** 延迟重新设置防止部分机型的系统重新设置图标出现图标着色后黑白块问题 */ + delayedRun(ms = 1500) { doParse() } + } + } + } + } } } } diff --git a/app/src/main/java/com/fankes/coloros/notify/utils/factory/FunctionFactory.kt b/app/src/main/java/com/fankes/coloros/notify/utils/factory/FunctionFactory.kt index 0a2cd8d..c8571ae 100644 --- a/app/src/main/java/com/fankes/coloros/notify/utils/factory/FunctionFactory.kt +++ b/app/src/main/java/com/fankes/coloros/notify/utils/factory/FunctionFactory.kt @@ -150,6 +150,8 @@ val isRealmeUI */ val androidVersionCodeName get() = when (Build.VERSION.SDK_INT) { + 36 -> "B" + 35 -> "V" 34 -> "U" 33 -> "T" 32 -> "S_V2"