Merge to new way support receiver callback

This commit is contained in:
2022-05-30 01:58:28 +08:00
parent 3b31e2c255
commit aae8a27fcc
7 changed files with 76 additions and 238 deletions

View File

@@ -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.
* <p>
*
* 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
* <https://www.gnu.org/licenses/>
*
* 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"
}

View File

@@ -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<ImageView>().also {
/** 注册壁纸颜色监听 */
registerWallpaperColorChanged(it)
/** 注册广播 */
registerReceiver(it.context)
}
/** 注册壁纸颜色监听 */
if (args().first().any() != null) instance<ImageView>().also { registerWallpaperColorChanged(it) }
}
}
}
@@ -902,8 +854,6 @@ object SystemUIHooker : YukiBaseHooker() {
}
afterHook {
args().first().cast<Context>()?.also {
/** 注册广播 */
registerReceiver(it)
/** 注册定时监听 */
if (isEnableHookColorNotifyIcon() && prefs.get(DataConst.ENABLE_NOTIFY_ICON_FIX_AUTO))
IconAdaptationTool.prepareAutoUpdateIconRule(

View File

@@ -302,9 +302,9 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
super.onResume()
/** 刷新模块状态 */
refreshModuleStatus()
/** 发送广播检查模块激活状态 */
SystemUITool.checkingActivated(context = this) { isRegular, isValied ->
isModuleRegular = isRegular
/** 检查模块激活状态 */
SystemUITool.checkingActivated(context = this) { isValied ->
isModuleRegular = true
isModuleValied = isValied
refreshModuleStatus()
}

View File

@@ -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)
}
}

View File

@@ -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<VB : ViewBinding> : 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)
}
}

View File

@@ -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
}

View File

@@ -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)
}
}
}
}