From aae8a27fcc4c2ba9c51f09c999267ec77ced6796 Mon Sep 17 00:00:00 2001 From: fankesyooni Date: Mon, 30 May 2022 01:58:28 +0800 Subject: [PATCH] Merge to new way support receiver callback --- .../com/fankes/coloros/notify/const/Const.kt | 60 --------- .../notify/hook/entity/SystemUIHooker.kt | 104 +++++----------- .../notify/ui/activity/MainActivity.kt | 6 +- .../auto/NotifyIconRuleUpdateActivity.kt | 8 -- .../notify/ui/activity/base/BaseActivity.kt | 9 -- .../notify/utils/tool/IconAdaptationTool.kt | 13 +- .../coloros/notify/utils/tool/SystemUITool.kt | 114 ++++++------------ 7 files changed, 76 insertions(+), 238 deletions(-) delete mode 100644 app/src/main/java/com/fankes/coloros/notify/const/Const.kt diff --git a/app/src/main/java/com/fankes/coloros/notify/const/Const.kt b/app/src/main/java/com/fankes/coloros/notify/const/Const.kt deleted file mode 100644 index e4a068f..0000000 --- a/app/src/main/java/com/fankes/coloros/notify/const/Const.kt +++ /dev/null @@ -1,60 +0,0 @@ -/* - * ColorOSNotifyIcon - Optimize notification icons for ColorOS and adapt to native notification icon specifications. - * Copyright (C) 2019-2022 Fankes Studio(qzmmcn@163.com) - * https://github.com/fankes/ColorOSNotifyIcon - * - * 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/3/24. - */ -@file:Suppress("MemberVisibilityCanBePrivate") - -package com.fankes.coloros.notify.const - -import com.fankes.coloros.notify.BuildConfig - -/** - * 存储一些静态编译后的值 - */ -object Const { - - /** 当前模块的包名 */ - const val MODULE_PACKAGE_NAME = BuildConfig.APPLICATION_ID - - /** 当前模块的版本名称 */ - const val MODULE_VERSION_NAME = BuildConfig.VERSION_NAME - - /** 当前模块的版本号 */ - const val MODULE_VERSION_CODE = BuildConfig.VERSION_CODE - - /** 当前模块的版本校验 */ - const val MODULE_VERSION_VERIFY = "${MODULE_VERSION_NAME}_${MODULE_VERSION_CODE}_202205091602" - - /** 当前模块的版本校验标签 */ - const val MODULE_VERSION_VERIFY_TAG = "module_version_verify" - - /** 发送通讯广播号标签 - 模块激活状态 */ - const val ACTION_MODULE_CHECKING_RECEIVER = "cnn_module_checking_action" - - /** 接收通讯广播号标签 - 模块激活状态 */ - const val ACTION_MODULE_HANDLER_RECEIVER = "cnn_module_handler_action" - - /** 发送通讯广播号标签 - 通知系统界面刷新 */ - const val ACTION_REMIND_CHECKING_RECEIVER = "cnn_remind_checking_action" - - /** 接收通讯广播号标签 - 通知系统界面刷新 */ - const val ACTION_REMIND_HANDLER_RECEIVER = "cnn_remind_handler_action" -} \ No newline at end of file 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 5cf8512..ebe1b8b 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 @@ -25,10 +25,8 @@ package com.fankes.coloros.notify.hook.entity import android.app.WallpaperManager -import android.content.BroadcastReceiver import android.content.Context import android.content.Intent -import android.content.IntentFilter import android.content.res.ColorStateList import android.graphics.Bitmap import android.graphics.Color @@ -37,6 +35,7 @@ import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable import android.graphics.drawable.Icon import android.graphics.drawable.VectorDrawable +import android.os.SystemClock import android.service.notification.StatusBarNotification import android.util.ArrayMap import android.view.View @@ -46,7 +45,6 @@ import android.widget.ImageView import androidx.core.graphics.drawable.toBitmap import androidx.core.view.children import com.fankes.coloros.notify.bean.IconDataBean -import com.fankes.coloros.notify.const.Const import com.fankes.coloros.notify.data.DataConst import com.fankes.coloros.notify.hook.HookConst.ANDROID_PACKAGE_NAME import com.fankes.coloros.notify.hook.HookConst.SYSTEMUI_PACKAGE_NAME @@ -56,6 +54,7 @@ import com.fankes.coloros.notify.param.IconPackParams import com.fankes.coloros.notify.utils.drawable.drawabletoolbox.DrawableBuilder import com.fankes.coloros.notify.utils.factory.* 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.current @@ -216,65 +215,6 @@ object SystemUIHooker : YukiBaseHooker() { /** 是否已经使用过缓存刷新功能 */ private var isUsingCachingMethod = false - /** 是否已经注册广播 */ - private var isRegisterReceiver = false - - /** 用户解锁屏幕广播接收器 */ - private val userPresentReceiver by lazy { - object : BroadcastReceiver() { - override fun onReceive(context: Context?, intent: Intent?) { - /** 解锁后重新刷新状态栏图标防止系统重新设置它 */ - if (isUsingCachingMethod) refreshStatusBarIcons() - } - } - } - - /** 模块广播接收器 */ - private val moduleCheckingReceiver by lazy { - object : BroadcastReceiver() { - override fun onReceive(context: Context?, intent: Intent?) { - context?.sendBroadcast(Intent().apply { - action = Const.ACTION_MODULE_HANDLER_RECEIVER - putExtra("isRegular", true) - putExtra("isValied", intent?.isValiedModule) - }) - } - } - } - - /** 通知广播接收器 */ - private val remindCheckingReceiver by lazy { - object : BroadcastReceiver() { - override fun onReceive(context: Context?, intent: Intent?) = delayedRun(ms = 300) { - if (intent?.isValiedModule == true) - recachingPrefs(intent.getBooleanExtra("isRefreshCacheOnly", false)) - context?.sendBroadcast(Intent().apply { - action = Const.ACTION_REMIND_HANDLER_RECEIVER - putExtra("isGrasp", true) - putExtra("isValied", intent?.isValiedModule) - }) - } - } - } - - /** - * 判断模块和宿主版本是否一致 - * @return [Boolean] - */ - private val Intent.isValiedModule get() = getStringExtra(Const.MODULE_VERSION_VERIFY_TAG) == Const.MODULE_VERSION_VERIFY - - /** - * 注册广播接收器 - * @param context 实例 - */ - private fun registerReceiver(context: Context) { - if (isRegisterReceiver) return - context.registerReceiver(userPresentReceiver, IntentFilter().apply { addAction(Intent.ACTION_USER_PRESENT) }) - context.registerReceiver(moduleCheckingReceiver, IntentFilter().apply { addAction(Const.ACTION_MODULE_CHECKING_RECEIVER) }) - context.registerReceiver(remindCheckingReceiver, IntentFilter().apply { addAction(Const.ACTION_REMIND_CHECKING_RECEIVER) }) - isRegisterReceiver = true - } - /** * 是否启用通知图标优化功能 * @param isHooking 是否判断启用通知功能 - 默认:是 @@ -580,6 +520,14 @@ object SystemUIHooker : YukiBaseHooker() { } } + /** 注册 */ + private fun register() { + /** 解锁后重新刷新状态栏图标防止系统重新设置它 */ + onAppLifecycle { registerReceiver(Intent.ACTION_USER_PRESENT) { _, _ -> if (isUsingCachingMethod) refreshStatusBarIcons() } } + /** 刷新图标缓存 */ + SystemUITool.Host.onRefreshSystemUI(param = this) { recachingPrefs(it) } + } + /** 缓存图标数据 */ private fun cachingIconDatas() { iconDatas.clear() @@ -594,17 +542,25 @@ object SystemUIHooker : YukiBaseHooker() { /** * 刷新缓存数据 * @param isRefreshCacheOnly 仅刷新缓存不刷新图标和通知改变 - 默认:否 + * @return [Boolean] 是否成功 */ - private fun recachingPrefs(isRefreshCacheOnly: Boolean = false) { - isUsingCachingMethod = true - prefs.clearCache() - cachingIconDatas() - if (isRefreshCacheOnly) return - refreshStatusBarIcons() - refreshNotificationIcons() + private fun recachingPrefs(isRefreshCacheOnly: Boolean = false): Boolean { + /** 必要的延迟防止 Sp 存储不刷新 */ + SystemClock.sleep(100) + /** 获取可读写状态 */ + return prefs.isXSharePrefsReadable.also { + isUsingCachingMethod = true + prefs.clearCache() + cachingIconDatas() + if (isRefreshCacheOnly) return@also + refreshStatusBarIcons() + refreshNotificationIcons() + } } override fun onHook() { + /** 注册 */ + register() /** 缓存图标数据 */ cachingIconDatas() /** 移除开发者警告通知 */ @@ -697,12 +653,8 @@ object SystemUIHooker : YukiBaseHooker() { param(StatusBarNotificationClass) } afterHook { - if (args().first().any() != null) instance().also { - /** 注册壁纸颜色监听 */ - registerWallpaperColorChanged(it) - /** 注册广播 */ - registerReceiver(it.context) - } + /** 注册壁纸颜色监听 */ + if (args().first().any() != null) instance().also { registerWallpaperColorChanged(it) } } } } @@ -902,8 +854,6 @@ object SystemUIHooker : YukiBaseHooker() { } afterHook { args().first().cast()?.also { - /** 注册广播 */ - registerReceiver(it) /** 注册定时监听 */ if (isEnableHookColorNotifyIcon() && prefs.get(DataConst.ENABLE_NOTIFY_ICON_FIX_AUTO)) IconAdaptationTool.prepareAutoUpdateIconRule( 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 911385e..16f0bf2 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 @@ -302,9 +302,9 @@ class MainActivity : BaseActivity() { super.onResume() /** 刷新模块状态 */ refreshModuleStatus() - /** 发送广播检查模块激活状态 */ - SystemUITool.checkingActivated(context = this) { isRegular, isValied -> - isModuleRegular = isRegular + /** 检查模块激活状态 */ + SystemUITool.checkingActivated(context = this) { isValied -> + isModuleRegular = true isModuleValied = isValied refreshModuleStatus() } diff --git a/app/src/main/java/com/fankes/coloros/notify/ui/activity/auto/NotifyIconRuleUpdateActivity.kt b/app/src/main/java/com/fankes/coloros/notify/ui/activity/auto/NotifyIconRuleUpdateActivity.kt index c1e52bf..b3d6475 100644 --- a/app/src/main/java/com/fankes/coloros/notify/ui/activity/auto/NotifyIconRuleUpdateActivity.kt +++ b/app/src/main/java/com/fankes/coloros/notify/ui/activity/auto/NotifyIconRuleUpdateActivity.kt @@ -43,8 +43,6 @@ class NotifyIconRuleUpdateActivity : Activity() { View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE window?.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) window?.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION) - /** 注册 */ - SystemUITool.register(context = this) /** 检测运行状态 */ if (BaseActivity.isMainThreadRunning) { finish() @@ -60,10 +58,4 @@ class NotifyIconRuleUpdateActivity : Activity() { /** 切换到后台 */ moveTaskToBack(true) } - - override fun onDestroy() { - super.onDestroy() - /** 解除注册 */ - SystemUITool.unregister(context = this) - } } \ No newline at end of file diff --git a/app/src/main/java/com/fankes/coloros/notify/ui/activity/base/BaseActivity.kt b/app/src/main/java/com/fankes/coloros/notify/ui/activity/base/BaseActivity.kt index 25366a5..87dd769 100644 --- a/app/src/main/java/com/fankes/coloros/notify/ui/activity/base/BaseActivity.kt +++ b/app/src/main/java/com/fankes/coloros/notify/ui/activity/base/BaseActivity.kt @@ -31,7 +31,6 @@ import androidx.core.view.ViewCompat import androidx.viewbinding.ViewBinding import com.fankes.coloros.notify.R import com.fankes.coloros.notify.utils.factory.isNotSystemInDarkMode -import com.fankes.coloros.notify.utils.tool.SystemUITool import com.highcapable.yukihookapi.hook.factory.method import com.highcapable.yukihookapi.hook.type.android.LayoutInflaterClass import java.lang.reflect.ParameterizedType @@ -71,18 +70,10 @@ abstract class BaseActivity : AppCompatActivity() { window?.navigationBarColor = it window?.navigationBarDividerColor = it } - /** 注册 */ - SystemUITool.register(context = this) /** 装载子类 */ onCreate() } /** 回调 [onCreate] 方法 */ abstract fun onCreate() - - override fun onDestroy() { - super.onDestroy() - /** 解除注册 */ - SystemUITool.unregister(context = this) - } } \ No newline at end of file diff --git a/app/src/main/java/com/fankes/coloros/notify/utils/tool/IconAdaptationTool.kt b/app/src/main/java/com/fankes/coloros/notify/utils/tool/IconAdaptationTool.kt index 89bd93f..7ba9010 100644 --- a/app/src/main/java/com/fankes/coloros/notify/utils/tool/IconAdaptationTool.kt +++ b/app/src/main/java/com/fankes/coloros/notify/utils/tool/IconAdaptationTool.kt @@ -33,7 +33,7 @@ import android.graphics.Bitmap import android.graphics.drawable.Icon import android.os.Build import androidx.core.graphics.drawable.toBitmap -import com.fankes.coloros.notify.const.Const +import com.fankes.coloros.notify.BuildConfig import com.fankes.coloros.notify.hook.HookEntry import com.fankes.coloros.notify.utils.factory.* @@ -44,6 +44,9 @@ import com.fankes.coloros.notify.utils.factory.* */ object IconAdaptationTool { + /** 当前模块的包名 */ + private const val MODULE_PACKAGE_NAME = BuildConfig.APPLICATION_ID + /** 推送通知的渠道名称 */ private const val NOTIFY_CHANNEL = "notifyRuleSupportId" @@ -137,8 +140,8 @@ object IconAdaptationTool { context, packageName.hashCode(), Intent().apply { component = ComponentName( - Const.MODULE_PACKAGE_NAME, - "${Const.MODULE_PACKAGE_NAME}.ui.activity.ConfigureActivity" + MODULE_PACKAGE_NAME, + "${MODULE_PACKAGE_NAME}.ui.activity.ConfigureActivity" ) flags = Intent.FLAG_ACTIVITY_NEW_TASK }.apply { @@ -177,8 +180,8 @@ object IconAdaptationTool { context.startActivity( Intent().apply { component = ComponentName( - Const.MODULE_PACKAGE_NAME, - "${Const.MODULE_PACKAGE_NAME}.ui.activity.auto.NotifyIconRuleUpdateActivity" + MODULE_PACKAGE_NAME, + "${MODULE_PACKAGE_NAME}.ui.activity.auto.NotifyIconRuleUpdateActivity" ) flags = Intent.FLAG_ACTIVITY_NEW_TASK } 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 17f7a04..250777b 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 @@ -22,59 +22,44 @@ */ package com.fankes.coloros.notify.utils.tool -import android.content.BroadcastReceiver import android.content.Context -import android.content.Intent -import android.content.IntentFilter -import com.fankes.coloros.notify.const.Const +import com.fankes.coloros.notify.hook.HookConst.SYSTEMUI_PACKAGE_NAME import com.fankes.coloros.notify.utils.factory.* import com.google.android.material.snackbar.Snackbar -import com.highcapable.yukihookapi.hook.factory.isXposedModuleActive -import com.highcapable.yukihookapi.hook.xposed.application.ModuleApplication.Companion.appContext +import com.highcapable.yukihookapi.YukiHookAPI +import com.highcapable.yukihookapi.hook.factory.dataChannel +import com.highcapable.yukihookapi.hook.param.PackageParam +import com.highcapable.yukihookapi.hook.xposed.channel.data.ChannelData /** * 系统界面工具 */ object SystemUITool { - /** 宿主广播回调 */ - private var moduleHandlerCallback: ((Boolean, Boolean) -> Unit)? = null - - /** 通知广播回调 */ - private var remindHandlerCallback: ((Boolean, Boolean) -> Unit)? = null + private val CALL_HOST_REFRESH_CACHING = ChannelData("call_host_refresh_caching", false) + private val CALL_MODULE_REFRESH_RESULT = ChannelData("call_module_refresh_result", false) /** - * 注册广播 - * @param context 实例 + * 宿主注册监听 */ - fun register(context: Context) = runInSafe { - /** 注册广播检查模块激活状态 */ - context.registerReceiver(moduleHandlerReceiver, IntentFilter().apply { addAction(Const.ACTION_MODULE_HANDLER_RECEIVER) }) - /** 注册广播通知系统界面改变 */ - context.registerReceiver(remindHandlerReceiver, IntentFilter().apply { addAction(Const.ACTION_REMIND_HANDLER_RECEIVER) }) - } + object Host { - /** - * 取消注册广播 - * @param context 实例 - */ - fun unregister(context: Context) = runInSafe { - context.unregisterReceiver(moduleHandlerReceiver) - context.unregisterReceiver(remindHandlerReceiver) + /** + * 监听系统界面刷新改变 + * @param param 实例 + * @param result 回调 - ([Boolean] 是否成功) + */ + fun onRefreshSystemUI(param: PackageParam, result: (Boolean) -> Boolean) { + param.dataChannel.with { wait(CALL_HOST_REFRESH_CACHING) { put(CALL_MODULE_REFRESH_RESULT, result(it)) } } + } } /** * 检查模块是否激活 * @param context 实例 - * @param it 成功后回调 - ([Boolean] 是否激活,[Boolean] 是否有效) + * @param result 成功后回调 */ - fun checkingActivated(context: Context, it: (Boolean, Boolean) -> Unit) { - moduleHandlerCallback = it - context.sendBroadcast(Intent().apply { - action = Const.ACTION_MODULE_CHECKING_RECEIVER - putExtra(Const.MODULE_VERSION_VERIFY_TAG, Const.MODULE_VERSION_VERIFY) - }) - } + fun checkingActivated(context: Context, result: (Boolean) -> Unit) = context.dataChannel(SYSTEMUI_PACKAGE_NAME).checkingVersionEquals(result) /** * 重启系统界面 @@ -99,17 +84,10 @@ object SystemUITool { * 刷新系统界面状态栏与通知图标 * @param context 实例 * @param isRefreshCacheOnly 仅刷新缓存不刷新图标和通知改变 - 默认:否 - * @param it 成功后回调 + * @param callback 成功后回调 */ - fun refreshSystemUI(context: Context? = null, isRefreshCacheOnly: Boolean = false, it: () -> Unit = {}) = runInSafe { - fun sendMessage() { - (context ?: appContext).sendBroadcast(Intent().apply { - action = Const.ACTION_REMIND_CHECKING_RECEIVER - putExtra("isRefreshCacheOnly", isRefreshCacheOnly) - putExtra(Const.MODULE_VERSION_VERIFY_TAG, Const.MODULE_VERSION_VERIFY) - }) - } - if (isXposedModuleActive) + fun refreshSystemUI(context: Context? = null, isRefreshCacheOnly: Boolean = false, callback: () -> Unit = {}) = runInSafe { + if (YukiHookAPI.Status.isXposedModuleActive) context?.showDialog { title = "请稍后" progressContent = "正在等待系统界面刷新" @@ -118,23 +96,29 @@ object SystemUITool { /** 设置等待延迟 */ delayedRun(ms = 5000) { if (isWaited) return@delayedRun - remindHandlerCallback = null cancel() context.snake(msg = "预计响应超时,建议重启系统界面", actionText = "立即重启") { restartSystemUI(context) } } - remindHandlerCallback = { isGrasp, isValied -> - remindHandlerCallback = null - cancel() - isWaited = true + checkingActivated(context) { isValied -> when { - isGrasp && !isValied -> + isValied.not() -> { + cancel() + isWaited = true context.snake(msg = "请重启系统界面以生效模块更新", actionText = "立即重启") { restartSystemUI(context) } - else -> it() + } + else -> context.dataChannel(SYSTEMUI_PACKAGE_NAME).with { + wait(CALL_MODULE_REFRESH_RESULT) { + cancel() + isWaited = true + callback() + if (it.not()) context.snake(msg = "刷新失败,建议重启系统界面", actionText = "立即重启") { restartSystemUI(context) } + } + put(CALL_HOST_REFRESH_CACHING, isRefreshCacheOnly) + } } } - sendMessage() noCancelable() - } ?: sendMessage() + } else context?.snake(msg = "模块没有激活,更改不会生效") } @@ -143,29 +127,7 @@ object SystemUITool { * @param context 实例 */ fun showNeedRestartSnake(context: Context) = - if (isXposedModuleActive) + if (YukiHookAPI.Status.isXposedModuleActive) context.snake(msg = "设置需要重启系统界面才能生效", actionText = "立即重启") { restartSystemUI(context) } else context.snake(msg = "模块没有激活,更改不会生效") - - /** 宿主广播接收器 */ - private val moduleHandlerReceiver by lazy { - object : BroadcastReceiver() { - override fun onReceive(context: Context?, intent: Intent?) { - val isRegular = intent?.getBooleanExtra("isRegular", false) ?: false - val isValied = intent?.getBooleanExtra("isValied", false) ?: false - moduleHandlerCallback?.invoke(isRegular, isValied) - } - } - } - - /** 通知广播接收器 */ - private val remindHandlerReceiver by lazy { - object : BroadcastReceiver() { - override fun onReceive(context: Context?, intent: Intent?) { - val isGrasp = intent?.getBooleanExtra("isGrasp", false) ?: false - val isValied = intent?.getBooleanExtra("isValied", false) ?: false - remindHandlerCallback?.invoke(isGrasp, isValied) - } - } - } } \ No newline at end of file