style: optimize code

This commit is contained in:
2023-09-18 00:15:13 +08:00
parent bd57f76232
commit b74adce241
9 changed files with 174 additions and 110 deletions

View File

@@ -47,13 +47,15 @@ data class IconDataBean(
) : Serializable {
fun toEnabledName() = ("$appName$packageName").base64 + "_enable"
fun toEnabledAllName() = ("$appName$packageName").base64 + "_enable_all"
override fun toString() = "{\n" +
" \"appName\": \"$appName\",\n" +
" \"packageName\": \"$packageName\",\n" +
" \"iconBitmap\": \"${iconBitmap.base64}\",\n" +
" \"iconColor\": \"#${Integer.toHexString(iconColor)}\",\n" +
" \"contributorName\": \"$contributorName\",\n" +
" \"isEnabled\": $isEnabled,\n" +
" \"isEnabledAll\": $isEnabledAll\n" +
" }"
override fun toString() = """
{
"appName": "$appName",
"packageName": "$packageName",
"iconBitmap": "${iconBitmap.base64}",
"iconColor": "#${Integer.toHexString(iconColor)}",
"contributorName": "$contributorName",
"isEnabled": $isEnabled,
"isEnabledAll": $isEnabledAll
}
""".trimIndent()
}

View File

@@ -20,7 +20,7 @@
*
* This file is Created by fankes on 2022/3/25.
*/
@file:Suppress("StaticFieldLeak")
@file:Suppress("StaticFieldLeak", "ConstPropertyName")
package com.fankes.coloros.notify.hook.entity
@@ -51,18 +51,39 @@ import com.fankes.coloros.notify.data.ConfigData
import com.fankes.coloros.notify.param.IconPackParams
import com.fankes.coloros.notify.param.factory.isAppNotifyHookAllOf
import com.fankes.coloros.notify.param.factory.isAppNotifyHookOf
import com.fankes.coloros.notify.utils.factory.*
import com.fankes.coloros.notify.utils.factory.appIconOf
import com.fankes.coloros.notify.utils.factory.appNameOf
import com.fankes.coloros.notify.utils.factory.colorAlphaOf
import com.fankes.coloros.notify.utils.factory.delayedRun
import com.fankes.coloros.notify.utils.factory.dp
import com.fankes.coloros.notify.utils.factory.dpFloat
import com.fankes.coloros.notify.utils.factory.drawableOf
import com.fankes.coloros.notify.utils.factory.isSystemInDarkMode
import com.fankes.coloros.notify.utils.factory.isUpperOfAndroidS
import com.fankes.coloros.notify.utils.factory.runInSafe
import com.fankes.coloros.notify.utils.factory.safeOf
import com.fankes.coloros.notify.utils.factory.safeOfFalse
import com.fankes.coloros.notify.utils.factory.systemAccentColor
import com.fankes.coloros.notify.utils.tool.ActivationPromptTool
import com.fankes.coloros.notify.utils.tool.BitmapCompatTool
import com.fankes.coloros.notify.utils.tool.IconAdaptationTool
import com.fankes.coloros.notify.utils.tool.SystemUITool
import com.highcapable.yukihookapi.hook.bean.VariousClass
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
import com.highcapable.yukihookapi.hook.factory.*
import com.highcapable.yukihookapi.hook.factory.MembersType
import com.highcapable.yukihookapi.hook.factory.current
import com.highcapable.yukihookapi.hook.factory.field
import com.highcapable.yukihookapi.hook.factory.hasMethod
import com.highcapable.yukihookapi.hook.factory.injectModuleAppResources
import com.highcapable.yukihookapi.hook.factory.method
import com.highcapable.yukihookapi.hook.log.loggerD
import com.highcapable.yukihookapi.hook.log.loggerE
import com.highcapable.yukihookapi.hook.log.loggerW
import com.highcapable.yukihookapi.hook.type.android.*
import com.highcapable.yukihookapi.hook.type.android.ContextClass
import com.highcapable.yukihookapi.hook.type.android.DrawableClass
import com.highcapable.yukihookapi.hook.type.android.IconClass
import com.highcapable.yukihookapi.hook.type.android.ImageViewClass
import com.highcapable.yukihookapi.hook.type.android.StatusBarNotificationClass
import com.highcapable.yukihookapi.hook.type.java.BooleanType
import com.highcapable.yukihookapi.hook.type.java.FloatType
import com.highcapable.yukihookapi.hook.type.java.IntType
@@ -238,15 +259,15 @@ object SystemUIHooker : YukiBaseHooker() {
private fun loggerDebug(tag: String, context: Context, nf: StatusBarNotification?, isCustom: Boolean, isGrayscale: Boolean) {
if (ConfigData.isEnableModuleLog) loggerD(
msg = "(Processing $tag) ↓\n" +
"[Title]: ${nf?.notification?.extras?.getString(Notification.EXTRA_TITLE)}\n" +
"[Content]: ${nf?.notification?.extras?.getString(Notification.EXTRA_TEXT)}\n" +
"[App Name]: ${context.appNameOf(packageName = nf?.packageName ?: "")}\n" +
"[Package Name]: ${nf?.packageName}\n" +
"[Sender Package Name]: ${nf?.opPkg}\n" +
"[Custom Icon]: $isCustom\n" +
"[Grayscale Icon]: $isGrayscale\n" +
"[From System Push]: ${nf?.isOplusPush}\n" +
"[String]: ${nf?.notification}"
"[Title]: ${nf?.notification?.extras?.getString(Notification.EXTRA_TITLE)}\n" +
"[Content]: ${nf?.notification?.extras?.getString(Notification.EXTRA_TEXT)}\n" +
"[App Name]: ${context.appNameOf(packageName = nf?.packageName ?: "")}\n" +
"[Package Name]: ${nf?.packageName}\n" +
"[Sender Package Name]: ${nf?.opPkg}\n" +
"[Custom Icon]: $isCustom\n" +
"[Grayscale Icon]: $isGrayscale\n" +
"[From System Push]: ${nf?.isOplusPush}\n" +
"[String]: ${nf?.notification}"
)
}
@@ -673,28 +694,28 @@ object SystemUIHooker : YukiBaseHooker() {
afterHook {
IconBuilderClass.toClass().field { name = "context" }
.get(field { name = "iconBuilder" }.get(instance).cast()).cast<Context>()?.also { context ->
NotificationEntryClass.toClass().method {
name = "getSbn"
}.get(args().first().any()).invoke<StatusBarNotification>()?.also { nf ->
nf.notification.smallIcon.loadDrawable(context)?.also { iconDrawable ->
compatStatusIcon(
context = context,
nf = nf,
isGrayscaleIcon = isGrayscaleIcon(context, iconDrawable).also {
/** 缓存第一次的 APP 小图标 */
if (it.not()) context.appIconOf(nf.packageName)?.also { e -> appIcons[nf.packageName] = e }
},
packageName = nf.packageName,
drawable = iconDrawable
).also { pair ->
if (pair.second) StatusBarIconClass.toClass().field {
name = "icon"
type = IconClass
}.get(result).set(Icon.createWithBitmap(pair.first.toBitmap()))
}
NotificationEntryClass.toClass().method {
name = "getSbn"
}.get(args().first().any()).invoke<StatusBarNotification>()?.also { nf ->
nf.notification.smallIcon.loadDrawable(context)?.also { iconDrawable ->
compatStatusIcon(
context = context,
nf = nf,
isGrayscaleIcon = isGrayscaleIcon(context, iconDrawable).also {
/** 缓存第一次的 APP 小图标 */
if (it.not()) context.appIconOf(nf.packageName)?.also { e -> appIcons[nf.packageName] = e }
},
packageName = nf.packageName,
drawable = iconDrawable
).also { pair ->
if (pair.second) StatusBarIconClass.toClass().field {
name = "icon"
type = IconClass
}.get(result).set(Icon.createWithBitmap(pair.first.toBitmap()))
}
}
}
}
}
}
}
@@ -840,36 +861,36 @@ object SystemUIHooker : YukiBaseHooker() {
afterHook {
NotificationHeaderViewWrapperClass.toClass()
.field { name = "mIcon" }.get(instance).cast<ImageView>()?.apply {
ExpandableNotificationRowClass.toClass()
.method { name = "getEntry" }
.get(NotificationViewWrapperClass.toClass().field {
name = "mRow"
}.get(instance).any()).call()?.let {
it.javaClass.method {
name = "getSbn"
}.get(it).invoke<StatusBarNotification>()
}.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() }
}
ExpandableNotificationRowClass.toClass()
.method { name = "getEntry" }
.get(NotificationViewWrapperClass.toClass().field {
name = "mRow"
}.get(instance).any()).call()?.let {
it.javaClass.method {
name = "getSbn"
}.get(it).invoke<StatusBarNotification>()
}.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() }
}
}
}
}
}
}
}

