refactor: migrate to YukiHookAPI new usage

This commit is contained in:
2023-10-07 21:07:40 +08:00
parent 1e0efe8f86
commit e0f50984b0
8 changed files with 250 additions and 289 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.coloros.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

@@ -28,7 +28,7 @@ import android.content.Context
import com.fankes.coloros.notify.const.IconRuleSourceSyncType import com.fankes.coloros.notify.const.IconRuleSourceSyncType
import com.fankes.coloros.notify.utils.factory.isUpperOfAndroidS import com.fankes.coloros.notify.utils.factory.isUpperOfAndroidS
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
@@ -134,7 +134,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")
} }
} }
@@ -158,7 +158,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")
} }
} }
@@ -182,7 +182,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

@@ -29,10 +29,10 @@ import com.fankes.coloros.notify.utils.factory.isNotColorOS
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 {
@@ -48,8 +48,8 @@ object HookEntry : IYukiHookXposedInit {
loadApp(PackageName.SYSTEMUI) { loadApp(PackageName.SYSTEMUI) {
ConfigData.init(instance = this) ConfigData.init(instance = this)
when { when {
isNotColorOS -> loggerW(msg = "Aborted Hook -> This System is not ColorOS") isNotColorOS -> YLog.warn("Aborted Hook -> This System is not ColorOS")
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

@@ -70,20 +70,19 @@ import com.fankes.coloros.notify.utils.tool.IconAdaptationTool
import com.fankes.coloros.notify.utils.tool.SystemUITool import com.fankes.coloros.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.field import com.highcapable.yukihookapi.hook.factory.field
import com.highcapable.yukihookapi.hook.factory.hasMethod import com.highcapable.yukihookapi.hook.factory.hasMethod
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.loggerE
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.IconClass import com.highcapable.yukihookapi.hook.type.android.IconClass
import com.highcapable.yukihookapi.hook.type.android.ImageViewClass import com.highcapable.yukihookapi.hook.type.android.ImageViewClass
import com.highcapable.yukihookapi.hook.type.android.StatusBarNotificationClass import com.highcapable.yukihookapi.hook.type.android.StatusBarNotificationClass
import com.highcapable.yukihookapi.hook.type.defined.VagueType
import com.highcapable.yukihookapi.hook.type.java.BooleanType import com.highcapable.yukihookapi.hook.type.java.BooleanType
import com.highcapable.yukihookapi.hook.type.java.FloatType import com.highcapable.yukihookapi.hook.type.java.FloatType
import com.highcapable.yukihookapi.hook.type.java.IntType import com.highcapable.yukihookapi.hook.type.java.IntType
@@ -96,110 +95,130 @@ import top.defaults.drawabletoolbox.DrawableBuilder
object SystemUIHooker : YukiBaseHooker() { object SystemUIHooker : YukiBaseHooker() {
/** 原生存在的类 */ /** 原生存在的类 */
private const val ContrastColorUtilClass = "com.android.internal.util.ContrastColorUtil" private val ContrastColorUtilClass by lazyClass("com.android.internal.util.ContrastColorUtil")
/** 原生存在的类 */ /** 原生存在的类 */
private const val NotificationUtilsClass = "${PackageName.SYSTEMUI}.statusbar.notification.NotificationUtils" private val NotificationUtilsClass by lazyClass("${PackageName.SYSTEMUI}.statusbar.notification.NotificationUtils")
/** 原生存在的类 */ /** 原生存在的类 */
private const val NotificationEntryClass = "${PackageName.SYSTEMUI}.statusbar.notification.collection.NotificationEntry" private val NotificationEntryClass by lazyClass("${PackageName.SYSTEMUI}.statusbar.notification.collection.NotificationEntry")
/** 原生存在的类 */ /** 原生存在的类 */
private const val StatusBarIconClass = "com.android.internal.statusbar.StatusBarIcon" private val StatusBarIconClass by lazyClass("com.android.internal.statusbar.StatusBarIcon")
/** 原生存在的类 */ /** 原生存在的类 */
private const val StatusBarIconViewClass = "${PackageName.SYSTEMUI}.statusbar.StatusBarIconView" private val StatusBarIconViewClass by lazyClass("${PackageName.SYSTEMUI}.statusbar.StatusBarIconView")
/** 原生存在的类 */ /** 原生存在的类 */
private const val IconBuilderClass = "${PackageName.SYSTEMUI}.statusbar.notification.icon.IconBuilder" private val IconBuilderClass by lazyClass("${PackageName.SYSTEMUI}.statusbar.notification.icon.IconBuilder")
/** 原生存在的类 */ /** 原生存在的类 */
private const val IconManagerClass = "${PackageName.SYSTEMUI}.statusbar.notification.icon.IconManager" private val IconManagerClass by lazyClass("${PackageName.SYSTEMUI}.statusbar.notification.icon.IconManager")
/** 原生存在的类 */ /** 原生存在的类 */
private const val NotificationBackgroundViewClass = "${PackageName.SYSTEMUI}.statusbar.notification.row.NotificationBackgroundView" private val NotificationBackgroundViewClass by lazyClassOrNull("${PackageName.SYSTEMUI}.statusbar.notification.row.NotificationBackgroundView")
/** 原生存在的类 */ /** 原生存在的类 */
private const val PlayerViewHolderClass = "${PackageName.SYSTEMUI}.media.PlayerViewHolder" private val PlayerViewHolderClass by lazyClassOrNull("${PackageName.SYSTEMUI}.media.PlayerViewHolder")
/** 原生存在的类 */ /** 原生存在的类 */
private const val MediaDataClass = "${PackageName.SYSTEMUI}.media.MediaData" private val MediaDataClass by lazyClassOrNull("${PackageName.SYSTEMUI}.media.MediaData")
/** ColorOS 存在的类 - 旧版本不存在 */ /** ColorOS 存在的类 - 旧版本不存在 */
private const val OplusContrastColorUtilClass = "com.oplusos.util.OplusContrastColorUtil" private val OplusContrastColorUtilClass by lazyClassOrNull("com.oplusos.util.OplusContrastColorUtil")
/** ColorOS 存在的类 - 旧版本不存在 */ /** ColorOS 存在的类 - 旧版本不存在 */
private const val OplusNotificationBackgroundViewClass = private val OplusNotificationBackgroundViewClass by lazyClassOrNull(
"com.oplusos.systemui.statusbar.notification.row.OplusNotificationBackgroundView" "com.oplusos.systemui.statusbar.notification.row.OplusNotificationBackgroundView")
/** ColorOS 存在的类 - 旧版本不存在 */ /** ColorOS 存在的类 - 旧版本不存在 */
private const val OplusMediaControlPanelClass = "com.oplusos.systemui.media.OplusMediaControlPanel" private val OplusMediaControlPanelClass by lazyClassOrNull("com.oplusos.systemui.media.OplusMediaControlPanel")
/** ColorOS 存在的类 - 旧版本不存在 */ /** ColorOS 存在的类 - 旧版本不存在 */
private const val OplusMediaViewControllerClass = "com.oplusos.systemui.media.OplusMediaViewController" private val OplusMediaViewControllerClass by lazyClassOrNull("com.oplusos.systemui.media.OplusMediaViewController")
/** ColorOS 存在的类 - 旧版本不存在 */ /** ColorOS 存在的类 - 旧版本不存在 */
private const val BasePlayViewHolderClass = "com.oplusos.systemui.media.base.BasePlayViewHolder" private val BasePlayViewHolderClass by lazyClassOrNull("com.oplusos.systemui.media.base.BasePlayViewHolder")
/** 根据多个版本存在不同的包名相同的类 */ /** 根据多个版本存在不同的包名相同的类 */
private val OplusNotificationIconAreaControllerClass = VariousClass( private val OplusNotificationIconAreaControllerClass by lazyClass(
"com.oplusos.systemui.statusbar.phone.OplusNotificationIconAreaController", VariousClass(
"com.oplusos.systemui.statusbar.policy.OplusNotificationIconAreaController", "com.oplusos.systemui.statusbar.phone.OplusNotificationIconAreaController",
"com.coloros.systemui.statusbar.policy.ColorNotificationIconAreaController" "com.oplusos.systemui.statusbar.policy.OplusNotificationIconAreaController",
"com.coloros.systemui.statusbar.policy.ColorNotificationIconAreaController"
)
) )
/** 根据多个版本存在不同的包名相同的类 */ /** 根据多个版本存在不同的包名相同的类 */
private val SystemPromptControllerClass = VariousClass( private val SystemPromptControllerClass by lazyClass(
"com.oplusos.systemui.statusbar.policy.SystemPromptController", VariousClass(
"com.coloros.systemui.statusbar.policy.ColorSystemPromptController" "com.oplusos.systemui.statusbar.policy.SystemPromptController",
"com.coloros.systemui.statusbar.policy.ColorSystemPromptController"
)
) )
/** 根据多个版本存在不同的包名相同的类 */ /** 根据多个版本存在不同的包名相同的类 */
private val RoundRectDrawableUtilClass = VariousClass( private val RoundRectDrawableUtilClass by lazyClass(
"com.oplusos.systemui.notification.util.RoundRectDrawableUtil", VariousClass(
"com.coloros.systemui.notification.util.RoundRectDrawableUtil" "com.oplusos.systemui.notification.util.RoundRectDrawableUtil",
"com.coloros.systemui.notification.util.RoundRectDrawableUtil"
)
) )
/** 根据多个版本存在不同的包名相同的类 */ /** 根据多个版本存在不同的包名相同的类 */
private val RoundRectDrawableUtil_CompanionClass = VariousClass( private val RoundRectDrawableUtil_CompanionClass by lazyClass(
"com.oplusos.systemui.notification.util.RoundRectDrawableUtil\$Companion", VariousClass(
"com.coloros.systemui.notification.util.RoundRectDrawableUtil\$Companion" "com.oplusos.systemui.notification.util.RoundRectDrawableUtil\$Companion",
"com.coloros.systemui.notification.util.RoundRectDrawableUtil\$Companion"
)
) )
/** 根据多个版本存在不同的包名相同的类 */ /** 根据多个版本存在不同的包名相同的类 */
private val DndAlertHelperClass = VariousClass( private val DndAlertHelperClass by lazyClass(
"com.oplusos.systemui.notification.helper.DndAlertHelper", VariousClass(
"com.coloros.systemui.notification.helper.DndAlertHelper" "com.oplusos.systemui.notification.helper.DndAlertHelper",
"com.coloros.systemui.notification.helper.DndAlertHelper"
)
) )
/** 根据多个版本存在不同的包名相同的类 */ /** 根据多个版本存在不同的包名相同的类 */
private val OplusPowerNotificationWarningsClass = VariousClass( private val OplusPowerNotificationWarningsClass by lazyClass(
"com.oplusos.systemui.notification.power.OplusPowerNotificationWarnings", VariousClass(
"com.coloros.systemui.notification.power.ColorosPowerNotificationWarnings" "com.oplusos.systemui.notification.power.OplusPowerNotificationWarnings",
"com.coloros.systemui.notification.power.ColorosPowerNotificationWarnings"
)
) )
/** 根据多个版本存在不同的包名相同的类 */ /** 根据多个版本存在不同的包名相同的类 */
private val StatusBarNotificationPresenterClass = VariousClass( private val StatusBarNotificationPresenterClass by lazyClass(
"${PackageName.SYSTEMUI}.statusbar.phone.StatusBarNotificationPresenter", VariousClass(
"${PackageName.SYSTEMUI}.statusbar.phone.StatusBar" "${PackageName.SYSTEMUI}.statusbar.phone.StatusBarNotificationPresenter",
"${PackageName.SYSTEMUI}.statusbar.phone.StatusBar"
)
) )
/** 根据多个版本存在不同的包名相同的类 */ /** 根据多个版本存在不同的包名相同的类 */
private val ExpandableNotificationRowClass = VariousClass( private val ExpandableNotificationRowClass by lazyClass(
"${PackageName.SYSTEMUI}.statusbar.notification.row.ExpandableNotificationRow", VariousClass(
"${PackageName.SYSTEMUI}.statusbar.ExpandableNotificationRow" "${PackageName.SYSTEMUI}.statusbar.notification.row.ExpandableNotificationRow",
"${PackageName.SYSTEMUI}.statusbar.ExpandableNotificationRow"
)
) )
/** 根据多个版本存在不同的包名相同的类 */ /** 根据多个版本存在不同的包名相同的类 */
private val NotificationViewWrapperClass = VariousClass( private val NotificationViewWrapperClass by lazyClass(
"${PackageName.SYSTEMUI}.statusbar.notification.row.wrapper.NotificationViewWrapper", VariousClass(
"${PackageName.SYSTEMUI}.statusbar.notification.NotificationViewWrapper" "${PackageName.SYSTEMUI}.statusbar.notification.row.wrapper.NotificationViewWrapper",
"${PackageName.SYSTEMUI}.statusbar.notification.NotificationViewWrapper"
)
) )
/** 根据多个版本存在不同的包名相同的类 */ /** 根据多个版本存在不同的包名相同的类 */
private val NotificationHeaderViewWrapperClass = VariousClass( private val NotificationHeaderViewWrapperClass by lazyClass(
"${PackageName.SYSTEMUI}.statusbar.notification.row.wrapper.NotificationHeaderViewWrapper", VariousClass(
"${PackageName.SYSTEMUI}.statusbar.notification.NotificationHeaderViewWrapper" "${PackageName.SYSTEMUI}.statusbar.notification.row.wrapper.NotificationHeaderViewWrapper",
"${PackageName.SYSTEMUI}.statusbar.notification.NotificationHeaderViewWrapper"
)
) )
/** 缓存的彩色 APP 图标 */ /** 缓存的彩色 APP 图标 */
@@ -243,7 +262,7 @@ object SystemUIHooker : YukiBaseHooker() {
* @return [Boolean] * @return [Boolean]
*/ */
private val isOldNotificationBackground private val isOldNotificationBackground
get() = NotificationBackgroundViewClass.toClassOrNull()?.hasMethod { get() = NotificationBackgroundViewClass?.hasMethod {
name = "drawCustom" name = "drawCustom"
paramCount = 2 paramCount = 2
} ?: false } ?: false
@@ -257,7 +276,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" +
@@ -286,14 +305,14 @@ object SystemUIHooker : YukiBaseHooker() {
/** 刷新状态栏小图标 */ /** 刷新状态栏小图标 */
private fun refreshStatusBarIcons() = runInSafe { private fun refreshStatusBarIcons() = runInSafe {
val nfField = StatusBarIconViewClass.toClass().field { name = "mNotification" } val nfField = StatusBarIconViewClass.field { name = "mNotification" }
val sRadiusField = StatusBarIconViewClass.toClass().field { name = "sIconRadiusFraction" } val sRadiusField = StatusBarIconViewClass.field { name = "sIconRadiusFraction" }
val sNfSizeField = StatusBarIconViewClass.toClass().field { name = "sNotificationRoundIconSize" } val sNfSizeField = StatusBarIconViewClass.field { name = "sNotificationRoundIconSize" }
val roundUtil = RoundRectDrawableUtil_CompanionClass.toClass().method { val roundUtil = RoundRectDrawableUtil_CompanionClass.method {
name = "getRoundRectDrawable" name = "getRoundRectDrawable"
param(DrawableClass, FloatType, IntType, IntType, ContextClass) param(DrawableClass, FloatType, IntType, IntType, ContextClass)
}.onNoSuchMethod { loggerE(msg = "Your system not support \"getRoundRectDrawable\"!", e = it) } }.onNoSuchMethod { YLog.error("Your system not support \"getRoundRectDrawable\"!", it) }
.get(RoundRectDrawableUtilClass.toClass().field { name = "Companion" }.get().any()) .get(RoundRectDrawableUtilClass.field { name = "Companion" }.get().any())
/** 启动一个线程防止卡顿 */ /** 启动一个线程防止卡顿 */
Thread { Thread {
(notificationIconContainer?.children?.toList() ?: notificationIconInstances.takeIf { it.isNotEmpty() })?.forEach { (notificationIconContainer?.children?.toList() ?: notificationIconInstances.takeIf { it.isNotEmpty() })?.forEach {
@@ -303,7 +322,7 @@ object SystemUIHooker : YukiBaseHooker() {
/** 得到原始通知图标 */ /** 得到原始通知图标 */
val iconDrawable = nf.notification.smallIcon.loadDrawable(it.context) val iconDrawable = nf.notification.smallIcon.loadDrawable(it.context)
?: return@Thread loggerW(msg = "refreshStatusBarIcons got null smallIcon") ?: return@Thread YLog.warn("refreshStatusBarIcons got null smallIcon")
/** 获取优化后的状态栏通知图标 */ /** 获取优化后的状态栏通知图标 */
compatStatusIcon( compatStatusIcon(
context = it.context, context = it.context,
@@ -344,7 +363,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)
@@ -632,138 +651,101 @@ object SystemUIHooker : YukiBaseHooker() {
/** 缓存图标数据 */ /** 缓存图标数据 */
cachingIconDatas() cachingIconDatas()
/** 移除开发者警告通知 */ /** 移除开发者警告通知 */
SystemPromptControllerClass.hook { SystemPromptControllerClass.method {
injectMember { name = "updateDeveloperMode"
method { name = "updateDeveloperMode" } }.hook().before {
beforeHook { /** 是否移除 */
/** 是否移除 */ if (ConfigData.isEnableRemoveDevNotify) resultNull()
if (ConfigData.isEnableRemoveDevNotify) resultNull()
}
}
} }
/** 移除充电完成通知 */ /** 移除充电完成通知 */
OplusPowerNotificationWarningsClass.hook { OplusPowerNotificationWarningsClass.method {
injectMember { name = "showChargeErrorDialog"
method { param(IntType)
name = "showChargeErrorDialog" }.hook().before {
param(IntType) /** 是否移除 */
} if (args().first().int() == 7 && ConfigData.isEnableRemoveChangeCompleteNotify) resultNull()
beforeHook {
/** 是否移除 */
if (args().first().int() == 7 && ConfigData.isEnableRemoveChangeCompleteNotify) resultNull()
}
}
} }
/** 移除免打扰通知 */ /** 移除免打扰通知 */
DndAlertHelperClass.hook { DndAlertHelperClass.method {
injectMember { name { it.lowercase() == "sendnotificationwithendtime" }
method { param(LongType)
name { it.lowercase() == "sendnotificationwithendtime" } }.hook().before {
param(LongType) /** 是否移除 */
} if (ConfigData.isEnableRemoveDndAlertNotify) resultNull()
beforeHook {
/** 是否移除 */
if (ConfigData.isEnableRemoveDndAlertNotify) resultNull()
}
}
} }
/** 修复并替换 ColorOS 以及原生灰度图标色彩判断 */ /** 修复并替换 ColorOS 以及原生灰度图标色彩判断 */
NotificationUtilsClass.hook { NotificationUtilsClass.apply {
injectMember { method {
method { name = "isGrayscale"
name = "isGrayscale" param(ImageViewClass, ContrastColorUtilClass)
param(ImageViewClass, ContrastColorUtilClass) }.hook().replaceAny { args().first().cast<ImageView>()?.let { isGrayscaleIcon(it.context, it.drawable) } ?: callOriginal() }
} method {
replaceAny { args().first().cast<ImageView>()?.let { isGrayscaleIcon(it.context, it.drawable) } ?: callOriginal() } name = "isGrayscaleOplus"
} param(ImageViewClass, OplusContrastColorUtilClass ?: VagueType)
injectMember { }.ignored().hook().replaceAny { args().first().cast<ImageView>()?.let { isGrayscaleIcon(it.context, it.drawable) } ?: callOriginal() }
method {
name = "isGrayscaleOplus"
param(ImageViewClass, OplusContrastColorUtilClass)
}
replaceAny { args().first().cast<ImageView>()?.let { isGrayscaleIcon(it.context, it.drawable) } ?: callOriginal() }
}.ignoredNoSuchMemberFailure()
} }
/** 替换状态栏图标 */ /** 替换状态栏图标 */
IconManagerClass.hook { IconManagerClass.method {
injectMember { name = "getIconDescriptor"
method { param(NotificationEntryClass, BooleanType)
name = "getIconDescriptor" }.hook().after {
param(NotificationEntryClass, BooleanType) IconBuilderClass.field { name = "context" }
} .get(IconManagerClass.field { name = "iconBuilder" }.get(instance).cast()).cast<Context>()?.also { context ->
afterHook { NotificationEntryClass.method {
IconBuilderClass.toClass().field { name = "context" } name = "getSbn"
.get(field { name = "iconBuilder" }.get(instance).cast()).cast<Context>()?.also { context -> }.get(args().first().any()).invoke<StatusBarNotification>()?.also { nf ->
NotificationEntryClass.toClass().method { nf.notification.smallIcon.loadDrawable(context)?.also { iconDrawable ->
name = "getSbn" compatStatusIcon(
}.get(args().first().any()).invoke<StatusBarNotification>()?.also { nf -> context = context,
nf.notification.smallIcon.loadDrawable(context)?.also { iconDrawable -> nf = nf,
compatStatusIcon( isGrayscaleIcon = isGrayscaleIcon(context, iconDrawable).also {
context = context, /** 缓存第一次的 APP 小图标 */
nf = nf, if (it.not()) context.appIconOf(nf.packageName)?.also { e -> appIcons[nf.packageName] = e }
isGrayscaleIcon = isGrayscaleIcon(context, iconDrawable).also { },
/** 缓存第一次的 APP 小图标 */ packageName = nf.packageName,
if (it.not()) context.appIconOf(nf.packageName)?.also { e -> appIcons[nf.packageName] = e } drawable = iconDrawable
}, ).also { pair ->
packageName = nf.packageName, if (pair.second) StatusBarIconClass.field {
drawable = iconDrawable name = "icon"
).also { pair -> type = IconClass
if (pair.second) StatusBarIconClass.toClass().field { }.get(result).set(Icon.createWithBitmap(pair.first.toBitmap()))
name = "icon"
type = IconClass
}.get(result).set(Icon.createWithBitmap(pair.first.toBitmap()))
}
}
} }
} }
} }
} }
} }
/** 得到状态栏图标实例 */ /** 得到状态栏图标实例 */
StatusBarIconViewClass.hook { StatusBarIconViewClass.method {
injectMember { name = "setNotification"
method { param(StatusBarNotificationClass)
name = "setNotification" }.hook().after {
param(StatusBarNotificationClass) /** 注册壁纸颜色监听 */
} if (args().first().any() != null) instance<ImageView>().also { registerWallpaperColorChanged(it) }
afterHook {
/** 注册壁纸颜色监听 */
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 }
}
}
/** 注入状态栏通知图标容器实例 */ /** 注入状态栏通知图标容器实例 */
OplusNotificationIconAreaControllerClass.hook { OplusNotificationIconAreaControllerClass.apply {
injectMember { var isOldWay = false
var isOldWay = false method {
name = "updateIconsForLayout"
paramCount = 10
}.remedys {
method { method {
name = "updateIconsForLayout" name = "updateIconsForLayout"
paramCount = 10 paramCount = 1
}.remedys { }.onFind { isOldWay = true }
method { }.hook().after {
name = "updateIconsForLayout" if (isOldWay) {
paramCount = 1 notificationIconInstances.clear()
}.onFind { isOldWay = true } field { name = "mLastToShow" }.get(instance).list<View>()
} .takeIf { it.isNotEmpty() }?.forEach { notificationIconInstances.add(it) }
afterHook { } else notificationIconContainer = args(index = 1).cast()
if (isOldWay) {
notificationIconInstances.clear()
field { name = "mLastToShow" }.get(instance).list<View>()
.takeIf { it.isNotEmpty() }?.forEach { notificationIconInstances.add(it) }
} else notificationIconContainer = args(index = 1).cast()
}
} }
} }
/** 替换通知面板背景 - 新版本 */ /** 替换通知面板背景 - 新版本 */
OplusNotificationBackgroundViewClass.hook { if (isOldNotificationBackground.not())
injectMember { OplusNotificationBackgroundViewClass?.apply {
method { method {
name = "drawRegionBlur" name = "drawRegionBlur"
paramCount = 2 paramCount = 2
@@ -772,122 +754,104 @@ object SystemUIHooker : YukiBaseHooker() {
name = "draw" name = "draw"
paramCount = 2 paramCount = 2
} }
} }.hook().before { modifyNotifyPanelAlpha(instance(), args().last().cast<Drawable>()) }
beforeHook { modifyNotifyPanelAlpha(instance(), args().last().cast<Drawable>()) }
}
injectMember {
method { method {
name = "draw" name = "draw"
paramCount = 2 paramCount = 2
superClass(isOnlySuperClass = true) superClass(isOnlySuperClass = true)
} }.hook().before { modifyNotifyPanelAlpha(instance(), args().last().cast<Drawable>()) }
beforeHook { modifyNotifyPanelAlpha(instance(), args().last().cast<Drawable>()) }
} }
}.ignoredHookClassNotFoundFailure().by { isOldNotificationBackground.not() }
/** 替换通知面板背景 - 旧版本 */ /** 替换通知面板背景 - 旧版本 */
NotificationBackgroundViewClass.hook { if (isOldNotificationBackground)
injectMember { NotificationBackgroundViewClass?.apply {
method { method {
name = "draw" name = "draw"
paramCount = 2 paramCount = 2
} }.hook().before { modifyNotifyPanelAlpha(instance(), args().last().cast<Drawable>()) }
beforeHook { modifyNotifyPanelAlpha(instance(), args().last().cast<Drawable>()) }
}
injectMember {
method { method {
name = "drawCustom" name = "drawCustom"
paramCount = 2 paramCount = 2
} }.ignored().hook().before { modifyNotifyPanelAlpha(instance(), args().last().cast<Drawable>()) }
beforeHook { modifyNotifyPanelAlpha(instance(), args().last().cast<Drawable>()) } }
}.ignoredNoSuchMemberFailure()
}.by { isOldNotificationBackground }
/** 替换通知面板背景 - 避免折叠展开通知二次修改通知面板背景 */ /** 替换通知面板背景 - 避免折叠展开通知二次修改通知面板背景 */
ExpandableNotificationRowClass.hook { ExpandableNotificationRowClass.apply {
injectMember { method {
method { name = "updateBackgroundForGroupState"
name = "updateBackgroundForGroupState" emptyParam()
emptyParam() }.hook().before {
} if (ConfigData.isEnableNotifyPanelAlpha) field { name = "mShowGroupBackgroundWhenExpanded" }.get(instance).setTrue()
beforeHook {
if (ConfigData.isEnableNotifyPanelAlpha) field { name = "mShowGroupBackgroundWhenExpanded" }.get(instance).setTrue()
}
} }
} }
/** 替换媒体通知面板背景 - 设置媒体通知自动展开 */ /** 替换媒体通知面板背景 - 设置媒体通知自动展开 */
OplusMediaControlPanelClass.hook { OplusMediaControlPanelClass?.apply {
injectMember { method {
method { name = "bind"
name = "bind" paramCount = 2
paramCount = 2 }.hook().after {
} /** 得到当前实例 */
afterHook { val holder = OplusMediaControlPanelClass?.field {
/** 得到当前实例 */ name = "mViewHolder"
val holder = field { superClass(isOnlySuperClass = true)
name = "mViewHolder" }?.get(instance)?.any()
superClass(isOnlySuperClass = true) /** 记录媒体通知 [View] */
}.get(instance).any() notificationPlayerView = PlayerViewHolderClass?.method {
/** 记录媒体通知 [View] */ name = "getPlayer"
notificationPlayerView = PlayerViewHolderClass.toClassOrNull()?.method { emptyParam()
name = "getPlayer" }?.get(holder)?.invoke()
emptyParam() /** 设置背景着色 */
}?.get(holder)?.invoke() modifyNotifyPanelAlpha(notificationPlayerView, isTint = true)
/** 设置背景着色 */ /** 当前是否正在播放 */
modifyNotifyPanelAlpha(notificationPlayerView, isTint = true) val isPlaying = MediaDataClass?.method {
/** 当前是否正在播放 */ name = "isPlaying"
val isPlaying = MediaDataClass.toClassOrNull()?.method { emptyParam()
name = "isPlaying" }?.get(args().first().any())?.boolean() ?: false
emptyParam()
}?.get(args().first().any())?.boolean() ?: false
/** 当前通知是否展开 */ /** 当前通知是否展开 */
val isExpanded = OplusMediaViewControllerClass.toClassOrNull()?.method { val isExpanded = OplusMediaViewControllerClass?.method {
name = "getExpanded" name = "getExpanded"
emptyParam() emptyParam()
}?.get(field { name = "mOplusMediaViewController" }.get(instance).any())?.boolean() ?: false }?.get(field { name = "mOplusMediaViewController" }.get(instance).any())?.boolean() ?: false
/** 符合条件后执行 */ /** 符合条件后执行 */
if (ConfigData.isEnableNotifyMediaPanelAutoExp.not() || isExpanded || isPlaying.not()) return@afterHook if (ConfigData.isEnableNotifyMediaPanelAutoExp.not() || isExpanded || isPlaying.not()) return@after
/** 模拟手动展开通知 */ /** 模拟手动展开通知 */
BasePlayViewHolderClass.toClassOrNull()?.method { BasePlayViewHolderClass?.method {
name = "getExpandButton" name = "getExpandButton"
emptyParam() emptyParam()
}?.get(holder)?.invoke<View>()?.performClick() }?.get(holder)?.invoke<View>()?.performClick()
}
} }
}.ignoredHookClassNotFoundFailure() }
/** 替换通知图标和样式 */ /** 替换通知图标和样式 */
NotificationHeaderViewWrapperClass.hook { NotificationHeaderViewWrapperClass.apply {
injectMember { method {
method { name { it == "resolveHeaderViews" || it == "onContentUpdated" } }.all() name { it == "resolveHeaderViews" || it == "onContentUpdated" }
afterHook { }.hookAll().after {
NotificationHeaderViewWrapperClass.toClass() field { name = "mIcon" }.get(instance).cast<ImageView>()?.apply {
.field { name = "mIcon" }.get(instance).cast<ImageView>()?.apply { ExpandableNotificationRowClass
ExpandableNotificationRowClass.toClass() .method { name = "getEntry" }
.method { name = "getEntry" } .get(NotificationViewWrapperClass.field {
.get(NotificationViewWrapperClass.toClass().field { name = "mRow"
name = "mRow" }.get(instance).any()).call()?.let {
}.get(instance).any()).call()?.let { it.javaClass.method {
it.javaClass.method { name = "getSbn"
name = "getSbn" }.get(it).invoke<StatusBarNotification>()
}.get(it).invoke<StatusBarNotification>() }.also { nf ->
}.also { nf -> nf?.notification?.also {
nf?.notification?.also { it.smallIcon.loadDrawable(context)?.also { iconDrawable ->
it.smallIcon.loadDrawable(context)?.also { iconDrawable -> /** 执行替换 */
/** 执行替换 */ fun doParse() {
fun doParse() { compatNotifyIcon(
compatNotifyIcon( context = context,
context = context, nf = nf,
nf = nf, isGrayscaleIcon = isGrayscaleIcon(context, iconDrawable),
isGrayscaleIcon = isGrayscaleIcon(context, iconDrawable), packageName = context.packageName,
packageName = context.packageName, drawable = iconDrawable,
drawable = iconDrawable, iconColor = it.color,
iconColor = it.color, iconView = this
iconView = this )
)
}
doParse()
/** 延迟重新设置防止部分机型的系统重新设置图标出现图标着色后黑白块问题 */
delayedRun(ms = 1500) { doParse() }
} }
doParse()
/** 延迟重新设置防止部分机型的系统重新设置图标出现图标着色后黑白块问题 */
delayedRun(ms = 1500) { doParse() }
} }
} }
} }

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.coloros.notify.utils.factory package com.fankes.coloros.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.coloros.notify.utils.factory package com.fankes.coloros.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.coloros.notify.utils.factory.openBrowser
import com.fankes.coloros.notify.utils.factory.safeOfNull import com.fankes.coloros.notify.utils.factory.safeOfNull
import com.fankes.coloros.notify.utils.factory.showDialog import com.fankes.coloros.notify.utils.factory.showDialog
import com.fankes.coloros.notify.utils.factory.snake import com.fankes.coloros.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

@@ -38,8 +38,8 @@ import com.fankes.coloros.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
@@ -53,7 +53,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
@@ -100,7 +100,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" +
"[ColorOS Version]: $colorOSFullVersion\n" + "[ColorOS Version]: $colorOSFullVersion\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 = "已取消操作")