mirror of
https://github.com/HighCapable/YukiHookAPI.git
synced 2025-09-06 02:35:40 +08:00
feat: add replace resources hook callback functions
This commit is contained in:
@@ -25,7 +25,10 @@
|
|||||||
*
|
*
|
||||||
* This file is created by fankes on 2022/5/1.
|
* This file is created by fankes on 2022/5/1.
|
||||||
*/
|
*/
|
||||||
@file:Suppress("unused", "MemberVisibilityCanBePrivate", "NON_PUBLIC_CALL_FROM_PUBLIC_INLINE")
|
@file:Suppress(
|
||||||
|
"unused", "MemberVisibilityCanBePrivate", "NON_PUBLIC_CALL_FROM_PUBLIC_INLINE",
|
||||||
|
"DiscouragedApi", "UseCompatLoadingForDrawables", "DEPRECATION"
|
||||||
|
)
|
||||||
|
|
||||||
package com.highcapable.yukihookapi.hook.core
|
package com.highcapable.yukihookapi.hook.core
|
||||||
|
|
||||||
@@ -96,6 +99,12 @@ class YukiResourcesHookCreator internal constructor(internal val packageParam: P
|
|||||||
/** 当前的替换值实例 */
|
/** 当前的替换值实例 */
|
||||||
private var replaceInstance: Any? = null
|
private var replaceInstance: Any? = null
|
||||||
|
|
||||||
|
/** 当前的替换值回调 */
|
||||||
|
private var replaceCallback: ((Any) -> Any?)? = null
|
||||||
|
|
||||||
|
/** 当前的替换值回调 */
|
||||||
|
private var replaceFwdCallback: ((Any) -> Int)? = null
|
||||||
|
|
||||||
/** 当前的布局注入实例 */
|
/** 当前的布局注入实例 */
|
||||||
private var layoutInstance: (YukiResources.LayoutInflatedParam.() -> Unit)? = null
|
private var layoutInstance: (YukiResources.LayoutInflatedParam.() -> Unit)? = null
|
||||||
|
|
||||||
@@ -144,6 +153,32 @@ class YukiResourcesHookCreator internal constructor(internal val packageParam: P
|
|||||||
replaceInstance = ModuleResFwd(resId)
|
replaceInstance = ModuleResFwd(resId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 替换指定 Resources 为指定的值
|
||||||
|
*
|
||||||
|
* - 此方法只支持部分类型 - 例如 [String]、[Boolean]
|
||||||
|
*
|
||||||
|
* - 此方法不支持在 [HookEntryType.ZYGOTE] 时使用
|
||||||
|
* @param result 回调原始值、返回需要替换的类型
|
||||||
|
*/
|
||||||
|
fun replaceTo(result: (original: Any) -> Any?) {
|
||||||
|
replaceCallback = result
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 替换为当前 Xposed 模块的 Resources
|
||||||
|
*
|
||||||
|
* 你可以直接使用模块的 R.string.xxx、R.mipmap.xxx、R.drawable.xxx 替换 Hook APP 的 Resources
|
||||||
|
*
|
||||||
|
* - 此方法只支持部分类型 - 例如 [String]、[Boolean]
|
||||||
|
*
|
||||||
|
* - 此方法不支持在 [HookEntryType.ZYGOTE] 时使用
|
||||||
|
* @param result 回调原始值、返回需要替换的当前 Xposed 模块的 Resources Id
|
||||||
|
*/
|
||||||
|
fun replaceToModuleResource(result: (original: Any) -> Int) {
|
||||||
|
replaceFwdCallback = result
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 作为装载的布局注入
|
* 作为装载的布局注入
|
||||||
* @param initiate [YukiResources.LayoutInflatedParam] 方法体
|
* @param initiate [YukiResources.LayoutInflatedParam] 方法体
|
||||||
@@ -172,7 +207,8 @@ class YukiResourcesHookCreator internal constructor(internal val packageParam: P
|
|||||||
if (isDisableCreatorRunHook.not()) runCatching {
|
if (isDisableCreatorRunHook.not()) runCatching {
|
||||||
when {
|
when {
|
||||||
conditions == null -> YLog.innerE("You must set the conditions before hook a Resources [$tag]")
|
conditions == null -> YLog.innerE("You must set the conditions before hook a Resources [$tag]")
|
||||||
replaceInstance == null && layoutInstance == null -> YLog.innerE("Resources Hook got null replaceInstance [$tag]")
|
replaceInstance == null && replaceCallback == null && replaceFwdCallback == null && layoutInstance == null ->
|
||||||
|
YLog.innerE("Resources Hook got null replaceInstance [$tag]")
|
||||||
packageParam.wrapper?.type == HookEntryType.RESOURCES && hookResources.instance != null ->
|
packageParam.wrapper?.type == HookEntryType.RESOURCES && hookResources.instance != null ->
|
||||||
if (resourceId == -1) when {
|
if (resourceId == -1) when {
|
||||||
layoutInstance != null ->
|
layoutInstance != null ->
|
||||||
@@ -180,6 +216,18 @@ class YukiResourcesHookCreator internal constructor(internal val packageParam: P
|
|||||||
packageParam.packageName, conditions!!.type,
|
packageParam.packageName, conditions!!.type,
|
||||||
conditions!!.name, layoutInstance!!
|
conditions!!.name, layoutInstance!!
|
||||||
) { YLog.innerD("Hook Resources Layout $conditions done [$tag]") }
|
) { YLog.innerD("Hook Resources Layout $conditions done [$tag]") }
|
||||||
|
replaceCallback != null -> conditionsResValue?.let {
|
||||||
|
hookResources.instance?.setReplacement(
|
||||||
|
packageParam.packageName, conditions!!.type,
|
||||||
|
conditions!!.name, compat(replaceCallback!!(it))
|
||||||
|
) { YLog.innerD("Hook Resources Value $conditions done [$tag]") }
|
||||||
|
} ?: YLog.innerW("Resources type \"${conditions!!.type}\" not support replaceTo { ... } function")
|
||||||
|
replaceFwdCallback != null -> conditionsResValue?.let {
|
||||||
|
hookResources.instance?.setReplacement(
|
||||||
|
packageParam.packageName, conditions!!.type,
|
||||||
|
conditions!!.name, compat(ModuleResFwd(replaceFwdCallback!!(it)))
|
||||||
|
) { YLog.innerD("Hook Resources Value $conditions done [$tag]") }
|
||||||
|
} ?: YLog.innerW("Resources type \"${conditions!!.type}\" not support replaceToModuleResource { ... } function")
|
||||||
else -> hookResources.instance?.setReplacement(
|
else -> hookResources.instance?.setReplacement(
|
||||||
packageParam.packageName, conditions!!.type,
|
packageParam.packageName, conditions!!.type,
|
||||||
conditions!!.name, compat(replaceInstance)
|
conditions!!.name, compat(replaceInstance)
|
||||||
@@ -199,6 +247,8 @@ class YukiResourcesHookCreator internal constructor(internal val packageParam: P
|
|||||||
packageParam.packageName, conditions!!.type,
|
packageParam.packageName, conditions!!.type,
|
||||||
conditions!!.name, layoutInstance!!
|
conditions!!.name, layoutInstance!!
|
||||||
) { YLog.innerD("Hook Wide Resources Layout $conditions done [$tag]") }
|
) { YLog.innerD("Hook Wide Resources Layout $conditions done [$tag]") }
|
||||||
|
replaceCallback != null -> YLog.innerW("Zygote not support replaceTo { ... } function")
|
||||||
|
replaceFwdCallback != null -> YLog.innerW("Zygote not support replaceToModuleResource { ... } function")
|
||||||
else -> YukiResources.setSystemWideReplacement(
|
else -> YukiResources.setSystemWideReplacement(
|
||||||
packageParam.packageName, conditions!!.type,
|
packageParam.packageName, conditions!!.type,
|
||||||
conditions!!.name, compat(replaceInstance)
|
conditions!!.name, compat(replaceInstance)
|
||||||
@@ -220,6 +270,29 @@ class YukiResourcesHookCreator internal constructor(internal val packageParam: P
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得查找条件中的宿主原始 [Resources]
|
||||||
|
* @return [Any] or null
|
||||||
|
*/
|
||||||
|
private val conditionsResValue get(): Any? {
|
||||||
|
val appResources = packageParam.appResources ?: error("Failed to got Host Resources")
|
||||||
|
val original = runCatching {
|
||||||
|
appResources.getIdentifier(conditions!!.name, conditions!!.type, packageParam.packageName)
|
||||||
|
}.getOrNull() ?: -1
|
||||||
|
return when (conditions!!.type) {
|
||||||
|
"anim" -> appResources.getAnimation(original)
|
||||||
|
"bool" -> appResources.getBoolean(original)
|
||||||
|
"color" -> appResources.getColor(original)
|
||||||
|
"dimen" -> appResources.getDimension(original)
|
||||||
|
"drawable", "mipmap" -> appResources.getDrawable(original)
|
||||||
|
"integer" -> appResources.getInteger(original)
|
||||||
|
"layout" -> appResources.getLayout(original)
|
||||||
|
"string" -> appResources.getString(original)
|
||||||
|
"xml" -> appResources.getXml(original)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resources 查找条件实现类
|
* Resources 查找条件实现类
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user