Merge code to YukiHookXposedBridge.kt and change optIn usage

This commit is contained in:
2022-04-03 21:13:48 +08:00
parent af7dcb41a9
commit d659251fda
18 changed files with 231 additions and 116 deletions

View File

@@ -233,7 +233,7 @@ class YukiHookXposedProcessor : SymbolProcessorProvider {
("package $packageName\n" + ("package $packageName\n" +
"\n" + "\n" +
"import androidx.annotation.Keep\n" + "import androidx.annotation.Keep\n" +
"import com.highcapable.yukihookapi.YukiHookAPI\n" + "import com.highcapable.yukihookapi.hook.xposed.bridge.YukiHookXposedBridge\n" +
"import com.highcapable.yukihookapi.hook.xposed.YukiHookModuleStatus\n" + "import com.highcapable.yukihookapi.hook.xposed.YukiHookModuleStatus\n" +
"import com.highcapable.yukihookapi.hook.log.loggerE\n" + "import com.highcapable.yukihookapi.hook.log.loggerE\n" +
"import de.robv.android.xposed.IXposedHookLoadPackage\n" + "import de.robv.android.xposed.IXposedHookLoadPackage\n" +
@@ -241,7 +241,7 @@ class YukiHookXposedProcessor : SymbolProcessorProvider {
"import de.robv.android.xposed.XposedHelpers\n" + "import de.robv.android.xposed.XposedHelpers\n" +
"import de.robv.android.xposed.XposedBridge\n" + "import de.robv.android.xposed.XposedBridge\n" +
"import de.robv.android.xposed.callbacks.XC_LoadPackage\n" + "import de.robv.android.xposed.callbacks.XC_LoadPackage\n" +
"import com.highcapable.yukihookapi.annotation.DoNotUseAPI\n" + "import com.highcapable.yukihookapi.annotation.YukiGenerateApi\n" +
"import $packageName.$className\n" + "import $packageName.$className\n" +
"\n" + "\n" +
"/**\n" + "/**\n" +
@@ -256,7 +256,7 @@ class YukiHookXposedProcessor : SymbolProcessorProvider {
" * Powered by YukiHookAPI (C) HighCapable 2022\n" + " * Powered by YukiHookAPI (C) HighCapable 2022\n" +
" */\n" + " */\n" +
"@Keep\n" + "@Keep\n" +
"@DoNotUseAPI\n" + "@YukiGenerateApi\n" +
"class $className$xposedClassShortName : IXposedHookLoadPackage {\n" + "class $className$xposedClassShortName : IXposedHookLoadPackage {\n" +
"\n" + "\n" +
" override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam?) {\n" + " override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam?) {\n" +
@@ -264,13 +264,13 @@ class YukiHookXposedProcessor : SymbolProcessorProvider {
" try {\n" + " try {\n" +
" $className().apply {\n" + " $className().apply {\n" +
" onInit()\n" + " onInit()\n" +
" if (YukiHookAPI.isXposedCallbackSetUp) {\n" + " if (YukiHookXposedBridge.isXposedCallbackSetUp) {\n" +
" loggerE(tag = \"YukiHookAPI\", msg = \"You cannot loading a hooker in \\\"onInit\\\" method! Aborted\")\n" + " loggerE(tag = \"YukiHookAPI\", msg = \"You cannot loading a hooker in \\\"onInit\\\" method! Aborted\")\n" +
" return\n" + " return\n" +
" }\n" + " }\n" +
" onHook()\n" + " onHook()\n" +
" }\n" + " }\n" +
" YukiHookAPI.onXposedInitialized()\n" + " YukiHookXposedBridge.callXposedInitialized()\n" +
" } catch (e: Throwable) {\n" + " } catch (e: Throwable) {\n" +
" loggerE(tag = \"YukiHookAPI\", msg = \"YukiHookAPI try to load HookEntryClass failed\", e = e)\n" + " loggerE(tag = \"YukiHookAPI\", msg = \"YukiHookAPI try to load HookEntryClass failed\", e = e)\n" +
" }\n" + " }\n" +
@@ -304,10 +304,10 @@ class YukiHookXposedProcessor : SymbolProcessorProvider {
" -1\n" + " -1\n" +
" }\n" + " }\n" +
" })\n" + " })\n" +
" YukiHookAPI.isModulePackageXposedEnv = true\n" + " YukiHookXposedBridge.isModulePackageXposedEnv = true\n" +
" }\n" + " }\n" +
" YukiHookAPI.modulePackageName = \"$realPackageName\"\n" + " YukiHookXposedBridge.modulePackageName = \"$realPackageName\"\n" +
" YukiHookAPI.onXposedLoaded(lpparam)\n" + " YukiHookXposedBridge.callXposedLoaded(lpparam)\n" +
" }\n" + " }\n" +
"}").toByteArray() "}").toByteArray()
) )

View File

@@ -20,11 +20,21 @@ javadoc {
kotlin { kotlin {
sourceSets.main { kotlin.srcDir("src/api/kotlin") } sourceSets.main { kotlin.srcDir("src/api/kotlin") }
sourceSets { all { languageSettings { optIn('com.highcapable.yukihookapi.annotation.DoNotUseAPI') } } } sourceSets {
all {
languageSettings {
optIn('com.highcapable.yukihookapi.annotation.YukiPrivateApi')
optIn('com.highcapable.yukihookapi.annotation.YukiGenerateApi')
}
}
}
} }
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach { tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
kotlinOptions { freeCompilerArgs += "-opt-in=com.highcapable.yukihookapi.annotation.DoNotUseAPI" } kotlinOptions {
freeCompilerArgs += "-opt-in=com.highcapable.yukihookapi.annotation.YukiPrivateApi"
freeCompilerArgs += "-opt-in=com.highcapable.yukihookapi.annotation.YukiGenerateApi"
}
} }
dependencies { dependencies {

View File

@@ -33,7 +33,6 @@ import android.app.Application
import android.content.Context import android.content.Context
import com.highcapable.yukihookapi.YukiHookAPI.configs import com.highcapable.yukihookapi.YukiHookAPI.configs
import com.highcapable.yukihookapi.YukiHookAPI.encase import com.highcapable.yukihookapi.YukiHookAPI.encase
import com.highcapable.yukihookapi.annotation.DoNotUseAPI
import com.highcapable.yukihookapi.hook.core.finder.ConstructorFinder import com.highcapable.yukihookapi.hook.core.finder.ConstructorFinder
import com.highcapable.yukihookapi.hook.core.finder.FieldFinder import com.highcapable.yukihookapi.hook.core.finder.FieldFinder
import com.highcapable.yukihookapi.hook.core.finder.MethodFinder import com.highcapable.yukihookapi.hook.core.finder.MethodFinder
@@ -43,6 +42,7 @@ import com.highcapable.yukihookapi.hook.log.*
import com.highcapable.yukihookapi.hook.param.PackageParam import com.highcapable.yukihookapi.hook.param.PackageParam
import com.highcapable.yukihookapi.hook.param.wrapper.PackageParamWrapper import com.highcapable.yukihookapi.hook.param.wrapper.PackageParamWrapper
import com.highcapable.yukihookapi.hook.store.MemberCacheStore import com.highcapable.yukihookapi.hook.store.MemberCacheStore
import com.highcapable.yukihookapi.hook.xposed.bridge.YukiHookXposedBridge
import com.highcapable.yukihookapi.hook.xposed.prefs.YukiHookModulePrefs import com.highcapable.yukihookapi.hook.xposed.prefs.YukiHookModulePrefs
import de.robv.android.xposed.XposedBridge import de.robv.android.xposed.XposedBridge
import de.robv.android.xposed.callbacks.XC_LoadPackage import de.robv.android.xposed.callbacks.XC_LoadPackage
@@ -62,14 +62,11 @@ import java.lang.reflect.Method
*/ */
object YukiHookAPI { object YukiHookAPI {
/** Xposed Hook API 方法体回调 */
private var packageParamCallback: (PackageParam.() -> Unit)? = null
/** 是否还未输出欢迎信息 */ /** 是否还未输出欢迎信息 */
private var isShowSplashLogOnceTime = true private var isShowSplashLogOnceTime = true
/** Xposed 是否装载完成 */ /** 标识是否从自定义 Hook API 装载 */
private var isXposedInitialized = false internal var isLoadedFromBaseContext = false
/** 获取当前 [YukiHookAPI] 的版本 */ /** 获取当前 [YukiHookAPI] 的版本 */
const val API_VERSION_NAME = "1.0.69" const val API_VERSION_NAME = "1.0.69"
@@ -77,39 +74,6 @@ object YukiHookAPI {
/** 获取当前 [YukiHookAPI] 的版本号 */ /** 获取当前 [YukiHookAPI] 的版本号 */
const val API_VERSION_CODE = 14 const val API_VERSION_CODE = 14
/**
* 模块是否装载了 Xposed 回调方法
*
* - ❗此变量为私有功能性 API - 你不应该手动调用此变量
* @return [Boolean]
*/
@DoNotUseAPI
val isXposedCallbackSetUp
get() = !isXposedInitialized && packageParamCallback != null
/**
* 当前 Hook 的对象是模块自身
*
* - ❗这是私有 API - 请勿手动修改 - 会引发未知异常
*/
@DoNotUseAPI
var isModulePackageXposedEnv = false
/**
* 预设的 Xposed 模块包名
*
* - ❗这是私有 API - 请勿手动修改 - 会引发未知异常
*/
@DoNotUseAPI
var modulePackageName = ""
/**
* 标识是否从自定义 Hook API 装载
*
* - ❗这是私有 API - 请勿手动修改 - 否则会导致功能判断错误
*/
internal var isLoadedFromBaseContext = false
/** /**
* 获取当前 Hook 框架的名称 * 获取当前 Hook 框架的名称
* *
@@ -201,32 +165,11 @@ object YukiHookAPI {
} }
/** /**
* 配置 [YukiHookAPI] 相关参数 * 装载 Xposed API 回调核心实现方法
*
* 详情请参考 [configs 方法](https://github.com/fankes/YukiHookAPI/wiki/API-%E5%9F%BA%E6%9C%AC%E9%85%8D%E7%BD%AE#configs-%E6%96%B9%E6%B3%95)
* @param initiate 方法体
*/
fun configs(initiate: Configs.() -> Unit) = Configs.apply(initiate).build()
/**
* 标识 Xposed API 装载完成
*
* - ❗装载代码将自动生成 - 你不应该手动使用此方法装载 Xposed 模块事件
*/
@DoNotUseAPI
fun onXposedInitialized() {
isXposedInitialized = true
}
/**
* 装载 Xposed API 回调
*
* - ❗装载代码将自动生成 - 你不应该手动使用此方法装载 Xposed 模块事件
* @param lpparam Xposed [XC_LoadPackage.LoadPackageParam] * @param lpparam Xposed [XC_LoadPackage.LoadPackageParam]
*/ */
@DoNotUseAPI internal fun onXposedLoaded(lpparam: XC_LoadPackage.LoadPackageParam) =
fun onXposedLoaded(lpparam: XC_LoadPackage.LoadPackageParam) = YukiHookXposedBridge.packageParamCallback?.invoke(
packageParamCallback?.invoke(
PackageParam( PackageParam(
PackageParamWrapper( PackageParamWrapper(
packageName = lpparam.packageName, packageName = lpparam.packageName,
@@ -237,6 +180,14 @@ object YukiHookAPI {
).apply { printSplashLog() } ).apply { printSplashLog() }
) )
/**
* 配置 [YukiHookAPI] 相关参数
*
* 详情请参考 [configs 方法](https://github.com/fankes/YukiHookAPI/wiki/API-%E5%9F%BA%E6%9C%AC%E9%85%8D%E7%BD%AE#configs-%E6%96%B9%E6%B3%95)
* @param initiate 方法体
*/
fun configs(initiate: Configs.() -> Unit) = Configs.apply(initiate).build()
/** /**
* 作为模块装载调用入口方法 - Xposed API * 作为模块装载调用入口方法 - Xposed API
* *
@@ -248,7 +199,7 @@ object YukiHookAPI {
fun encase(initiate: PackageParam.() -> Unit) { fun encase(initiate: PackageParam.() -> Unit) {
isLoadedFromBaseContext = false isLoadedFromBaseContext = false
if (hasXposedBridge) if (hasXposedBridge)
packageParamCallback = initiate YukiHookXposedBridge.packageParamCallback = initiate
else printNoXposedEnvLog() else printNoXposedEnvLog()
} }
@@ -264,7 +215,7 @@ object YukiHookAPI {
fun encase(vararg hooker: YukiBaseHooker) { fun encase(vararg hooker: YukiBaseHooker) {
isLoadedFromBaseContext = false isLoadedFromBaseContext = false
if (hasXposedBridge) if (hasXposedBridge)
packageParamCallback = { YukiHookXposedBridge.packageParamCallback = {
if (hooker.isNotEmpty()) if (hooker.isNotEmpty())
hooker.forEach { it.assignInstance(packageParam = this) } hooker.forEach { it.assignInstance(packageParam = this) }
else yLoggerE(msg = "Failed to passing \"encase\" method because your hooker param is empty") else yLoggerE(msg = "Failed to passing \"encase\" method because your hooker param is empty")
@@ -323,7 +274,7 @@ object YukiHookAPI {
/** 输出欢迎信息调试日志 */ /** 输出欢迎信息调试日志 */
private fun printSplashLog() { private fun printSplashLog() {
if (Configs.isDebug.not() || isShowSplashLogOnceTime.not() || isModulePackageXposedEnv) return if (Configs.isDebug.not() || isShowSplashLogOnceTime.not() || YukiHookXposedBridge.isModulePackageXposedEnv) return
isShowSplashLogOnceTime = false isShowSplashLogOnceTime = false
yLoggerI(msg = "Welcome to YukiHookAPI $API_VERSION_NAME($API_VERSION_CODE)! Using $executorName API $executorVersion") yLoggerI(msg = "Welcome to YukiHookAPI $API_VERSION_NAME($API_VERSION_CODE)! Using $executorName API $executorVersion")
} }

View File

@@ -46,8 +46,8 @@ package com.highcapable.yukihookapi.annotation
) )
@Retention(AnnotationRetention.BINARY) @Retention(AnnotationRetention.BINARY)
/** /**
* - 不可在非指定区域被使用的隐藏 API * - 标记为自动生成调用的 API
* *
* 此功能除继承和接口外不应该在这里被调用 * 此功能除继承和接口外不应该在这里被调用
*/ */
annotation class DoNotUseAPI annotation class YukiGenerateApi

View File

@@ -0,0 +1,53 @@
/*
* YukiHookAPI - An efficient Kotlin version of the Xposed Hook API.
* Copyright (C) 2019-2022 HighCapable
* https://github.com/fankes/YukiHookAPI
*
* MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* This file is Created by fankes on 2022/4/3.
*/
@file:Suppress("OPT_IN_IS_NOT_ENABLED", "EXPERIMENTAL_IS_NOT_ENABLED")
package com.highcapable.yukihookapi.annotation
@RequiresOptIn(level = RequiresOptIn.Level.ERROR)
@MustBeDocumented
@Target(
AnnotationTarget.CLASS,
AnnotationTarget.CONSTRUCTOR,
AnnotationTarget.FUNCTION,
AnnotationTarget.ANNOTATION_CLASS,
AnnotationTarget.PROPERTY,
AnnotationTarget.FIELD,
AnnotationTarget.LOCAL_VARIABLE,
AnnotationTarget.VALUE_PARAMETER,
AnnotationTarget.PROPERTY_GETTER,
AnnotationTarget.PROPERTY_SETTER,
AnnotationTarget.TYPEALIAS
)
@Retention(AnnotationRetention.BINARY)
/**
* - ❗标记功能为私有功能性 API
*
* 此功能除继承和接口外不应该在这里被调用
*/
internal annotation class YukiPrivateApi

View File

@@ -31,7 +31,7 @@ package com.highcapable.yukihookapi.hook.core
import android.os.SystemClock import android.os.SystemClock
import com.highcapable.yukihookapi.YukiHookAPI import com.highcapable.yukihookapi.YukiHookAPI
import com.highcapable.yukihookapi.annotation.DoNotUseAPI import com.highcapable.yukihookapi.annotation.YukiPrivateApi
import com.highcapable.yukihookapi.hook.bean.HookClass import com.highcapable.yukihookapi.hook.bean.HookClass
import com.highcapable.yukihookapi.hook.core.finder.ConstructorFinder import com.highcapable.yukihookapi.hook.core.finder.ConstructorFinder
import com.highcapable.yukihookapi.hook.core.finder.FieldFinder import com.highcapable.yukihookapi.hook.core.finder.FieldFinder
@@ -96,7 +96,7 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl
* @throws IllegalStateException 如果必要参数没有被设置 * @throws IllegalStateException 如果必要参数没有被设置
* @return [Result] * @return [Result]
*/ */
@DoNotUseAPI @YukiPrivateApi
fun hook(): Result { fun hook(): Result {
if (YukiHookAPI.hasXposedBridge.not()) return Result() if (YukiHookAPI.hasXposedBridge.not()) return Result()
return if (hookMembers.isEmpty()) error("Hook Members is empty,hook aborted") return if (hookMembers.isEmpty()) error("Hook Members is empty,hook aborted")
@@ -370,7 +370,7 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl
* - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法 * - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法
* @return [Result] * @return [Result]
*/ */
@DoNotUseAPI @YukiPrivateApi
fun build() = Result() fun build() = Result()
/** /**
@@ -378,7 +378,7 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl
* *
* - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法 * - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法
*/ */
@DoNotUseAPI @YukiPrivateApi
fun hook() { fun hook() {
if (YukiHookAPI.hasXposedBridge.not() || isDisableMemberRunHook) return if (YukiHookAPI.hasXposedBridge.not() || isDisableMemberRunHook) return
if (hookClass.instance == null) { if (hookClass.instance == null) {

View File

@@ -29,7 +29,7 @@
package com.highcapable.yukihookapi.hook.core.finder package com.highcapable.yukihookapi.hook.core.finder
import com.highcapable.yukihookapi.annotation.DoNotUseAPI import com.highcapable.yukihookapi.annotation.YukiPrivateApi
import com.highcapable.yukihookapi.hook.core.YukiHookCreater import com.highcapable.yukihookapi.hook.core.YukiHookCreater
import com.highcapable.yukihookapi.hook.core.finder.base.BaseFinder import com.highcapable.yukihookapi.hook.core.finder.base.BaseFinder
import com.highcapable.yukihookapi.hook.core.finder.type.ModifierRules import com.highcapable.yukihookapi.hook.core.finder.type.ModifierRules
@@ -147,7 +147,7 @@ class ConstructorFinder(
* - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法 * - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法
* @return [Result] * @return [Result]
*/ */
@DoNotUseAPI @YukiPrivateApi
override fun build(isBind: Boolean) = try { override fun build(isBind: Boolean) = try {
if (classSet != null) { if (classSet != null) {
runBlocking { runBlocking {
@@ -168,7 +168,7 @@ class ConstructorFinder(
* @param throwable 异常 * @param throwable 异常
* @return [Result] * @return [Result]
*/ */
@DoNotUseAPI @YukiPrivateApi
override fun failure(throwable: Throwable?) = Result(isNoSuch = true, throwable) override fun failure(throwable: Throwable?) = Result(isNoSuch = true, throwable)
/** /**
@@ -197,7 +197,7 @@ class ConstructorFinder(
* *
* - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法 * - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法
*/ */
@DoNotUseAPI @YukiPrivateApi
internal fun build() { internal fun build() {
if (classSet == null) return if (classSet == null) return
if (remedyPlans.isNotEmpty()) run { if (remedyPlans.isNotEmpty()) run {

View File

@@ -30,7 +30,7 @@
package com.highcapable.yukihookapi.hook.core.finder package com.highcapable.yukihookapi.hook.core.finder
import android.os.SystemClock import android.os.SystemClock
import com.highcapable.yukihookapi.annotation.DoNotUseAPI import com.highcapable.yukihookapi.annotation.YukiPrivateApi
import com.highcapable.yukihookapi.hook.core.YukiHookCreater import com.highcapable.yukihookapi.hook.core.YukiHookCreater
import com.highcapable.yukihookapi.hook.core.finder.base.BaseFinder import com.highcapable.yukihookapi.hook.core.finder.base.BaseFinder
import com.highcapable.yukihookapi.hook.core.finder.type.ModifierRules import com.highcapable.yukihookapi.hook.core.finder.type.ModifierRules
@@ -123,7 +123,7 @@ class FieldFinder(
* @return [Result] * @return [Result]
* @throws IllegalStateException 如果 [name] 没有被设置 * @throws IllegalStateException 如果 [name] 没有被设置
*/ */
@DoNotUseAPI @YukiPrivateApi
override fun build(isBind: Boolean) = try { override fun build(isBind: Boolean) = try {
if (classSet != null) { if (classSet != null) {
runBlocking { runBlocking {
@@ -147,7 +147,7 @@ class FieldFinder(
* @param throwable 异常 * @param throwable 异常
* @return [Result] * @return [Result]
*/ */
@DoNotUseAPI @YukiPrivateApi
override fun failure(throwable: Throwable?) = Result(isNoSuch = true, throwable) override fun failure(throwable: Throwable?) = Result(isNoSuch = true, throwable)
/** /**

View File

@@ -29,7 +29,7 @@
package com.highcapable.yukihookapi.hook.core.finder package com.highcapable.yukihookapi.hook.core.finder
import com.highcapable.yukihookapi.annotation.DoNotUseAPI import com.highcapable.yukihookapi.annotation.YukiPrivateApi
import com.highcapable.yukihookapi.hook.core.YukiHookCreater import com.highcapable.yukihookapi.hook.core.YukiHookCreater
import com.highcapable.yukihookapi.hook.core.finder.base.BaseFinder import com.highcapable.yukihookapi.hook.core.finder.base.BaseFinder
import com.highcapable.yukihookapi.hook.core.finder.type.ModifierRules import com.highcapable.yukihookapi.hook.core.finder.type.ModifierRules
@@ -192,7 +192,7 @@ class MethodFinder(
* @param isBind 是否将结果设置到目标 [YukiHookCreater.MemberHookCreater] * @param isBind 是否将结果设置到目标 [YukiHookCreater.MemberHookCreater]
* @return [Result] * @return [Result]
*/ */
@DoNotUseAPI @YukiPrivateApi
override fun build(isBind: Boolean) = try { override fun build(isBind: Boolean) = try {
if (classSet != null) { if (classSet != null) {
runBlocking { runBlocking {
@@ -213,7 +213,7 @@ class MethodFinder(
* @param throwable 异常 * @param throwable 异常
* @return [Result] * @return [Result]
*/ */
@DoNotUseAPI @YukiPrivateApi
override fun failure(throwable: Throwable?) = Result(isNoSuch = true, throwable) override fun failure(throwable: Throwable?) = Result(isNoSuch = true, throwable)
/** /**
@@ -243,7 +243,7 @@ class MethodFinder(
* *
* - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法 * - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法
*/ */
@DoNotUseAPI @YukiPrivateApi
internal fun build() { internal fun build() {
if (classSet == null) return if (classSet == null) return
if (remedyPlans.isNotEmpty()) run { if (remedyPlans.isNotEmpty()) run {

View File

@@ -29,7 +29,7 @@ package com.highcapable.yukihookapi.hook.core.finder.base
import android.os.SystemClock import android.os.SystemClock
import com.highcapable.yukihookapi.YukiHookAPI import com.highcapable.yukihookapi.YukiHookAPI
import com.highcapable.yukihookapi.annotation.DoNotUseAPI import com.highcapable.yukihookapi.annotation.YukiPrivateApi
import com.highcapable.yukihookapi.hook.core.YukiHookCreater import com.highcapable.yukihookapi.hook.core.YukiHookCreater
import com.highcapable.yukihookapi.hook.log.yLoggerE import com.highcapable.yukihookapi.hook.log.yLoggerE
import com.highcapable.yukihookapi.hook.log.yLoggerI import com.highcapable.yukihookapi.hook.log.yLoggerI
@@ -164,7 +164,7 @@ abstract class BaseFinder(
* @param isBind 是否将结果设置到目标 [YukiHookCreater.MemberHookCreater] * @param isBind 是否将结果设置到目标 [YukiHookCreater.MemberHookCreater]
* @return [Any] * @return [Any]
*/ */
@DoNotUseAPI @YukiPrivateApi
abstract fun build(isBind: Boolean = false): Any abstract fun build(isBind: Boolean = false): Any
/** /**
@@ -174,6 +174,6 @@ abstract class BaseFinder(
* @param throwable 异常 * @param throwable 异常
* @return [Any] * @return [Any]
*/ */
@DoNotUseAPI @YukiPrivateApi
abstract fun failure(throwable: Throwable?): Any abstract fun failure(throwable: Throwable?): Any
} }

View File

@@ -28,7 +28,7 @@
package com.highcapable.yukihookapi.hook.entity package com.highcapable.yukihookapi.hook.entity
import com.highcapable.yukihookapi.YukiHookAPI import com.highcapable.yukihookapi.YukiHookAPI
import com.highcapable.yukihookapi.annotation.DoNotUseAPI import com.highcapable.yukihookapi.annotation.YukiPrivateApi
import com.highcapable.yukihookapi.annotation.xposed.InjectYukiHookWithXposed import com.highcapable.yukihookapi.annotation.xposed.InjectYukiHookWithXposed
import com.highcapable.yukihookapi.hook.param.PackageParam import com.highcapable.yukihookapi.hook.param.PackageParam
import com.highcapable.yukihookapi.hook.xposed.proxy.YukiHookXposedInitProxy import com.highcapable.yukihookapi.hook.xposed.proxy.YukiHookXposedInitProxy
@@ -58,7 +58,7 @@ abstract class YukiBaseHooker : PackageParam() {
* - ❗此方法为私有功能性 API - 你不应该手动调用此方法 * - ❗此方法为私有功能性 API - 你不应该手动调用此方法
* @param packageParam 需要使用的 [PackageParam] * @param packageParam 需要使用的 [PackageParam]
*/ */
@DoNotUseAPI @YukiPrivateApi
internal fun assignInstance(packageParam: PackageParam) { internal fun assignInstance(packageParam: PackageParam) {
baseAssignInstance(packageParam) baseAssignInstance(packageParam)
onHook() onHook()

View File

@@ -31,7 +31,7 @@ package com.highcapable.yukihookapi.hook.param
import android.app.Application import android.app.Application
import android.content.pm.ApplicationInfo import android.content.pm.ApplicationInfo
import com.highcapable.yukihookapi.annotation.DoNotUseAPI import com.highcapable.yukihookapi.annotation.YukiPrivateApi
import com.highcapable.yukihookapi.hook.bean.HookClass import com.highcapable.yukihookapi.hook.bean.HookClass
import com.highcapable.yukihookapi.hook.bean.VariousClass import com.highcapable.yukihookapi.hook.bean.VariousClass
import com.highcapable.yukihookapi.hook.core.YukiHookCreater import com.highcapable.yukihookapi.hook.core.YukiHookCreater
@@ -109,7 +109,7 @@ open class PackageParam(private var wrapper: PackageParamWrapper? = null) {
* - ❗此方法为私有功能性 API - 你不应该手动调用此方法 * - ❗此方法为私有功能性 API - 你不应该手动调用此方法
* @param anotherParam 另一个 [PackageParam] * @param anotherParam 另一个 [PackageParam]
*/ */
@DoNotUseAPI @YukiPrivateApi
internal fun baseAssignInstance(anotherParam: PackageParam) { internal fun baseAssignInstance(anotherParam: PackageParam) {
thisParam.wrapper = anotherParam.wrapper thisParam.wrapper = anotherParam.wrapper
} }

View File

@@ -27,7 +27,7 @@
*/ */
package com.highcapable.yukihookapi.hook.param.wrapper package com.highcapable.yukihookapi.hook.param.wrapper
import com.highcapable.yukihookapi.annotation.DoNotUseAPI import com.highcapable.yukihookapi.annotation.YukiPrivateApi
import com.highcapable.yukihookapi.hook.param.HookParam import com.highcapable.yukihookapi.hook.param.HookParam
import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XC_MethodHook
import de.robv.android.xposed.XposedBridge import de.robv.android.xposed.XposedBridge
@@ -39,7 +39,7 @@ import java.lang.reflect.Member
* - ❗这是一个私有 API - 请不要在外部使用 * - ❗这是一个私有 API - 请不要在外部使用
* @param baseParam 对接 [XC_MethodHook.MethodHookParam] * @param baseParam 对接 [XC_MethodHook.MethodHookParam]
*/ */
@DoNotUseAPI @YukiPrivateApi
class HookParamWrapper(private val baseParam: XC_MethodHook.MethodHookParam) { class HookParamWrapper(private val baseParam: XC_MethodHook.MethodHookParam) {
/** /**

View File

@@ -30,7 +30,7 @@
package com.highcapable.yukihookapi.hook.param.wrapper package com.highcapable.yukihookapi.hook.param.wrapper
import android.content.pm.ApplicationInfo import android.content.pm.ApplicationInfo
import com.highcapable.yukihookapi.annotation.DoNotUseAPI import com.highcapable.yukihookapi.annotation.YukiPrivateApi
import com.highcapable.yukihookapi.hook.param.PackageParam import com.highcapable.yukihookapi.hook.param.PackageParam
/** /**
@@ -42,7 +42,7 @@ import com.highcapable.yukihookapi.hook.param.PackageParam
* @param appClassLoader APP [ClassLoader] * @param appClassLoader APP [ClassLoader]
* @param appInfo APP [ApplicationInfo] * @param appInfo APP [ApplicationInfo]
*/ */
@DoNotUseAPI @YukiPrivateApi
class PackageParamWrapper( class PackageParamWrapper(
var packageName: String, var packageName: String,
var processName: String, var processName: String,

View File

@@ -27,14 +27,14 @@
*/ */
package com.highcapable.yukihookapi.hook.utils package com.highcapable.yukihookapi.hook.utils
import com.highcapable.yukihookapi.annotation.DoNotUseAPI import com.highcapable.yukihookapi.annotation.YukiPrivateApi
/** /**
* 计算方法执行耗时 * 计算方法执行耗时
* @param block 方法块 * @param block 方法块
* @return [RunBlockResult] * @return [RunBlockResult]
*/ */
@DoNotUseAPI @YukiPrivateApi
inline fun <R> runBlocking(block: () -> R): RunBlockResult { inline fun <R> runBlocking(block: () -> R): RunBlockResult {
val start = System.currentTimeMillis() val start = System.currentTimeMillis()
block() block()
@@ -45,7 +45,7 @@ inline fun <R> runBlocking(block: () -> R): RunBlockResult {
* 构造耗时计算结果类 * 构造耗时计算结果类
* @param after 耗时 * @param after 耗时
*/ */
@DoNotUseAPI @YukiPrivateApi
class RunBlockResult(private val after: Long) { class RunBlockResult(private val after: Long) {
/** /**

View File

@@ -29,7 +29,7 @@ package com.highcapable.yukihookapi.hook.xposed
import android.app.Activity import android.app.Activity
import androidx.annotation.Keep import androidx.annotation.Keep
import com.highcapable.yukihookapi.annotation.DoNotUseAPI import com.highcapable.yukihookapi.annotation.YukiPrivateApi
import com.highcapable.yukihookapi.hook.factory.isModuleActive import com.highcapable.yukihookapi.hook.factory.isModuleActive
import com.highcapable.yukihookapi.hook.factory.isTaiChiModuleActive import com.highcapable.yukihookapi.hook.factory.isTaiChiModuleActive
import com.highcapable.yukihookapi.hook.factory.isXposedModuleActive import com.highcapable.yukihookapi.hook.factory.isXposedModuleActive
@@ -92,7 +92,7 @@ object YukiHookModuleStatus {
* @return [Boolean] * @return [Boolean]
*/ */
@Keep @Keep
@DoNotUseAPI @YukiPrivateApi
@JvmName(IS_ACTIVE_METHOD_NAME) @JvmName(IS_ACTIVE_METHOD_NAME)
internal fun isActive(): Boolean { internal fun isActive(): Boolean {
yLoggerD(msg = IS_ACTIVE_METHOD_NAME, isDisableLog = true) yLoggerD(msg = IS_ACTIVE_METHOD_NAME, isDisableLog = true)

View File

@@ -0,0 +1,98 @@
/*
* YukiHookAPI - An efficient Kotlin version of the Xposed Hook API.
* Copyright (C) 2019-2022 HighCapable
* https://github.com/fankes/YukiHookAPI
*
* MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* This file is Created by fankes on 2022/4/3.
*/
@file:Suppress("unused")
package com.highcapable.yukihookapi.hook.xposed.bridge
import com.highcapable.yukihookapi.YukiHookAPI
import com.highcapable.yukihookapi.annotation.YukiGenerateApi
import com.highcapable.yukihookapi.hook.param.PackageParam
import de.robv.android.xposed.IXposedHookLoadPackage
import de.robv.android.xposed.callbacks.XC_LoadPackage
/**
* 这是一个 Xposed 模块的入口装载类实现桥
*
* 实现与 [IXposedHookLoadPackage] 接口通讯
*
* - ❗装载代码将自动生成 - 请勿修改或移动以及重命名此类的任何方法与变量
*/
@YukiGenerateApi
object YukiHookXposedBridge {
/** Xposed 是否装载完成 */
private var isXposedInitialized = false
/** Xposed Hook API 方法体回调 */
internal var packageParamCallback: (PackageParam.() -> Unit)? = null
/**
* 模块是否装载了 Xposed 回调方法
*
* - ❗装载代码将自动生成 - 请勿手动修改 - 会引发未知异常
* @return [Boolean]
*/
@YukiGenerateApi
val isXposedCallbackSetUp
get() = !isXposedInitialized && packageParamCallback != null
/**
* 当前 Hook 的对象是模块自身
*
* - ❗装载代码将自动生成 - 请勿手动修改 - 会引发未知异常
*/
@YukiGenerateApi
var isModulePackageXposedEnv = false
/**
* 预设的 Xposed 模块包名
*
* - ❗装载代码将自动生成 - 请勿手动修改 - 会引发未知异常
*/
@YukiGenerateApi
var modulePackageName = ""
/**
* 标识 Xposed API 装载完成
*
* - ❗装载代码将自动生成 - 你不应该手动使用此方法装载 Xposed 模块事件
*/
@YukiGenerateApi
fun callXposedInitialized() {
isXposedInitialized = true
}
/**
* 装载 Xposed API 回调
*
* - ❗装载代码将自动生成 - 你不应该手动使用此方法装载 Xposed 模块事件
* @param lpparam Xposed [XC_LoadPackage.LoadPackageParam]
*/
@YukiGenerateApi
fun callXposedLoaded(lpparam: XC_LoadPackage.LoadPackageParam) = YukiHookAPI.onXposedLoaded(lpparam)
}

View File

@@ -32,6 +32,7 @@ package com.highcapable.yukihookapi.hook.xposed.prefs
import android.content.Context import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import com.highcapable.yukihookapi.YukiHookAPI import com.highcapable.yukihookapi.YukiHookAPI
import com.highcapable.yukihookapi.hook.xposed.bridge.YukiHookXposedBridge
import com.highcapable.yukihookapi.hook.xposed.prefs.data.PrefsData import com.highcapable.yukihookapi.hook.xposed.prefs.data.PrefsData
import de.robv.android.xposed.XSharedPreferences import de.robv.android.xposed.XSharedPreferences
import java.io.File import java.io.File
@@ -57,7 +58,7 @@ import java.io.File
class YukiHookModulePrefs(private val context: Context? = null) { class YukiHookModulePrefs(private val context: Context? = null) {
/** 存储名称 - 默认包名 + _preferences */ /** 存储名称 - 默认包名 + _preferences */
private var prefsName = "${YukiHookAPI.modulePackageName.ifBlank { context?.packageName ?: "" }}_preferences" private var prefsName = "${YukiHookXposedBridge.modulePackageName.ifBlank { context?.packageName ?: "" }}_preferences"
/** 是否为 Xposed 环境 */ /** 是否为 Xposed 环境 */
private val isXposedEnvironment = YukiHookAPI.hasXposedBridge private val isXposedEnvironment = YukiHookAPI.hasXposedBridge
@@ -80,9 +81,11 @@ class YukiHookModulePrefs(private val context: Context? = null) {
/** 是否使用键值缓存 */ /** 是否使用键值缓存 */
private var isUsingKeyValueCache = YukiHookAPI.Configs.isEnableModulePrefsCache private var isUsingKeyValueCache = YukiHookAPI.Configs.isEnableModulePrefsCache
/** 检查是否处于自定义 Hook API 状态 */ /** 检查 API 装载状态 */
private fun checkApiInBaseContext() { private fun checkApi() {
if (YukiHookAPI.isLoadedFromBaseContext) error("YukiHookModulePrefs not allowed in Custom Hook API") if (YukiHookAPI.isLoadedFromBaseContext) error("YukiHookModulePrefs not allowed in Custom Hook API")
if (YukiHookAPI.hasXposedBridge && YukiHookXposedBridge.modulePackageName.isBlank())
error("Xposed modulePackageName load failed, please reset and rebuild it")
} }
/** /**
@@ -90,8 +93,8 @@ class YukiHookModulePrefs(private val context: Context? = null) {
* @return [XSharedPreferences] * @return [XSharedPreferences]
*/ */
private val xPref private val xPref
get() = XSharedPreferences(YukiHookAPI.modulePackageName, prefsName).apply { get() = XSharedPreferences(YukiHookXposedBridge.modulePackageName, prefsName).apply {
checkApiInBaseContext() checkApi()
makeWorldReadable() makeWorldReadable()
reload() reload()
} }
@@ -102,11 +105,11 @@ class YukiHookModulePrefs(private val context: Context? = null) {
*/ */
private val sPref private val sPref
get() = try { get() = try {
checkApiInBaseContext() checkApi()
context?.getSharedPreferences(prefsName, Context.MODE_WORLD_READABLE) context?.getSharedPreferences(prefsName, Context.MODE_WORLD_READABLE)
?: error("If you want to use module prefs,you must set the context instance first") ?: error("If you want to use module prefs,you must set the context instance first")
} catch (_: Throwable) { } catch (_: Throwable) {
checkApiInBaseContext() checkApi()
context?.getSharedPreferences(prefsName, Context.MODE_PRIVATE) context?.getSharedPreferences(prefsName, Context.MODE_PRIVATE)
?: error("If you want to use module prefs,you must set the context instance first") ?: error("If you want to use module prefs,you must set the context instance first")
} }