From 1862faf637be7a74fd6a970c878fb4776a18f3af Mon Sep 17 00:00:00 2001 From: fankesyooni Date: Sun, 2 Oct 2022 00:25:16 +0800 Subject: [PATCH] Modify merge DataConst to ConfigData and move DataFactory to data/factory --- .../application/AppErrorsApplication.kt | 3 + .../apperrorstracking/data/ConfigData.kt | 156 ++++++++++++++++++ .../apperrorstracking/data/DataConst.kt | 34 ---- .../{hook => data}/factory/DataFactory.kt | 2 +- .../apperrorstracking/hook/HookEntry.kt | 2 + .../hook/entity/FrameworkHooker.kt | 24 ++- .../ui/activity/main/ConfigureActivity.kt | 2 +- .../ui/activity/main/MainActivity.kt | 34 +--- 8 files changed, 182 insertions(+), 75 deletions(-) create mode 100644 app/src/main/java/com/fankes/apperrorstracking/data/ConfigData.kt delete mode 100644 app/src/main/java/com/fankes/apperrorstracking/data/DataConst.kt rename app/src/main/java/com/fankes/apperrorstracking/{hook => data}/factory/DataFactory.kt (98%) diff --git a/app/src/main/java/com/fankes/apperrorstracking/application/AppErrorsApplication.kt b/app/src/main/java/com/fankes/apperrorstracking/application/AppErrorsApplication.kt index ab07144..f92c773 100644 --- a/app/src/main/java/com/fankes/apperrorstracking/application/AppErrorsApplication.kt +++ b/app/src/main/java/com/fankes/apperrorstracking/application/AppErrorsApplication.kt @@ -22,6 +22,7 @@ package com.fankes.apperrorstracking.application import androidx.appcompat.app.AppCompatDelegate +import com.fankes.apperrorstracking.data.ConfigData import com.fankes.apperrorstracking.locale.LocaleString import com.highcapable.yukihookapi.hook.xposed.application.ModuleApplication @@ -33,5 +34,7 @@ class AppErrorsApplication : ModuleApplication() { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) /** 绑定 I18n */ LocaleString.bind(instance = this) + /** 装载存储控制类 */ + ConfigData.init(instance = this) } } \ No newline at end of file diff --git a/app/src/main/java/com/fankes/apperrorstracking/data/ConfigData.kt b/app/src/main/java/com/fankes/apperrorstracking/data/ConfigData.kt new file mode 100644 index 0000000..52b196b --- /dev/null +++ b/app/src/main/java/com/fankes/apperrorstracking/data/ConfigData.kt @@ -0,0 +1,156 @@ +/* + * AppErrorsTracking - Added more features to app's crash dialog, fixed custom rom deleted dialog, the best experience to Android developer. + * Copyright (C) 2019-2022 Fankes Studio(qzmmcn@163.com) + * https://github.com/KitsunePie/AppErrorsTracking + * + * This software is non-free but opensource software: you can redistribute it + * and/or modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * and eula along with this software. If not, see + * + * + * This file is Created by fankes on 2022/10/1. + */ +@file:Suppress("MemberVisibilityCanBePrivate") + +package com.fankes.apperrorstracking.data + +import android.content.Context +import android.widget.CompoundButton +import com.highcapable.yukihookapi.hook.factory.modulePrefs +import com.highcapable.yukihookapi.hook.log.loggerW +import com.highcapable.yukihookapi.hook.param.PackageParam +import com.highcapable.yukihookapi.hook.xposed.prefs.data.PrefsData + +/** + * 全局配置存储控制类 + */ +object ConfigData { + + /** 显示开发者提示 */ + val SHOW_DEVELOPER_NOTICE = PrefsData("_show_developer_notice", true) + + /** 仅对前台应用显示错误对话框 */ + val ENABLE_ONLY_SHOW_ERRORS_IN_FRONT = PrefsData("_enable_only_show_errors_in_front", false) + + /** 仅对应用主进程显示错误对话框 */ + val ENABLE_ONLY_SHOW_ERRORS_IN_MAIN = PrefsData("_enable_only_show_errors_in_main", false) + + /** 错误对话框始终显示“重新打开”选项 */ + val ENABLE_ALWAYS_SHOWS_REOPEN_APP_OPTIONS = PrefsData("_enable_always_shows_reopen_app_options", false) + + /** 启用应用配置模板 */ + val ENABLE_APP_CONFIG_TEMPLATE = PrefsData("_enable_app_config_template", false) + + /** 当前实例 - [Context] or [PackageParam] */ + private var instance: Any? = null + + /** + * 初始化存储控制类 + * @param instance 实例 - 只能是 [Context] or [PackageParam] + * @throws IllegalStateException 如果类型错误 + */ + fun init(instance: Any) { + when (instance) { + is Context, is PackageParam -> this.instance = instance + else -> error("Unknown type for init ConfigData") + } + } + + /** + * 读取 [Boolean] 数据 + * @param data 键值数据模板 + * @return [Boolean] + */ + private fun getBoolean(data: PrefsData) = when (instance) { + is Context -> (instance as Context).modulePrefs.get(data) + is PackageParam -> (instance as PackageParam).prefs.get(data) + else -> error("Unknown type for get prefs data") + } + + /** + * 存入 [Boolean] 数据 + * @param data 键值数据模板 + * @param value 键值内容 + */ + private fun putBoolean(data: PrefsData, value: Boolean) { + when (instance) { + is Context -> (instance as Context).modulePrefs.put(data, value) + is PackageParam -> loggerW(msg = "Not support for this method") + else -> error("Unknown type for put prefs data") + } + } + + /** + * 绑定到 [CompoundButton] 自动设置选中状态 + * @param data 键值数据模板 + * @param onChange 当改变时回调 + */ + fun CompoundButton.bind(data: PrefsData, onChange: (Boolean) -> Unit = {}) { + isChecked = getBoolean(data).also(onChange) + setOnCheckedChangeListener { button, isChecked -> + if (button.isPressed) { + putBoolean(data, isChecked) + onChange(isChecked) + } + } + } + + /** + * 是否显示开发者提示 + * @return [Boolean] + */ + var isShowDeveloperNotice + get() = getBoolean(SHOW_DEVELOPER_NOTICE) + set(value) { + putBoolean(SHOW_DEVELOPER_NOTICE, value) + } + + /** + * 仅对前台应用显示错误对话框 + * @return [Boolean] + */ + var isEnableOnlyShowErrorsInFront + get() = getBoolean(ENABLE_ONLY_SHOW_ERRORS_IN_FRONT) + set(value) { + putBoolean(ENABLE_ONLY_SHOW_ERRORS_IN_FRONT, value) + } + + /** + * 仅对应用主进程显示错误对话框 + * @return [Boolean] + */ + var isEnableOnlyShowErrorsInMain + get() = getBoolean(ENABLE_ONLY_SHOW_ERRORS_IN_MAIN) + set(value) { + putBoolean(ENABLE_ONLY_SHOW_ERRORS_IN_MAIN, value) + } + + /** + * 错误对话框始终显示“重新打开”选项 + * @return [Boolean] + */ + var isEnableAlwaysShowsReopenAppOptions + get() = getBoolean(ENABLE_ALWAYS_SHOWS_REOPEN_APP_OPTIONS) + set(value) { + putBoolean(ENABLE_ALWAYS_SHOWS_REOPEN_APP_OPTIONS, value) + } + + /** + * 启用应用配置模板 + * @return [Boolean] + */ + var isEnableAppConfigTemplate + get() = getBoolean(ENABLE_APP_CONFIG_TEMPLATE) + set(value) { + putBoolean(ENABLE_APP_CONFIG_TEMPLATE, value) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/fankes/apperrorstracking/data/DataConst.kt b/app/src/main/java/com/fankes/apperrorstracking/data/DataConst.kt deleted file mode 100644 index e4d5c9d..0000000 --- a/app/src/main/java/com/fankes/apperrorstracking/data/DataConst.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * AppErrorsTracking - Added more features to app's crash dialog, fixed custom rom deleted dialog, the best experience to Android developer. - * Copyright (C) 2019-2022 Fankes Studio(qzmmcn@163.com) - * https://github.com/KitsunePie/AppErrorsTracking - * - * This software is non-free but opensource software: you can redistribute it - * and/or modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * and eula along with this software. If not, see - * - * - * This file is Created by fankes on 2022/5/14. - */ -package com.fankes.apperrorstracking.data - -import com.highcapable.yukihookapi.hook.xposed.prefs.data.PrefsData - -object DataConst { - - val SHOW_DEVELOPER_NOTICE = PrefsData("_show_developer_notice", true) - - val ENABLE_ONLY_SHOW_ERRORS_IN_FRONT = PrefsData("_enable_only_show_errors_in_front", false) - val ENABLE_ONLY_SHOW_ERRORS_IN_MAIN = PrefsData("_enable_only_show_errors_in_main", false) - val ENABLE_ALWAYS_SHOWS_REOPEN_APP_OPTIONS = PrefsData("_enable_always_shows_reopen_app_options", false) - val ENABLE_APP_CONFIG_TEMPLATE = PrefsData("_enable_app_config_template", false) -} \ No newline at end of file diff --git a/app/src/main/java/com/fankes/apperrorstracking/hook/factory/DataFactory.kt b/app/src/main/java/com/fankes/apperrorstracking/data/factory/DataFactory.kt similarity index 98% rename from app/src/main/java/com/fankes/apperrorstracking/hook/factory/DataFactory.kt rename to app/src/main/java/com/fankes/apperrorstracking/data/factory/DataFactory.kt index c5b1310..4a5e147 100644 --- a/app/src/main/java/com/fankes/apperrorstracking/hook/factory/DataFactory.kt +++ b/app/src/main/java/com/fankes/apperrorstracking/data/factory/DataFactory.kt @@ -21,7 +21,7 @@ */ @file:Suppress("unused") -package com.fankes.apperrorstracking.hook.factory +package com.fankes.apperrorstracking.data.factory import android.content.Context import com.highcapable.yukihookapi.hook.factory.modulePrefs diff --git a/app/src/main/java/com/fankes/apperrorstracking/hook/HookEntry.kt b/app/src/main/java/com/fankes/apperrorstracking/hook/HookEntry.kt index 4b0468b..85e0e20 100644 --- a/app/src/main/java/com/fankes/apperrorstracking/hook/HookEntry.kt +++ b/app/src/main/java/com/fankes/apperrorstracking/hook/HookEntry.kt @@ -21,6 +21,7 @@ */ package com.fankes.apperrorstracking.hook +import com.fankes.apperrorstracking.data.ConfigData import com.fankes.apperrorstracking.hook.entity.FrameworkHooker import com.fankes.apperrorstracking.locale.LocaleString import com.highcapable.yukihookapi.annotation.xposed.InjectYukiHookWithXposed @@ -40,6 +41,7 @@ class HookEntry : IYukiHookXposedInit { override fun onHook() = encase { loadSystem { LocaleString.bind(instance = this) + ConfigData.init(instance = this) loadHooker(FrameworkHooker) } } diff --git a/app/src/main/java/com/fankes/apperrorstracking/hook/entity/FrameworkHooker.kt b/app/src/main/java/com/fankes/apperrorstracking/hook/entity/FrameworkHooker.kt index 792b511..dbb207b 100644 --- a/app/src/main/java/com/fankes/apperrorstracking/hook/entity/FrameworkHooker.kt +++ b/app/src/main/java/com/fankes/apperrorstracking/hook/entity/FrameworkHooker.kt @@ -37,10 +37,10 @@ import com.fankes.apperrorstracking.bean.AppErrorsDisplayBean import com.fankes.apperrorstracking.bean.AppErrorsInfoBean import com.fankes.apperrorstracking.bean.AppInfoBean import com.fankes.apperrorstracking.bean.MutedErrorsAppBean -import com.fankes.apperrorstracking.data.DataConst -import com.fankes.apperrorstracking.hook.factory.isAppShowErrorsNotify -import com.fankes.apperrorstracking.hook.factory.isAppShowErrorsToast -import com.fankes.apperrorstracking.hook.factory.isAppShowNothing +import com.fankes.apperrorstracking.data.ConfigData +import com.fankes.apperrorstracking.data.factory.isAppShowErrorsNotify +import com.fankes.apperrorstracking.data.factory.isAppShowErrorsToast +import com.fankes.apperrorstracking.data.factory.isAppShowNothing import com.fankes.apperrorstracking.locale.LocaleString import com.fankes.apperrorstracking.ui.activity.errors.AppErrorsDisplayActivity import com.fankes.apperrorstracking.ui.activity.errors.AppErrorsRecordActivity @@ -238,9 +238,6 @@ object FrameworkHooker : YukiBaseHooker() { /** 崩溃标题 */ val errorTitle = if (isRepeating) LocaleString.aerrRepeatedTitle(appName) else LocaleString.aerrTitle(appName) - - /** 是否始终显示重新打开按钮 */ - val isAlwaysShowsReopenApp = prefs.get(DataConst.ENABLE_ALWAYS_SHOWS_REOPEN_APP_OPTIONS) /** 打印错误日志 */ if (isApp) loggerE( msg = "App \"$packageName\"${if (packageName != processName) " --process \"$processName\"" else ""}" + @@ -254,7 +251,7 @@ object FrameworkHooker : YukiBaseHooker() { /** 判断是否为已忽略的 APP */ if (mutedErrorsIfUnlockApps.contains(packageName) || mutedErrorsIfRestartApps.contains(packageName)) return@afterHook /** 判断配置模块启用状态 */ - if (prefs.get(DataConst.ENABLE_APP_CONFIG_TEMPLATE)) { + if (ConfigData.isEnableAppConfigTemplate) { if (isAppShowNothing(packageName)) return@afterHook if (isAppShowErrorsNotify(packageName)) { context.pushNotify( @@ -274,11 +271,10 @@ object FrameworkHooker : YukiBaseHooker() { } } /** 判断是否为后台进程 */ - if ((isBackgroundProcess || context.isAppCanOpened(packageName).not()) - && prefs.get(DataConst.ENABLE_ONLY_SHOW_ERRORS_IN_FRONT) - ) return@afterHook + if ((isBackgroundProcess || context.isAppCanOpened(packageName).not()) && ConfigData.isEnableOnlyShowErrorsInFront) + return@afterHook /** 判断是否为主进程 */ - if (isMainProcess.not() && prefs.get(DataConst.ENABLE_ONLY_SHOW_ERRORS_IN_MAIN)) return@afterHook + if (isMainProcess.not() && ConfigData.isEnableOnlyShowErrorsInMain) return@afterHook /** 启动错误对话框显示窗口 */ AppErrorsDisplayActivity.start( context, AppErrorsDisplayBean( @@ -287,7 +283,7 @@ object FrameworkHooker : YukiBaseHooker() { appName = appName, title = errorTitle, isShowAppInfoButton = isApp, - isShowReopenButton = isApp && (isRepeating.not() || isAlwaysShowsReopenApp) + isShowReopenButton = isApp && (isRepeating.not() || ConfigData.isEnableAlwaysShowsReopenAppOptions) && context.isAppCanOpened(packageName) && isMainProcess, isShowCloseAppButton = isApp ) @@ -308,4 +304,4 @@ object FrameworkHooker : YukiBaseHooker() { } } } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/fankes/apperrorstracking/ui/activity/main/ConfigureActivity.kt b/app/src/main/java/com/fankes/apperrorstracking/ui/activity/main/ConfigureActivity.kt index 3615afa..94890cd 100644 --- a/app/src/main/java/com/fankes/apperrorstracking/ui/activity/main/ConfigureActivity.kt +++ b/app/src/main/java/com/fankes/apperrorstracking/ui/activity/main/ConfigureActivity.kt @@ -24,11 +24,11 @@ package com.fankes.apperrorstracking.ui.activity.main import androidx.core.view.isVisible import com.fankes.apperrorstracking.bean.AppFiltersBean import com.fankes.apperrorstracking.bean.AppInfoBean +import com.fankes.apperrorstracking.data.factory.* import com.fankes.apperrorstracking.databinding.ActivityConfigBinding import com.fankes.apperrorstracking.databinding.AdapterAppInfoBinding import com.fankes.apperrorstracking.databinding.DiaAppConfigBinding import com.fankes.apperrorstracking.databinding.DiaAppsFilterBinding -import com.fankes.apperrorstracking.hook.factory.* import com.fankes.apperrorstracking.locale.LocaleString import com.fankes.apperrorstracking.ui.activity.base.BaseActivity import com.fankes.apperrorstracking.utils.factory.appIconOf diff --git a/app/src/main/java/com/fankes/apperrorstracking/ui/activity/main/MainActivity.kt b/app/src/main/java/com/fankes/apperrorstracking/ui/activity/main/MainActivity.kt index f64ea6f..a78e42f 100644 --- a/app/src/main/java/com/fankes/apperrorstracking/ui/activity/main/MainActivity.kt +++ b/app/src/main/java/com/fankes/apperrorstracking/ui/activity/main/MainActivity.kt @@ -27,7 +27,8 @@ import android.os.Build import androidx.core.view.isVisible import com.fankes.apperrorstracking.BuildConfig import com.fankes.apperrorstracking.R -import com.fankes.apperrorstracking.data.DataConst +import com.fankes.apperrorstracking.data.ConfigData +import com.fankes.apperrorstracking.data.ConfigData.bind import com.fankes.apperrorstracking.databinding.ActivityMainBinding import com.fankes.apperrorstracking.locale.LocaleString import com.fankes.apperrorstracking.ui.activity.base.BaseActivity @@ -36,7 +37,6 @@ import com.fankes.apperrorstracking.ui.activity.errors.AppErrorsRecordActivity import com.fankes.apperrorstracking.utils.factory.* import com.fankes.apperrorstracking.utils.tool.FrameworkTool import com.highcapable.yukihookapi.YukiHookAPI -import com.highcapable.yukihookapi.hook.factory.modulePrefs class MainActivity : BaseActivity() { @@ -50,27 +50,11 @@ class MainActivity : BaseActivity() { binding.mainTextVersion.text = LocaleString.moduleVersion(BuildConfig.VERSION_NAME) binding.mainTextSystemVersion.text = LocaleString.systemVersion("${Build.VERSION.RELEASE} (API ${Build.VERSION.SDK_INT}) ${Build.DISPLAY}") - binding.onlyShowErrorsInFrontSwitch.isChecked = modulePrefs.get(DataConst.ENABLE_ONLY_SHOW_ERRORS_IN_FRONT) - binding.onlyShowErrorsInMainProcessSwitch.isChecked = modulePrefs.get(DataConst.ENABLE_ONLY_SHOW_ERRORS_IN_MAIN) - binding.alwaysShowsReopenAppOptionsSwitch.isChecked = modulePrefs.get(DataConst.ENABLE_ALWAYS_SHOWS_REOPEN_APP_OPTIONS) - binding.enableAppsConfigsTemplateSwitch.isChecked = modulePrefs.get(DataConst.ENABLE_APP_CONFIG_TEMPLATE) - binding.mgrAppsConfigsTemplateButton.isVisible = modulePrefs.get(DataConst.ENABLE_APP_CONFIG_TEMPLATE) - binding.onlyShowErrorsInFrontSwitch.setOnCheckedChangeListener { btn, b -> - if (btn.isPressed.not()) return@setOnCheckedChangeListener - modulePrefs.put(DataConst.ENABLE_ONLY_SHOW_ERRORS_IN_FRONT, b) - } - binding.onlyShowErrorsInMainProcessSwitch.setOnCheckedChangeListener { btn, b -> - if (btn.isPressed.not()) return@setOnCheckedChangeListener - modulePrefs.put(DataConst.ENABLE_ONLY_SHOW_ERRORS_IN_MAIN, b) - } - binding.alwaysShowsReopenAppOptionsSwitch.setOnCheckedChangeListener { btn, b -> - if (btn.isPressed.not()) return@setOnCheckedChangeListener - modulePrefs.put(DataConst.ENABLE_ALWAYS_SHOWS_REOPEN_APP_OPTIONS, b) - } - binding.enableAppsConfigsTemplateSwitch.setOnCheckedChangeListener { btn, b -> - if (btn.isPressed.not()) return@setOnCheckedChangeListener - binding.mgrAppsConfigsTemplateButton.isVisible = b - modulePrefs.put(DataConst.ENABLE_APP_CONFIG_TEMPLATE, b) + binding.onlyShowErrorsInFrontSwitch.bind(ConfigData.ENABLE_ONLY_SHOW_ERRORS_IN_FRONT) + binding.onlyShowErrorsInMainProcessSwitch.bind(ConfigData.ENABLE_ONLY_SHOW_ERRORS_IN_MAIN) + binding.alwaysShowsReopenAppOptionsSwitch.bind(ConfigData.ENABLE_ALWAYS_SHOWS_REOPEN_APP_OPTIONS) + binding.enableAppsConfigsTemplateSwitch.bind(ConfigData.ENABLE_APP_CONFIG_TEMPLATE) { + binding.mgrAppsConfigsTemplateButton.isVisible = it } /** 设置桌面图标显示隐藏 */ binding.hideIconInLauncherSwitch.isChecked = isLauncherIconShowing.not() @@ -88,11 +72,11 @@ class MainActivity : BaseActivity() { /** 项目地址按钮点击事件 */ binding.titleGithubIcon.setOnClickListener { openBrowser(url = "https://github.com/KitsunePie/AppErrorsTracking") } /** 显示开发者提示 */ - if (modulePrefs.get(DataConst.SHOW_DEVELOPER_NOTICE)) + if (ConfigData.isShowDeveloperNotice) showDialog { title = LocaleString.developerNotice msg = LocaleString.developerNoticeTip - confirmButton(LocaleString.gotIt) { modulePrefs.put(DataConst.SHOW_DEVELOPER_NOTICE, value = false) } + confirmButton(LocaleString.gotIt) { ConfigData.isShowDeveloperNotice = false } noCancelable() } }