@@ -44,6 +44,7 @@ import android.widget.ImageView
4444import androidx.core.graphics.drawable.toBitmap
4545import androidx.core.graphics.drawable.toDrawable
4646import androidx.core.view.children
47+ import androidx.core.view.setPadding
4748import com.fankes.coloros.notify.R
4849import com.fankes.coloros.notify.bean.IconDataBean
4950import com.fankes.coloros.notify.const.PackageName
@@ -136,6 +137,12 @@ object SystemUIHooker : YukiBaseHooker() {
136137 /* * ColorOS 存在的类 - 旧版本不存在 */
137138 private val OplusNotificationSmallIconUtilClass by lazyClassOrNull(" com.oplus.systemui.statusbar.notification.util.OplusNotificationSmallIconUtil" )
138139
140+ /* * ColorOS 存在的类 - 旧版本不存在 */
141+ private val OplusNotificationHeaderViewWrapperExImpClass by lazyClassOrNull(" com.oplus.systemui.statusbar.notification.row.wrapper.OplusNotificationHeaderViewWrapperExImp" )
142+
143+ /* * ColorOS 存在的类 - 旧版本不存在 */
144+ private val OplusNotificationGroupTemplateWrapperClass by lazyClassOrNull(" com.oplus.systemui.notification.row.oplusgroup.OplusNotificationGroupTemplateWrapper" )
145+
139146 /* * 根据多个版本存在不同的包名相同的类 */
140147 private val OplusNotificationIconAreaControllerClass by lazyClass(
141148 VariousClass (
@@ -276,6 +283,17 @@ object SystemUIHooker : YukiBaseHooker() {
276283 parameterCount = 2
277284 } != null
278285
286+ /* *
287+ * 判断通知是否为新版本
288+ * @return [Boolean]
289+ */
290+ private val isNewNotification
291+ get() = OplusNotificationHeaderViewWrapperExImpClass ?.resolve()?.optional(silent = true )
292+ ?.firstMethodOrNull {
293+ name = " proxyOnContentUpdated"
294+ parameterCount = 1
295+ } != null
296+
279297 /* *
280298 * 打印日志
281299 * @param tag 标识
@@ -314,6 +332,7 @@ object SystemUIHooker : YukiBaseHooker() {
314332
315333 /* * 刷新状态栏小图标 */
316334 private fun refreshStatusBarIcons () = runInSafe {
335+ if (isNewNotification) return @runInSafe
317336 val nfField = StatusBarIconViewClass .resolve().optional().firstFieldOrNull { name = " mNotification" }
318337 val sRadiusField = StatusBarIconViewClass .resolve().optional(silent = true ).firstFieldOrNull {
319338 name = " sIconRadiusFraction"
@@ -533,11 +552,11 @@ object SystemUIHooker : YukiBaseHooker() {
533552 .solidColor(newApplyColor)
534553 .build()
535554 setColorFilter(newStyle)
536- setPadding(2 .dp(context), 2 .dp(context), 2 .dp(context), 2 .dp(context) )
555+ setPadding(2 .dp(context))
537556 } else {
538557 background = null
539558 setColorFilter(oldApplyColor)
540- setPadding(0 , 0 , 0 , 0 )
559+ setPadding(0 )
541560 }
542561 }
543562 else -> iconView.apply {
@@ -599,7 +618,7 @@ object SystemUIHooker : YukiBaseHooker() {
599618 }
600619 }
601620 /* * 清除图标间距 */
602- setPadding(0 , 0 , 0 , 0 )
621+ setPadding(0 )
603622 /* * 清除背景 */
604623 background = null
605624 /* * 清除着色 */
@@ -767,46 +786,6 @@ object SystemUIHooker : YukiBaseHooker() {
767786 }
768787 /* * 注入通知控制器实例 */
769788 StatusBarNotificationPresenterClass .resolve().optional().constructor {}.hookAll().after { notificationPresenter = instance }
770- /* * 注入状态栏通知图标容器实例 */
771- OplusNotificationIconAreaControllerClass .resolve().optional().apply {
772- var way = 0
773- (firstMethodOrNull {
774- name = " updateIconsForLayout"
775- parameterCount = 10
776- } ? : firstMethodOrNull {
777- /* * ColorOS 14 */
778- name = " updateIconsForLayout"
779- parameterCount = 5
780- } ? : firstMethodOrNull {
781- name = " updateIconsForLayout"
782- parameterCount = 1
783- }?.apply { way = 1 }
784- ? : firstMethodOrNull {
785- name = " updateIconsForLayout"
786- }?.apply { way = 2 })?.hook()?.after {
787- when (way) {
788- 2 -> notificationIconContainer = OplusNotificationIconAreaControllerClass .resolve().optional()
789- .firstMethodOrNull { name = " getNotificationIcons" }
790- ?.of(instance)?.invoke<ViewGroup >()
791- 1 -> {
792- notificationIconInstances.clear()
793- firstFieldOrNull { name = " mLastToShow" }?.of(instance)?.get<List <View >>()
794- ?.takeIf { it.isNotEmpty() }?.forEach { notificationIconInstances.add(it) }
795- }
796- else -> notificationIconContainer = args(index = 1 ).cast()
797- }
798- }
799- }
800- /* * 注入状态栏通知图标容器实例 */
801- (LegacyNotificationIconAreaControllerImpl ? : NotificationIconAreaControllerClass )
802- .resolve().optional().apply {
803- firstMethodOrNull {
804- name = " updateIconsForLayout"
805- parameterCount = 8
806- }?.hook()?.after {
807- notificationIconContainer = args(index = 1 ).cast()
808- }
809- }
810789 /* * 替换通知面板背景 - 新版本 */
811790 if (! isOldNotificationBackground)
812791 OplusNotificationBackgroundViewClass ?.resolve()?.optional()?.apply {
@@ -876,25 +855,75 @@ object SystemUIHooker : YukiBaseHooker() {
876855 }?.of(holder)?.invokeQuietly<View >()?.performClick()
877856 }
878857 }
879- /* * 替换通知图标和样式 */
880- NotificationHeaderViewWrapperClass .resolve().optional().apply {
881- method {
882- name { it == " resolveHeaderViews" || it == " onContentUpdated" }
883- }.hookAll().after {
884- firstFieldOrNull { name = " mIcon" }?.of(instance)?.get<ImageView >()?.apply {
885- ExpandableNotificationRowClass .resolve().optional()
886- .firstMethodOrNull { name = " getEntry" }
887- ?.of(NotificationViewWrapperClass .resolve().optional().firstFieldOrNull {
888- name = " mRow"
889- }?.of(instance)?.get())?.invokeQuietly()?.let {
890- it.asResolver().optional().firstMethodOrNull {
891- name = " getSbn"
892- }?.invoke<StatusBarNotification >()
893- }.also { nf ->
894- nf?.notification?.also {
895- it.smallIcon.loadDrawable(context)?.also { iconDrawable ->
896- /* * 执行替换 */
897- fun doParse () {
858+
859+ if (isNewNotification) {
860+ /* * 替换通知图标和样式 */
861+ OplusNotificationHeaderViewWrapperExImpClass ?.resolve()?.optional()?.apply {
862+ firstMethodOrNull {
863+ name = " proxyOnContentUpdated"
864+ parameterCount = 1
865+ }?.hook()?.after {
866+ val mBase = instance.asResolver().optional().firstMethodOrNull {
867+ name = " getBase"
868+ emptyParameters()
869+ }?.invokeQuietly()
870+ val imageView = mBase?.asResolver()?.optional()?.firstFieldOrNull {
871+ name = " mIcon"
872+ type = ImageView ::class
873+ }?.getQuietly<ImageView >()
874+ imageView?.apply {
875+ ExpandableNotificationRowClass .resolve().optional()
876+ .firstMethodOrNull { name = " getEntry" }
877+ ?.of(args[0 ])?.invokeQuietly()?.let {
878+ it.asResolver().optional().firstMethodOrNull {
879+ name = " getSbn"
880+ }?.invoke<StatusBarNotification >()
881+ }.also { nf ->
882+ nf?.notification?.also {
883+ it.smallIcon.loadDrawable(context)?.also { iconDrawable ->
884+ compatNotifyIcon(
885+ context = context,
886+ nf = nf,
887+ isGrayscaleIcon = isGrayscaleIcon(context, iconDrawable),
888+ packageName = context.packageName,
889+ drawable = iconDrawable,
890+ iconColor = it.color,
891+ iconView = this
892+ )
893+ }
894+ }
895+ }
896+ }
897+ }
898+ }
899+
900+ OplusNotificationGroupTemplateWrapperClass ?.resolve()?.optional()?.apply {
901+ firstMethodOrNull {
902+ name = " initIcon"
903+ }?.hook()?.before {
904+ val instanceContext = firstFieldOrNull {
905+ name = " context"
906+ }?.of(instance)?.get() as Context ?
907+ if (instanceContext == null )
908+ return @before
909+ resultNull()
910+ NotificationHeaderViewWrapperClass .resolve().optional().firstFieldOrNull { name = " mIcon" }?.of(instance)?.get<ImageView >()?.apply {
911+ ExpandableNotificationRowClass .resolve().optional()
912+ .firstMethodOrNull { name = " getEntry" }
913+ ?.of(NotificationViewWrapperClass .resolve().optional().firstFieldOrNull {
914+ name = " mRow"
915+ }?.of(instance)?.get())?.invokeQuietly()?.let {
916+ it.asResolver().optional().firstMethodOrNull {
917+ name = " getSbn"
918+ }?.invoke<StatusBarNotification >()
919+ }.also { nf ->
920+ val context = StatusBarNotification ::class .resolve().firstMethod {
921+ name = " getPackageContext"
922+ }.of(nf).invoke<Context >(instanceContext)
923+ if (context == null ) return @also
924+
925+ nf?.notification?.also {
926+ it.smallIcon.loadDrawable(context)?.also { iconDrawable ->
898927 compatNotifyIcon(
899928 context = context,
900929 nf = nf,
@@ -905,12 +934,89 @@ object SystemUIHooker : YukiBaseHooker() {
905934 iconView = this
906935 )
907936 }
908- doParse()
909- /* * 延迟重新设置防止部分机型的系统重新设置图标出现图标着色后黑白块问题 */
910- delayedRun(ms = 1500 ) { doParse() }
911937 }
912938 }
939+ }
940+ }
941+ }
942+ } else {
943+ /* * 注入状态栏通知图标容器实例 */
944+ OplusNotificationIconAreaControllerClass .resolve().optional().apply {
945+ var way = 0
946+ (firstMethodOrNull {
947+ name = " updateIconsForLayout"
948+ parameterCount = 10
949+ } ? : firstMethodOrNull {
950+ /* * ColorOS 14 */
951+ name = " updateIconsForLayout"
952+ parameterCount = 5
953+ } ? : firstMethodOrNull {
954+ name = " updateIconsForLayout"
955+ parameterCount = 1
956+ }?.apply { way = 1 }
957+ ? : firstMethodOrNull {
958+ name = " updateIconsForLayout"
959+ }?.apply { way = 2 })?.hook()?.after {
960+ when (way) {
961+ 2 -> notificationIconContainer = OplusNotificationIconAreaControllerClass .resolve().optional()
962+ .firstMethodOrNull { name = " getNotificationIcons" }
963+ ?.of(instance)?.invoke<ViewGroup >()
964+ 1 -> {
965+ notificationIconInstances.clear()
966+ firstFieldOrNull { name = " mLastToShow" }?.of(instance)?.get<List <View >>()
967+ ?.takeIf { it.isNotEmpty() }?.forEach { notificationIconInstances.add(it) }
913968 }
969+ else -> notificationIconContainer = args(index = 1 ).cast()
970+ }
971+ }
972+ }
973+ /* * 注入状态栏通知图标容器实例 */
974+ (LegacyNotificationIconAreaControllerImpl ? : NotificationIconAreaControllerClass )
975+ .resolve().optional().apply {
976+ firstMethodOrNull {
977+ name = " updateIconsForLayout"
978+ parameterCount = 8
979+ }?.hook()?.after {
980+ notificationIconContainer = args(index = 1 ).cast()
981+ }
982+ }
983+
984+ /* * 替换通知图标和样式 */
985+ NotificationHeaderViewWrapperClass .resolve().optional().apply {
986+ method {
987+ name { it == " resolveHeaderViews" || it == " onContentUpdated" }
988+ }.hookAll().after {
989+ firstFieldOrNull { name = " mIcon" }?.of(instance)?.get<ImageView >()?.apply {
990+ ExpandableNotificationRowClass .resolve().optional()
991+ .firstMethodOrNull { name = " getEntry" }
992+ ?.of(NotificationViewWrapperClass .resolve().optional().firstFieldOrNull {
993+ name = " mRow"
994+ }?.of(instance)?.get())?.invokeQuietly()?.let {
995+ it.asResolver().optional().firstMethodOrNull {
996+ name = " getSbn"
997+ }?.invoke<StatusBarNotification >()
998+ }.also { nf ->
999+ nf?.notification?.also {
1000+ it.smallIcon.loadDrawable(context)?.also { iconDrawable ->
1001+ /* * 执行替换 */
1002+ fun doParse () {
1003+ compatNotifyIcon(
1004+ context = context,
1005+ nf = nf,
1006+ isGrayscaleIcon = isGrayscaleIcon(context, iconDrawable),
1007+ packageName = context.packageName,
1008+ drawable = iconDrawable,
1009+ iconColor = it.color,
1010+ iconView = this
1011+ )
1012+ }
1013+ doParse()
1014+ /* * 延迟重新设置防止部分机型的系统重新设置图标出现图标着色后黑白块问题 */
1015+ delayedRun(ms = 1500 ) { doParse() }
1016+ }
1017+ }
1018+ }
1019+ }
9141020 }
9151021 }
9161022 }
0 commit comments