From cb4bf479ba075d4a87f5700ea7f8c5842c2923f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=A4=AA=E7=99=BD?= <36808766+ghhccghk@users.noreply.github.com> Date: Thu, 5 Dec 2024 15:37:03 +0800 Subject: [PATCH] =?UTF-8?q?add=20hook=20HyperOS=20=E7=84=A6=E7=82=B9?= =?UTF-8?q?=E9=80=9A=E7=9F=A5=E5=BD=A9=E8=89=B2=E5=9B=BE=E6=A0=87=20(#215)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add hook HyperOS 焦点通知彩色图标 * clean code * fix: hyper os 2.0.25.0 bug --- .../miui/notify/hook/entity/SystemUIHooker.kt | 107 +++++++++++++++++- 1 file changed, 106 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/fankes/miui/notify/hook/entity/SystemUIHooker.kt b/app/src/main/java/com/fankes/miui/notify/hook/entity/SystemUIHooker.kt index 70af8ef..5808a2e 100644 --- a/app/src/main/java/com/fankes/miui/notify/hook/entity/SystemUIHooker.kt +++ b/app/src/main/java/com/fankes/miui/notify/hook/entity/SystemUIHooker.kt @@ -31,7 +31,10 @@ import android.content.Context import android.content.Intent import android.content.IntentFilter import android.graphics.Color +import android.graphics.Bitmap import android.graphics.Outline +import android.graphics.PorterDuff +import android.graphics.PorterDuffColorFilter import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable import android.graphics.drawable.Icon @@ -182,6 +185,9 @@ object SystemUIHooker : YukiBaseHooker() { ) ) + /** 澎湃系统焦点通知的用到的库 */ + private val FocusUtils by lazyClass("com.android.systemui.statusbar.notification.utils.FocusUtils") + /** 根据多个版本存在不同的包名相同的类 */ private val ExpandedNotificationClass by lazyClass( VariousClass( @@ -189,7 +195,6 @@ object SystemUIHooker : YukiBaseHooker() { "${PackageName.SYSTEMUI}.miui.statusbar.ExpandedNotification" ) ) - /** 缓存的通知图标优化数组 */ private var iconDatas = ArrayList() @@ -868,6 +873,55 @@ object SystemUIHooker : YukiBaseHooker() { } } + /** 图标颜色替换工具 + * @param oldBitmap 原始 Bitmap + * @param oldColor 要替换的颜色(忽略透明度部分,仅匹配 RGB) + * @param newColor 新颜色(将替换原颜色的 RGB 部分,保留原透明度) + * @param tolerance 容差范围(0-255),默认0(完全匹配) + * @return 替换颜色后的 Bitmap + */ + private fun replaceBitmapColor(oldBitmap: Bitmap, oldColor: Int, newColor: Int, tolerance: Int = 0): Bitmap { + // 创建一个可变的副本 + val mBitmap = oldBitmap.copy(Bitmap.Config.ARGB_8888, true) + val mBitmapWidth = mBitmap.width + val mBitmapHeight = mBitmap.height + + // 获取目标颜色的 RGB 值 + val oldR = Color.red(oldColor) + val oldG = Color.green(oldColor) + val oldB = Color.blue(oldColor) + + // 获取替换颜色的 RGB 值 + val newR = Color.red(newColor) + val newG = Color.green(newColor) + val newB = Color.blue(newColor) + + // 遍历每个像素点 + for (i in 0 until mBitmapHeight) { + for (j in 0 until mBitmapWidth) { + val color = mBitmap.getPixel(j, i) + + // 当前像素的 RGB 值 + val r = Color.red(color) + val g = Color.green(color) + val b = Color.blue(color) + + // 判断颜色是否接近目标颜色(模糊匹配) + if (Math.abs(r - oldR) <= tolerance && + Math.abs(g - oldG) <= tolerance && + Math.abs(b - oldB) <= tolerance + ) { + // 保留原始透明度 + val alpha = Color.alpha(color) + // 替换 RGB 并保留透明度 + val replacedColor = Color.argb(alpha, newR, newG, newB) + mBitmap.setPixel(j, i, replacedColor) + } + } + } + return mBitmap + } + override fun onHook() { /** 注册生命周期 */ registerLifecycle() @@ -894,6 +948,10 @@ object SystemUIHooker : YukiBaseHooker() { name = "getSmallIcon" param(ExpandedNotificationClass) } + method { + name = "getSmallIcon" + param { it[0] == ContextClass && it[1] extends SystemUIApplicationClass && it[2] == IntType && it[3] == BooleanType } + } method { name = "getSmallIcon" param { it[0] == ContextClass && it[1] extends StatusBarNotificationClass } @@ -910,6 +968,53 @@ object SystemUIHooker : YukiBaseHooker() { } } } + + /** 去他妈的焦点通知彩色图标 */ + FocusUtils.apply { + method{ + name = "getStatusBarTickerDarkIcon" + param(StatusBarNotificationClass) + }.remedys { + method { + name = "getStatusBarTickerDarkIcon" + param(ExpandedNotificationClass) + } + }.hook().after { + (globalContext ?: args().first().cast())?.also { context -> + val expandedNf = args(0).cast() + /** Hook 状态栏小图标 */ + compatStatusIcon( + context = context, + nf = expandedNf, + iconDrawable = result()?.loadDrawable(context) + ).also { pair -> + if (pair.second) result = Icon.createWithBitmap(pair.first?.let { replaceBitmapColor(it.toBitmap(),Color.WHITE,Color.BLACK,210) }) + } + } + } + method{ + name = "getStatusBarTickerIcon" + param(StatusBarNotificationClass) + }.remedys { + method { + name = "getStatusBarTickerIcon" + param(ExpandedNotificationClass) + } + }.hook().after { + (globalContext ?: args().first().cast())?.also { context -> + val expandedNf = args(0).cast() + /** Hook 状态栏小图标 */ + compatStatusIcon( + context = context, + nf = expandedNf, + iconDrawable = result()?.loadDrawable(context) + ).also { pair -> + if (pair.second) result = Icon.createWithBitmap(pair.first?.toBitmap()) + } + } + } + } + /** 注入状态栏通知图标实例 */ StatusBarIconViewClass.method { name = "updateIconColor"