From 2b4269d0126651078b2724684ccd55c42dbafd25 Mon Sep 17 00:00:00 2001 From: Fankesyooni Date: Fri, 6 May 2022 14:28:34 +0800 Subject: [PATCH] Fix some device not support Resources Hook lead to function not functioning properly (like ZUI) --- .../hook/core/YukiResourcesHookCreater.kt | 16 +-- .../bridge/dummy/YukiModuleResources.kt | 6 +- .../hook/xposed/bridge/dummy/YukiResources.kt | 106 +++++++++++++----- 3 files changed, 94 insertions(+), 34 deletions(-) diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/YukiResourcesHookCreater.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/YukiResourcesHookCreater.kt index bf03b790..a07687d4 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/YukiResourcesHookCreater.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/YukiResourcesHookCreater.kt @@ -184,16 +184,16 @@ class YukiResourcesHookCreater(private val packageParam: PackageParam, @Publishe hookResources.instance?.hookLayout( packageParam.packageName, conditions!!.type, conditions!!.name, layoutInstance!! - ).run { onHookLogMsg(msg = "Hook Resources Layout $conditions done [$tag]") } + ) { onHookLogMsg(msg = "Hook Resources Layout $conditions done [$tag]") } else -> hookResources.instance?.setReplacement( packageParam.packageName, conditions!!.type, conditions!!.name, compat(replaceInstance) - ).run { onHookLogMsg(msg = "Hook Resources Value $conditions done [$tag]") } + ) { onHookLogMsg(msg = "Hook Resources Value $conditions done [$tag]") } } else when { layoutInstance != null -> hookResources.instance?.hookLayout(resourceId, layoutInstance!!) - .run { onHookLogMsg(msg = "Hook Resources Layout Id $resourceId done [$tag]") } + { onHookLogMsg(msg = "Hook Resources Layout Id $resourceId done [$tag]") } else -> hookResources.instance?.setReplacement(resourceId, compat(replaceInstance)) - .run { onHookLogMsg(msg = "Hook Resources Value Id $resourceId done [$tag]") } + { onHookLogMsg(msg = "Hook Resources Value Id $resourceId done [$tag]") } } packageParam.wrapper?.type == HookEntryType.ZYGOTE -> if (resourceId == -1) when { @@ -201,16 +201,16 @@ class YukiResourcesHookCreater(private val packageParam: PackageParam, @Publishe YukiResources.hookSystemWideLayout( packageParam.packageName, conditions!!.type, conditions!!.name, layoutInstance!! - ).run { onHookLogMsg(msg = "Hook Wide Resources Layout $conditions done [$tag]") } + ) { onHookLogMsg(msg = "Hook Wide Resources Layout $conditions done [$tag]") } else -> YukiResources.setSystemWideReplacement( packageParam.packageName, conditions!!.type, conditions!!.name, compat(replaceInstance) - ).run { onHookLogMsg(msg = "Hook Wide Resources Value $conditions done [$tag]") } + ) { onHookLogMsg(msg = "Hook Wide Resources Value $conditions done [$tag]") } } else when { layoutInstance != null -> YukiResources.hookSystemWideLayout(resourceId, layoutInstance!!) - .run { onHookLogMsg(msg = "Hook Wide Resources Layout Id $resourceId done [$tag]") } + { onHookLogMsg(msg = "Hook Wide Resources Layout Id $resourceId done [$tag]") } else -> YukiResources.setSystemWideReplacement(resourceId, compat(replaceInstance)) - .run { onHookLogMsg(msg = "Hook Wide Resources Value Id $resourceId done [$tag]") } + { onHookLogMsg(msg = "Hook Wide Resources Value Id $resourceId done [$tag]") } } else -> yLoggerE(msg = "Resources Hook type is invalid [$tag]") } diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/bridge/dummy/YukiModuleResources.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/bridge/dummy/YukiModuleResources.kt index cb78381d..fc61a38e 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/bridge/dummy/YukiModuleResources.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/bridge/dummy/YukiModuleResources.kt @@ -38,7 +38,11 @@ import android.content.res.XResForwarder * @param baseInstance 原始实例 */ class YukiModuleResources(private val baseInstance: XModuleResources) : - Resources(baseInstance.assets, baseInstance.displayMetrics, baseInstance.configuration) { + Resources( + runCatching { baseInstance.assets }.getOrNull(), + runCatching { baseInstance.displayMetrics }.getOrNull(), + runCatching { baseInstance.configuration }.getOrNull() + ) { companion object { diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/bridge/dummy/YukiResources.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/bridge/dummy/YukiResources.kt index 22a0fa7c..e95c8cff 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/bridge/dummy/YukiResources.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/bridge/dummy/YukiResources.kt @@ -33,6 +33,7 @@ import android.content.res.Resources import android.content.res.XResources import android.graphics.drawable.Drawable import android.view.View +import com.highcapable.yukihookapi.hook.log.yLoggerE import com.highcapable.yukihookapi.hook.xposed.bridge.dummy.YukiResources.LayoutInflatedParam import de.robv.android.xposed.callbacks.XC_LayoutInflated @@ -41,7 +42,11 @@ import de.robv.android.xposed.callbacks.XC_LayoutInflated * @param baseInstance 原始实例 */ class YukiResources(private val baseInstance: XResources) : - Resources(baseInstance.assets, baseInstance.displayMetrics, baseInstance.configuration) { + Resources( + runCatching { baseInstance.assets }.getOrNull(), + runCatching { baseInstance.displayMetrics }.getOrNull(), + runCatching { baseInstance.configuration }.getOrNull() + ) { companion object { @@ -71,8 +76,13 @@ class YukiResources(private val baseInstance: XResources) : * 对接 [XResources.setSystemWideReplacement] * @param resId Resources Id * @param replacement 替换 Resources + * @param callback 是否成功执行回调 */ - internal fun setSystemWideReplacement(resId: Int, replacement: Any?) = XResources.setSystemWideReplacement(resId, compat(replacement)) + internal fun setSystemWideReplacement(resId: Int, replacement: Any?, callback: () -> Unit = {}) = + runIfAnyErrors(name = "setSystemWideReplacement") { + XResources.setSystemWideReplacement(resId, compat(replacement)) + callback() + } /** * 在 Zygote 中替换 Resources @@ -82,9 +92,13 @@ class YukiResources(private val baseInstance: XResources) : * @param type Resources 类型 * @param name Resources 名称 * @param replacement 替换 Resources + * @param callback 是否成功执行回调 */ - internal fun setSystemWideReplacement(packageName: String, type: String, name: String, replacement: Any?) = - XResources.setSystemWideReplacement(packageName, type, name, compat(replacement)) + internal fun setSystemWideReplacement(packageName: String, type: String, name: String, replacement: Any?, callback: () -> Unit = {}) = + runIfAnyErrors(name = "setSystemWideReplacement") { + XResources.setSystemWideReplacement(packageName, type, name, compat(replacement)) + callback() + } /** * 在 Zygote 中注入布局 Resources @@ -92,15 +106,18 @@ class YukiResources(private val baseInstance: XResources) : * 对接 [XResources.hookSystemWideLayout] * @param resId Resources Id * @param initiate 注入方法体 + * @param callback 是否成功执行回调 */ - internal fun hookSystemWideLayout(resId: Int, initiate: LayoutInflatedParam.() -> Unit) { - XResources.hookSystemWideLayout(resId, object : XC_LayoutInflated() { - override fun handleLayoutInflated(liparam: LayoutInflatedParam?) { - if (liparam == null) return - initiate(LayoutInflatedParam(liparam)) - } - }) - } + internal fun hookSystemWideLayout(resId: Int, initiate: LayoutInflatedParam.() -> Unit, callback: () -> Unit = {}) = + runIfAnyErrors(name = "hookSystemWideLayout") { + XResources.hookSystemWideLayout(resId, object : XC_LayoutInflated() { + override fun handleLayoutInflated(liparam: LayoutInflatedParam?) { + if (liparam == null) return + initiate(LayoutInflatedParam(liparam)) + } + }) + callback() + } /** * 在 Zygote 中注入布局 Resources @@ -110,14 +127,33 @@ class YukiResources(private val baseInstance: XResources) : * @param type Resources 类型 * @param name Resources 名称 * @param initiate 注入方法体 + * @param callback 是否成功执行回调 */ - internal fun hookSystemWideLayout(packageName: String, type: String, name: String, initiate: LayoutInflatedParam.() -> Unit) { + internal fun hookSystemWideLayout( + packageName: String, + type: String, + name: String, + initiate: LayoutInflatedParam.() -> Unit, + callback: () -> Unit = {} + ) = runIfAnyErrors(name = "hookSystemWideLayout") { XResources.hookSystemWideLayout(packageName, type, name, object : XC_LayoutInflated() { override fun handleLayoutInflated(liparam: LayoutInflatedParam?) { if (liparam == null) return initiate(LayoutInflatedParam(liparam)) } }) + callback() + } + + /** + * 忽略异常执行 + * @param name 方法名称 + * @param initiate 方法体 + */ + private inline fun runIfAnyErrors(name: String, initiate: () -> Unit) { + runCatching { + initiate() + }.onFailure { yLoggerE(msg = "Failed to execute method \"$name\", maybe your Hook Framework not support Resources Hook", it) } } } @@ -127,8 +163,13 @@ class YukiResources(private val baseInstance: XResources) : * 对接 [XResources.setReplacement] * @param resId Resources Id * @param replacement 替换 Resources + * @param callback 是否成功执行回调 */ - internal fun setReplacement(resId: Int, replacement: Any?) = baseInstance.setReplacement(resId, compat(replacement)) + internal fun setReplacement(resId: Int, replacement: Any?, callback: () -> Unit = {}) = + runIfAnyErrors(name = "setReplacement") { + baseInstance.setReplacement(resId, compat(replacement)) + callback() + } /** * 执行替换 Resources @@ -138,9 +179,13 @@ class YukiResources(private val baseInstance: XResources) : * @param type Resources 类型 * @param name Resources 名称 * @param replacement 替换 Resources + * @param callback 是否成功执行回调 */ - internal fun setReplacement(packageName: String, type: String, name: String, replacement: Any?) = - baseInstance.setReplacement(packageName, type, name, compat(replacement)) + internal fun setReplacement(packageName: String, type: String, name: String, replacement: Any?, callback: () -> Unit = {}) = + runIfAnyErrors(name = "setReplacement") { + baseInstance.setReplacement(packageName, type, name, compat(replacement)) + callback() + } /** * 执行注入布局 Resources @@ -148,15 +193,18 @@ class YukiResources(private val baseInstance: XResources) : * 对接 [XResources.hookLayout] * @param resId Resources Id * @param initiate 注入方法体 + * @param callback 是否成功执行回调 */ - internal fun hookLayout(resId: Int, initiate: LayoutInflatedParam.() -> Unit) { - baseInstance.hookLayout(resId, object : XC_LayoutInflated() { - override fun handleLayoutInflated(liparam: LayoutInflatedParam?) { - if (liparam == null) return - initiate(LayoutInflatedParam(liparam)) - } - }) - } + internal fun hookLayout(resId: Int, initiate: LayoutInflatedParam.() -> Unit, callback: () -> Unit = {}) = + runIfAnyErrors(name = "hookLayout") { + baseInstance.hookLayout(resId, object : XC_LayoutInflated() { + override fun handleLayoutInflated(liparam: LayoutInflatedParam?) { + if (liparam == null) return + initiate(LayoutInflatedParam(liparam)) + } + }) + callback() + } /** * 执行注入布局 Resources @@ -166,14 +214,22 @@ class YukiResources(private val baseInstance: XResources) : * @param type Resources 类型 * @param name Resources 名称 * @param initiate 注入方法体 + * @param callback 是否成功执行回调 */ - internal fun hookLayout(packageName: String, type: String, name: String, initiate: LayoutInflatedParam.() -> Unit) { + internal fun hookLayout( + packageName: String, + type: String, + name: String, + initiate: LayoutInflatedParam.() -> Unit, + callback: () -> Unit = {} + ) = runIfAnyErrors(name = "hookLayout") { baseInstance.hookLayout(packageName, type, name, object : XC_LayoutInflated() { override fun handleLayoutInflated(liparam: LayoutInflatedParam?) { if (liparam == null) return initiate(LayoutInflatedParam(liparam)) } }) + callback() } /**