From 70c2f9aa8fcf8f4d479b453f740dda4b8f6edcd3 Mon Sep 17 00:00:00 2001 From: fankesyooni Date: Sun, 5 Feb 2023 04:51:35 +0800 Subject: [PATCH] Modify change module debug logs record method and optimize some code in HookEntry, SystemUIHooker, SystemUITool, MainActivity, activity_main --- .../fankes/coloros/notify/hook/HookEntry.kt | 6 +- .../notify/hook/entity/SystemUIHooker.kt | 35 +++++---- .../notify/ui/activity/MainActivity.kt | 11 ++- .../coloros/notify/utils/tool/SystemUITool.kt | 72 +++++++++++++++++-- app/src/main/res/layout/activity_main.xml | 27 ++++++- 5 files changed, 127 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/com/fankes/coloros/notify/hook/HookEntry.kt b/app/src/main/java/com/fankes/coloros/notify/hook/HookEntry.kt index c381852..1f0cd57 100644 --- a/app/src/main/java/com/fankes/coloros/notify/hook/HookEntry.kt +++ b/app/src/main/java/com/fankes/coloros/notify/hook/HookEntry.kt @@ -36,7 +36,11 @@ import com.highcapable.yukihookapi.hook.xposed.proxy.IYukiHookXposedInit object HookEntry : IYukiHookXposedInit { override fun onInit() = configs { - debugLog { tag = "ColorOSNotifyIcon" } + debugLog { + tag = "ColorOSNotifyIcon" + isRecord = true + elements(PRIORITY) + } isDebug = false } 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 810af6f..dabacbc 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 @@ -24,6 +24,7 @@ package com.fankes.coloros.notify.hook.entity +import android.app.Notification import android.app.WallpaperManager import android.content.Context import android.content.Intent @@ -223,21 +224,22 @@ object SystemUIHooker : YukiBaseHooker() { * 打印日志 * @param tag 标识 * @param context 实例 - * @param packageName APP 包名 + * @param nf 通知实例 * @param isCustom 是否为通知优化生效图标 * @param isGrayscale 是否为灰度图标 */ - private fun printLogcat( - tag: String, - context: Context, - packageName: String, - isCustom: Boolean, - isGrayscale: Boolean - ) { + private fun loggerDebug(tag: String, context: Context, nf: StatusBarNotification?, isCustom: Boolean, isGrayscale: Boolean) { if (ConfigData.isEnableModuleLog) loggerD( - msg = "$tag --> [${context.appNameOf(packageName)}][$packageName] " + - "custom [$isCustom] " + - "grayscale [$isGrayscale]" + 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}" ) } @@ -388,10 +390,11 @@ object SystemUIHooker : YukiBaseHooker() { isGrayscaleIcon: Boolean, packageName: String, drawable: Drawable - ) = compatCustomIcon(context, isGrayscaleIcon, packageName).first.also { + ) = compatCustomIcon(context, isGrayscaleIcon, packageName).let { /** 打印日志 */ - printLogcat(tag = "StatusIcon", context, packageName, isCustom = it != null, isGrayscaleIcon) - }?.let { Pair(it, true) } ?: Pair(if (isGrayscaleIcon) drawable else nf.compatPushingIcon(drawable), isGrayscaleIcon.not()) + loggerDebug(tag = "Status Bar Icon", context, nf, isCustom = it.first != null && it.third.not(), isGrayscaleIcon) + it.first?.let { e -> Pair(e, true) } ?: Pair(if (isGrayscaleIcon) drawable else nf.compatPushingIcon(drawable), isGrayscaleIcon.not()) + } /** * 自动适配通知栏小图标 @@ -474,8 +477,10 @@ object SystemUIHooker : YukiBaseHooker() { setDefaultNotifyIconViewStyle() } } + /** 是否为通知优化生效图标 */ + val isCustom = customTriple.first != null && customTriple.third.not() /** 打印日志 */ - printLogcat(tag = "NotifyIcon", iconView.context, packageName, isCustom = customTriple.first != null, isGrayscaleIcon) + loggerDebug(tag = "Notification Panel Icon", iconView.context, nf, isCustom = isCustom, isGrayscaleIcon) } } diff --git a/app/src/main/java/com/fankes/coloros/notify/ui/activity/MainActivity.kt b/app/src/main/java/com/fankes/coloros/notify/ui/activity/MainActivity.kt index 84d479e..1e164d0 100644 --- a/app/src/main/java/com/fankes/coloros/notify/ui/activity/MainActivity.kt +++ b/app/src/main/java/com/fankes/coloros/notify/ui/activity/MainActivity.kt @@ -128,6 +128,7 @@ class MainActivity : BaseActivity() { binding.moduleEnableSwitch.bind(ConfigData.ENABLE_MODULE) { onInitialize { binding.moduleEnableLogSwitch.isVisible = it + binding.expAllDebugLogButton.isVisible = it && ConfigData.isEnableModuleLog binding.notifyIconConfigItem.isVisible = it binding.devNotifyConfigItem.isVisible = it binding.notifyStyleConfigItem.isVisible = it @@ -139,7 +140,11 @@ class MainActivity : BaseActivity() { } } binding.moduleEnableLogSwitch.bind(ConfigData.ENABLE_MODULE_LOG) { - onChanged { SystemUITool.showNeedRestartSnake(context = this@MainActivity) } + onInitialize { binding.expAllDebugLogButton.isVisible = it && ConfigData.isEnableModule } + onChanged { + reinitialize() + SystemUITool.refreshSystemUI(context = this@MainActivity, isRefreshCacheOnly = true) + } } binding.devNotifyConfigSwitch.bind(ConfigData.ENABLE_REMOVE_DEV_NOTIFY) { onChanged { SystemUITool.refreshSystemUI(context = this@MainActivity, isRefreshCacheOnly = true) } @@ -258,6 +263,8 @@ class MainActivity : BaseActivity() { binding.notifyIconCustomCornerSeekbar.bind(ConfigData.NOTIFY_ICON_CORNER_SIZE, binding.notifyIconCustomCornerText, suffix = " dp") { SystemUITool.refreshSystemUI(context = this) } + /** 导出全部日志按钮点击事件 */ + binding.expAllDebugLogButton.setOnClickListener { SystemUITool.obtainAndExportDebugLogs(context = this) } /** 通知图标优化名单按钮点击事件 */ binding.notifyIconFixButton.setOnClickListener { navigate() } /** 自动更新在线规则修改时间按钮点击事件 */ @@ -295,6 +302,8 @@ class MainActivity : BaseActivity() { if (btn.isPressed.not()) return@setOnCheckedChangeListener hideOrShowLauncherIcon(b) } + /** 注册导出调试日志启动器 */ + SystemUITool.registerExportDebugLogsLauncher(activity = this) } /** 刷新模块状态 */ diff --git a/app/src/main/java/com/fankes/coloros/notify/utils/tool/SystemUITool.kt b/app/src/main/java/com/fankes/coloros/notify/utils/tool/SystemUITool.kt index 893b8b9..623e0ff 100644 --- a/app/src/main/java/com/fankes/coloros/notify/utils/tool/SystemUITool.kt +++ b/app/src/main/java/com/fankes/coloros/notify/utils/tool/SystemUITool.kt @@ -23,19 +23,22 @@ package com.fankes.coloros.notify.utils.tool import android.content.Context +import android.os.Build +import androidx.activity.result.ActivityResultLauncher +import androidx.activity.result.contract.ActivityResultContracts 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.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.fankes.coloros.notify.utils.factory.* import com.google.android.material.snackbar.Snackbar import com.highcapable.yukihookapi.YukiHookAPI import com.highcapable.yukihookapi.hook.factory.dataChannel +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.* /** * 系统界面工具 @@ -45,6 +48,12 @@ object SystemUITool { private val CALL_HOST_REFRESH_CACHING = ChannelData("call_host_refresh_caching", false) private val CALL_MODULE_REFRESH_RESULT = ChannelData("call_module_refresh_result", false) + /** 当前全部调试日志 */ + private var debugLogs = ArrayList() + + /** 当前启动器实例 */ + private var launcher: ActivityResultLauncher? = null + /** * 宿主注册监听 */ @@ -68,6 +77,61 @@ object SystemUITool { fun checkingActivated(context: Context, result: (Boolean) -> Unit) = context.dataChannel(PackageName.SYSTEMUI).checkingVersionEquals(result = result) + /** + * 注册导出调试日志启动器到 [AppCompatActivity] + * @param activity 实例 + */ + fun registerExportDebugLogsLauncher(activity: AppCompatActivity) { + launcher = activity.registerForActivityResult(ActivityResultContracts.CreateDocument("*/application")) { result -> + 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() + activity.contentResolver?.openOutputStream(e)?.apply { write(content.toByteArray()) }?.close() + activity.snake(msg = "导出完成") + } ?: activity.snake(msg = "已取消操作") + }.onFailure { activity.snake(msg = "导出过程发生错误") } + } + } + + /** + * 获取并导出全部调试日志 + * @param context 实例 + */ + fun obtainAndExportDebugLogs(context: Context) { + /** 执行导出操作 */ + fun doExport() { + context.dataChannel(PackageName.SYSTEMUI).obtainLoggerInMemoryData { + if (it.isNotEmpty()) { + debugLogs = it + runCatching { launcher?.launch("coloros_notification_icons_processing_logs.log") } + .onFailure { context.snake(msg = "启动系统文件选择器失败") } + } else context.snake(msg = "暂无调试日志") + } + } + if (YukiHookAPI.Status.isXposedModuleActive) + context.showDialog { + title = "导出全部调试日志" + msg = "调试日志中会包含当前系统推送的全部通知内容,其中可能包含你的个人隐私," + + "你可以在导出后的日志文件中选择将这些敏感信息模糊化处理再进行共享," + + "开发者使用并查看你导出的调试日志仅为排查与修复问题,并且在之后会及时销毁这些日志。\n\n" + + "继续导出即代表你已阅读并知悉上述内容。" + confirmButton(text = "继续") { doExport() } + cancelButton() + } + else context.snake(msg = "模块没有激活,请先激活模块") + } + /** * 重启系统界面 * @param context 实例 diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 22a5ad3..13e12d2 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -211,13 +211,13 @@ android:elevation="0dp" android:gravity="center" android:orientation="vertical" - android:paddingLeft="15dp" - android:paddingTop="15dp" - android:paddingRight="15dp"> + android:paddingTop="15dp"> @@ -259,14 +261,33 @@ android:id="@+id/module_enable_log_switch" android:layout_width="match_parent" android:layout_height="35dp" + android:layout_marginLeft="15dp" + android:layout_marginRight="15dp" android:layout_marginBottom="5dp" android:text="启用调试日志" android:textColor="@color/colorTextGray" android:textSize="15sp" /> + +