View File

@@ -28,7 +28,11 @@ import android.content.Context
import android.graphics.Color
import com.fankes.coloros.notify.bean.IconDataBean
import com.fankes.coloros.notify.data.ConfigData
import com.fankes.coloros.notify.utils.factory.*
import com.fankes.coloros.notify.utils.factory.bitmap
import com.fankes.coloros.notify.utils.factory.safeOf
import com.fankes.coloros.notify.utils.factory.safeOfNan
import com.fankes.coloros.notify.utils.factory.safeOfNull
import com.fankes.coloros.notify.utils.factory.snake
import com.highcapable.yukihookapi.hook.factory.prefs
import com.highcapable.yukihookapi.hook.param.PackageParam
import org.json.JSONArray

View File

@@ -37,7 +37,16 @@ import com.fankes.coloros.notify.param.factory.isAppNotifyHookOf
import com.fankes.coloros.notify.param.factory.putAppNotifyHookAllOf
import com.fankes.coloros.notify.param.factory.putAppNotifyHookOf
import com.fankes.coloros.notify.ui.activity.base.BaseActivity
import com.fankes.coloros.notify.utils.factory.*
import com.fankes.coloros.notify.utils.factory.addOnBackPressedEvent
import com.fankes.coloros.notify.utils.factory.bindAdapter
import com.fankes.coloros.notify.utils.factory.callOnBackPressed
import com.fankes.coloros.notify.utils.factory.colorOf
import com.fankes.coloros.notify.utils.factory.copyToClipboard
import com.fankes.coloros.notify.utils.factory.navigate
import com.fankes.coloros.notify.utils.factory.openBrowser
import com.fankes.coloros.notify.utils.factory.showDialog
import com.fankes.coloros.notify.utils.factory.snake
import com.fankes.coloros.notify.utils.factory.toast
import com.fankes.coloros.notify.utils.tool.IconRuleManagerTool
import com.fankes.coloros.notify.utils.tool.SystemUITool
import com.highcapable.yukihookapi.YukiHookAPI
@@ -145,8 +154,8 @@ class ConfigureActivity : BaseActivity<ActivityConfigBinding>() {
if (b) showDialog {
title = "全部替换"
msg = "此功能仅针对严重不遵守规范的 APP 通知图标才需要开启例如APP 推送通知后无法识别出现的黑白块图标。\n\n" +
"此功能在一般情况下请保持关闭并跟随在线规则的配置,并不要随意改变此配置," +
"开启后 APP 的通知图标可能会被规则破坏,你确定还要开启吗?"
"此功能在一般情况下请保持关闭并跟随在线规则的配置,并不要随意改变此配置," +
"开启后 APP 的通知图标可能会被规则破坏,你确定还要开启吗?"
confirmButton { saveState() }
cancelButton { btn.isChecked = btn.isChecked.not() }
noCancelable()
@@ -188,10 +197,10 @@ class ConfigureActivity : BaseActivity<ActivityConfigBinding>() {
val pkgName = intent?.getStringExtra("pkgName") ?: ""
title = "新安装应用通知图标适配"
msg = "你已安装 $appName($pkgName)\n\n" +
"此应用未在通知优化名单中发现适配数据,若此应用发送的通知为彩色图标," +
"可随时点击本页面下方的“贡献通知图标优化名单”按钮提交贡献或请求适配。\n\n" +
"若你已知晓此应用会遵守原生通知图标规范,可忽略此提示。\n\n" +
"你可以现在立即同步适配列表,以获取最新的适配数据。"
"此应用未在通知优化名单中发现适配数据,若此应用发送的通知为彩色图标," +
"可随时点击本页面下方的“贡献通知图标优化名单”按钮提交贡献或请求适配。\n\n" +
"若你已知晓此应用会遵守原生通知图标规范,可忽略此提示。\n\n" +
"你可以现在立即同步适配列表,以获取最新的适配数据。"
confirmButton(text = "同步列表") { onStartRefresh() }
cancelButton(text = "复制名称+包名") { copyToClipboard(content = "$appName($pkgName)") }
neutralButton(text = "取消")
@@ -250,7 +259,7 @@ class ConfigureActivity : BaseActivity<ActivityConfigBinding>() {
onChanged?.invoke()
binding.configTitleCountText.text =
if (filterText.isBlank()) "已适配 ${iconDatas.size} 个 APP 的通知图标"
else "${filterText}” 匹配到 ${iconDatas.size} 个结果"
else "$filterText” 匹配到 ${iconDatas.size} 个结果"
binding.configListNoDataView.apply {
text = if (iconAllDatas.isEmpty()) "噫,竟然什么都没有~\n请点击右上角同步按钮获取云端数据" else "噫,竟然什么都没找到~"
isVisible = iconDatas.isEmpty()

View File

@@ -22,7 +22,11 @@
*/
package com.fankes.coloros.notify.utils.tool
import android.graphics.*
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Matrix
import android.graphics.Paint
import android.graphics.PorterDuff
import android.graphics.drawable.AnimationDrawable
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable

View File

@@ -27,12 +27,20 @@ import android.content.Context
import android.icu.text.SimpleDateFormat
import android.icu.util.Calendar
import android.icu.util.TimeZone
import com.fankes.coloros.notify.utils.factory.*
import okhttp3.*
import com.fankes.coloros.notify.utils.factory.isNetWorkSuccess
import com.fankes.coloros.notify.utils.factory.openBrowser
import com.fankes.coloros.notify.utils.factory.openSelfSetting
import com.fankes.coloros.notify.utils.factory.runInSafe
import com.fankes.coloros.notify.utils.factory.showDialog
import okhttp3.Call
import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.json.JSONObject
import java.io.IOException
import java.io.Serializable
import java.util.*
import java.util.Locale
/**
* 获取 GitHub Release 最新版本工具类
@@ -71,7 +79,7 @@ object GithubReleaseTool {
fun showUpdate() = context.showDialog {
title = "最新版本 $name"
msg = "发布于 $date\n\n" +
"更新日志\n\n" + content
"更新日志\n\n" + content
confirmButton(text = "更新") { context.openBrowser(htmlUrl) }
cancelButton()
}

View File

@@ -26,7 +26,7 @@ import android.content.Context
import com.fankes.coloros.notify.utils.factory.showDialog
import com.highcapable.yukihookapi.hook.factory.prefs
import com.highcapable.yukihookapi.hook.xposed.prefs.data.PrefsData
import java.util.*
import java.util.Locale
/**
* I18n 适配警告提示工具类
@@ -46,8 +46,8 @@ object I18nWarnTool {
context.showDialog {
title = "Notice of I18n Support"
msg = "This Xposed Module is only for Chinese and the Chinese region.\n\n" +
"Currently, there will be no internationalization adaptation.\n\n" +
"There may be plans for internationalization adaptation in the future, so stay tuned."
"Currently, there will be no internationalization adaptation.\n\n" +
"There may be plans for internationalization adaptation in the future, so stay tuned."
confirmButton(text = "Got It") { saveReaded() }
noCancelable()
}

View File

@@ -20,7 +20,7 @@
*
* This file is Created by fankes on 2022/2/25.
*/
@file:Suppress("TrustAllX509TrustManager", "CustomX509TrustManager", "DEPRECATION", "IMPLICIT_CAST_TO_ANY")
@file:Suppress("TrustAllX509TrustManager", "CustomX509TrustManager", "IMPLICIT_CAST_TO_ANY")
package com.fankes.coloros.notify.utils.tool
@@ -45,13 +45,25 @@ import com.fankes.coloros.notify.databinding.DiaSourceFromBinding
import com.fankes.coloros.notify.databinding.DiaSourceFromStringBinding
import com.fankes.coloros.notify.param.IconPackParams
import com.fankes.coloros.notify.ui.activity.ConfigureActivity
import com.fankes.coloros.notify.utils.factory.*
import com.fankes.coloros.notify.utils.factory.delayedRun
import com.fankes.coloros.notify.utils.factory.openBrowser
import com.fankes.coloros.notify.utils.factory.safeOfNull
import com.fankes.coloros.notify.utils.factory.showDialog
import com.fankes.coloros.notify.utils.factory.snake
import com.highcapable.yukihookapi.hook.log.loggerD
import okhttp3.*
import okhttp3.Call
import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import java.io.IOException
import java.security.SecureRandom
import java.security.cert.X509Certificate
import javax.net.ssl.*
import javax.net.ssl.HostnameVerifier
import javax.net.ssl.SSLContext
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager
/**
* 通知图标在线规则管理类

View File

@@ -30,7 +30,11 @@ import androidx.appcompat.app.AppCompatActivity
import com.fankes.coloros.notify.const.PackageName
import com.fankes.coloros.notify.data.ConfigData
import com.fankes.coloros.notify.ui.activity.MainActivity
import com.fankes.coloros.notify.utils.factory.*
import com.fankes.coloros.notify.utils.factory.colorOSFullVersion
import com.fankes.coloros.notify.utils.factory.delayedRun
import com.fankes.coloros.notify.utils.factory.execShell
import com.fankes.coloros.notify.utils.factory.showDialog
import com.fankes.coloros.notify.utils.factory.snake
import com.google.android.material.snackbar.Snackbar
import com.highcapable.yukihookapi.YukiHookAPI
import com.highcapable.yukihookapi.hook.factory.dataChannel
@@ -38,7 +42,7 @@ import com.highcapable.yukihookapi.hook.log.YukiHookLogger
import com.highcapable.yukihookapi.hook.log.YukiLoggerData
import com.highcapable.yukihookapi.hook.param.PackageParam
import com.highcapable.yukihookapi.hook.xposed.channel.data.ChannelData
import java.util.*
import java.util.Locale
/**
* 系统界面工具
@@ -86,17 +90,17 @@ object SystemUITool {
runCatching {
result?.let { e ->
val content = "" +
"================================================================\n" +
" Generated by ColorOSNotifyIcon\n" +
" Project Url: https://github.com/fankes/ColorOSNotifyIcon\n" +
"================================================================\n\n" +
"[Device Brand]: ${Build.BRAND}\n" +
"[Device Model]: ${Build.MODEL}\n" +
"[Display]: ${Build.DISPLAY}\n" +
"[Android Version]: ${Build.VERSION.RELEASE}\n" +
"[Android API Level]: ${Build.VERSION.SDK_INT}\n" +
"[ColorOS Version]: $colorOSFullVersion\n" +
"[System Locale]: ${Locale.getDefault()}\n\n" + YukiHookLogger.contents(debugLogs).trim()
"================================================================\n" +
" Generated by ColorOSNotifyIcon\n" +
" Project Url: https://github.com/fankes/ColorOSNotifyIcon\n" +
"================================================================\n\n" +
"[Device Brand]: ${Build.BRAND}\n" +
"[Device Model]: ${Build.MODEL}\n" +
"[Display]: ${Build.DISPLAY}\n" +
"[Android Version]: ${Build.VERSION.RELEASE}\n" +
"[Android API Level]: ${Build.VERSION.SDK_INT}\n" +
"[ColorOS Version]: $colorOSFullVersion\n" +
"[System Locale]: ${Locale.getDefault()}\n\n" + YukiHookLogger.contents(debugLogs).trim()
activity.contentResolver?.openOutputStream(e)?.apply { write(content.toByteArray()) }?.close()
activity.snake(msg = "导出完成")
} ?: activity.snake(msg = "已取消操作")
@@ -123,9 +127,9 @@ object SystemUITool {
context.showDialog {
title = "导出全部调试日志"
msg = "调试日志中会包含当前系统推送的全部通知内容,其中可能包含你的个人隐私," +
"你可以在导出后的日志文件中选择将这些敏感信息模糊化处理再进行共享," +
"开发者使用并查看你导出的调试日志仅为排查与修复问题,并且在之后会及时销毁这些日志。\n\n" +
"继续导出即代表你已阅读并知悉上述内容。"
"你可以在导出后的日志文件中选择将这些敏感信息模糊化处理再进行共享," +
"开发者使用并查看你导出的调试日志仅为排查与修复问题,并且在之后会及时销毁这些日志。\n\n" +
"继续导出即代表你已阅读并知悉上述内容。"
confirmButton(text = "继续") { doExport() }
cancelButton()
}
@@ -145,15 +149,15 @@ object SystemUITool {
context.showDialog {
title = "获取 Root 权限失败"
msg = "当前无法获取 Root 权限,请确认你的设备已经被 Root 且同意授予 Root 权限。\n" +
"如果你正在使用 Magisk 并安装了 Shamiko 模块," +
"请确认当前是否正处于白名单模式。 (白名单模式将导致无法申请 Root 权限)"
"如果你正在使用 Magisk 并安装了 Shamiko 模块," +
"请确认当前是否正处于白名单模式。 (白名单模式将导致无法申请 Root 权限)"
confirmButton(text = "我知道了")
}
context.showDialog {
title = "重启系统界面"
msg = "你确定要立即重启系统界面吗?\n\n" +
"重启过程会黑屏并等待进入锁屏重新解锁。" + (if (isDynamicAvailable)
"\n\n你也可以选择“立即生效”来动态刷新系统界面并生效当前模块设置。" else "")
"重启过程会黑屏并等待进入锁屏重新解锁。" + (if (isDynamicAvailable)
"\n\n你也可以选择“立即生效”来动态刷新系统界面并生效当前模块设置。" else "")
confirmButton {
execShell(cmd = "pgrep systemui").also { pid ->
if (pid.isNotBlank())