Added invokeOriginalMember function in MethodFinder and merge some code

This commit is contained in:
2022-07-29 22:27:17 +08:00
parent 11d5adee47
commit 2954b70dc0
4 changed files with 59 additions and 6 deletions

View File

@@ -513,6 +513,24 @@ inner class Instance internal constructor(private val instance: Any?)
> `Method` 实例处理类。
##### original [method]
```kotlin
fun original(): Instance
```
**变更记录**
`v1.0.93` `新增`
**功能描述**
> 标识需要调用当前 `Method` 未经 Hook 的原始方法。
若当前 `Method` 并未 Hook 则会使用原始的 `Method.invoke` 方法调用。
!> 你只能在 (Xposed) 宿主环境中使用此功能。
##### call [method]
```kotlin

View File

@@ -40,6 +40,7 @@ import com.highcapable.yukihookapi.hook.factory.hasExtends
import com.highcapable.yukihookapi.hook.log.yLoggerW
import com.highcapable.yukihookapi.hook.type.defined.UndefinedType
import com.highcapable.yukihookapi.hook.utils.runBlocking
import com.highcapable.yukihookapi.hook.xposed.bridge.factory.YukiHookHelper
import java.lang.reflect.Method
/**
@@ -443,15 +444,32 @@ class MethodFinder @PublishedApi internal constructor(
*/
inner class Instance internal constructor(private val instance: Any?) {
/** 标识需要调用当前 [Method] 未经 Hook 的原始方法 */
private var isCallOriginal = false
/**
* 标识需要调用当前 [Method] 未经 Hook 的原始方法
*
* 若当前 [Method] 并未 Hook 则会使用原始的 [Method.invoke] 方法调用
*
* - ❗你只能在 (Xposed) 宿主环境中使用此功能
* @return [Instance] 可继续向下监听
*/
fun original(): Instance {
isCallOriginal = true
return this
}
/**
* 执行方法
* @param param 方法参数
* @return [Any] or null
*/
private fun baseCall(vararg param: Any?) =
if (param.isNotEmpty())
(memberInstance as? Method?)?.invoke(instance, *param)
else (memberInstance as? Method?)?.invoke(instance)
private fun baseCall(vararg param: Any?) = (memberInstance as? Method?)?.let {
if (isCallOriginal)
YukiHookHelper.invokeOriginalMember(it, instance, *param) ?: it.invoke(instance, *param)
else it.invoke(instance, *param)
}
/**
* 执行方法 - 不指定返回值类型

View File

@@ -29,8 +29,8 @@ package com.highcapable.yukihookapi.hook.param.wrapper
import com.highcapable.yukihookapi.annotation.YukiPrivateApi
import com.highcapable.yukihookapi.hook.param.HookParam
import com.highcapable.yukihookapi.hook.xposed.bridge.factory.YukiHookHelper
import de.robv.android.xposed.XC_MethodHook
import de.robv.android.xposed.XposedBridge
import java.lang.reflect.Member
/**
@@ -95,7 +95,7 @@ class HookParamWrapper internal constructor(private var baseParam: XC_MethodHook
* @param args 参数实例
* @return [Any] or null
*/
fun invokeOriginalMember(member: Member, vararg args: Any?): Any? = XposedBridge.invokeOriginalMethod(member, instance, args)
fun invokeOriginalMember(member: Member, vararg args: Any?): Any? = YukiHookHelper.invokeOriginalMember(member, instance, args)
override fun toString() = "HookParamWrapper[$baseParam]"
}

View File

@@ -173,6 +173,23 @@ internal object YukiHookHelper {
return Pair(hookedMembers, isAlreadyHook)
}
/**
* 执行原始 [Member]
*
* 未进行 Hook 的 [Member]
* @param member 实例
* @param args 参数实例
* @return [Any] or null
*/
internal fun invokeOriginalMember(member: Member, instance: Any?, vararg args: Any?): Any? {
val isHookedMember = YukiHookedMembers.hookedMembers.any { it.member.toString() == member.toString() }
val isQueueMethod = YukiHookedMembers.hookedQueueMethods.any { it.value.any { e -> e.member.toString() == member.toString() } }
val isQueueConstructor = YukiHookedMembers.hookedQueueConstructors.any { it.value.any { e -> e.member.toString() == member.toString() } }
return if (isHookedMember || isQueueMethod || isQueueConstructor)
XposedBridge.invokeOriginalMethod(member, instance, args)
else null
}
/**
* 兼容对接 Hook 回调接口
* @return [XC_MethodHook] 原始接口