From d659251fda7ad84c8091b059777d5ce20e295749 Mon Sep 17 00:00:00 2001 From: Fankesyooni Date: Sun, 3 Apr 2022 21:13:48 +0800 Subject: [PATCH] Merge code to YukiHookXposedBridge.kt and change optIn usage --- .../YukiHookXposedProcessor.kt | 16 +-- yukihookapi/build.gradle | 14 ++- .../highcapable/yukihookapi/YukiHookAPI.kt | 83 ++++------------ .../{DoNotUseAPI.kt => YukiGenerateApi.kt} | 4 +- .../yukihookapi/annotation/YukiPrivateApi.kt | 53 ++++++++++ .../yukihookapi/hook/core/YukiHookCreater.kt | 8 +- .../hook/core/finder/ConstructorFinder.kt | 8 +- .../hook/core/finder/FieldFinder.kt | 6 +- .../hook/core/finder/MethodFinder.kt | 8 +- .../hook/core/finder/base/BaseFinder.kt | 6 +- .../yukihookapi/hook/entity/YukiBaseHooker.kt | 4 +- .../yukihookapi/hook/param/PackageParam.kt | 4 +- .../hook/param/wrapper/HookParamWrapper.kt | 4 +- .../hook/param/wrapper/PackageParamWrapper.kt | 4 +- .../yukihookapi/hook/utils/UtilsFactory.kt | 6 +- .../hook/xposed/YukiHookModuleStatus.kt | 4 +- .../xposed/bridge/YukiHookXposedBridge.kt | 98 +++++++++++++++++++ .../hook/xposed/prefs/YukiHookModulePrefs.kt | 17 ++-- 18 files changed, 231 insertions(+), 116 deletions(-) rename yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/annotation/{DoNotUseAPI.kt => YukiGenerateApi.kt} (95%) create mode 100644 yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/annotation/YukiPrivateApi.kt create mode 100644 yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/bridge/YukiHookXposedBridge.kt diff --git a/yukihookapi-ksp-xposed/src/api/kotlin/com/highcapable/yukihookapi_ksp_xposed/YukiHookXposedProcessor.kt b/yukihookapi-ksp-xposed/src/api/kotlin/com/highcapable/yukihookapi_ksp_xposed/YukiHookXposedProcessor.kt index 1885545b..73d4fbfb 100644 --- a/yukihookapi-ksp-xposed/src/api/kotlin/com/highcapable/yukihookapi_ksp_xposed/YukiHookXposedProcessor.kt +++ b/yukihookapi-ksp-xposed/src/api/kotlin/com/highcapable/yukihookapi_ksp_xposed/YukiHookXposedProcessor.kt @@ -233,7 +233,7 @@ class YukiHookXposedProcessor : SymbolProcessorProvider { ("package $packageName\n" + "\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.log.loggerE\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.XposedBridge\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" + "\n" + "/**\n" + @@ -256,7 +256,7 @@ class YukiHookXposedProcessor : SymbolProcessorProvider { " * Powered by YukiHookAPI (C) HighCapable 2022\n" + " */\n" + "@Keep\n" + - "@DoNotUseAPI\n" + + "@YukiGenerateApi\n" + "class $className$xposedClassShortName : IXposedHookLoadPackage {\n" + "\n" + " override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam?) {\n" + @@ -264,13 +264,13 @@ class YukiHookXposedProcessor : SymbolProcessorProvider { " try {\n" + " $className().apply {\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" + " return\n" + " }\n" + " onHook()\n" + " }\n" + - " YukiHookAPI.onXposedInitialized()\n" + + " YukiHookXposedBridge.callXposedInitialized()\n" + " } catch (e: Throwable) {\n" + " loggerE(tag = \"YukiHookAPI\", msg = \"YukiHookAPI try to load HookEntryClass failed\", e = e)\n" + " }\n" + @@ -304,10 +304,10 @@ class YukiHookXposedProcessor : SymbolProcessorProvider { " -1\n" + " }\n" + " })\n" + - " YukiHookAPI.isModulePackageXposedEnv = true\n" + + " YukiHookXposedBridge.isModulePackageXposedEnv = true\n" + " }\n" + - " YukiHookAPI.modulePackageName = \"$realPackageName\"\n" + - " YukiHookAPI.onXposedLoaded(lpparam)\n" + + " YukiHookXposedBridge.modulePackageName = \"$realPackageName\"\n" + + " YukiHookXposedBridge.callXposedLoaded(lpparam)\n" + " }\n" + "}").toByteArray() ) diff --git a/yukihookapi/build.gradle b/yukihookapi/build.gradle index 3dc6d499..a3b6dbe1 100644 --- a/yukihookapi/build.gradle +++ b/yukihookapi/build.gradle @@ -20,11 +20,21 @@ javadoc { 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 { - 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 { diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/YukiHookAPI.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/YukiHookAPI.kt index 7202d086..67b63cd2 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/YukiHookAPI.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/YukiHookAPI.kt @@ -33,7 +33,6 @@ import android.app.Application import android.content.Context import com.highcapable.yukihookapi.YukiHookAPI.configs 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.FieldFinder 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.wrapper.PackageParamWrapper import com.highcapable.yukihookapi.hook.store.MemberCacheStore +import com.highcapable.yukihookapi.hook.xposed.bridge.YukiHookXposedBridge import com.highcapable.yukihookapi.hook.xposed.prefs.YukiHookModulePrefs import de.robv.android.xposed.XposedBridge import de.robv.android.xposed.callbacks.XC_LoadPackage @@ -62,14 +62,11 @@ import java.lang.reflect.Method */ object YukiHookAPI { - /** Xposed Hook API 方法体回调 */ - private var packageParamCallback: (PackageParam.() -> Unit)? = null - /** 是否还未输出欢迎信息 */ private var isShowSplashLogOnceTime = true - /** Xposed 是否装载完成 */ - private var isXposedInitialized = false + /** 标识是否从自定义 Hook API 装载 */ + internal var isLoadedFromBaseContext = false /** 获取当前 [YukiHookAPI] 的版本 */ const val API_VERSION_NAME = "1.0.69" @@ -77,39 +74,6 @@ object YukiHookAPI { /** 获取当前 [YukiHookAPI] 的版本号 */ 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 框架的名称 * @@ -201,32 +165,11 @@ object YukiHookAPI { } /** - * 配置 [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 模块事件 - */ - @DoNotUseAPI - fun onXposedInitialized() { - isXposedInitialized = true - } - - /** - * 装载 Xposed API 回调 - * - * - ❗装载代码将自动生成 - 你不应该手动使用此方法装载 Xposed 模块事件 + * 装载 Xposed API 回调核心实现方法 * @param lpparam Xposed [XC_LoadPackage.LoadPackageParam] */ - @DoNotUseAPI - fun onXposedLoaded(lpparam: XC_LoadPackage.LoadPackageParam) = - packageParamCallback?.invoke( + internal fun onXposedLoaded(lpparam: XC_LoadPackage.LoadPackageParam) = + YukiHookXposedBridge.packageParamCallback?.invoke( PackageParam( PackageParamWrapper( packageName = lpparam.packageName, @@ -237,6 +180,14 @@ object YukiHookAPI { ).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 * @@ -248,7 +199,7 @@ object YukiHookAPI { fun encase(initiate: PackageParam.() -> Unit) { isLoadedFromBaseContext = false if (hasXposedBridge) - packageParamCallback = initiate + YukiHookXposedBridge.packageParamCallback = initiate else printNoXposedEnvLog() } @@ -264,7 +215,7 @@ object YukiHookAPI { fun encase(vararg hooker: YukiBaseHooker) { isLoadedFromBaseContext = false if (hasXposedBridge) - packageParamCallback = { + YukiHookXposedBridge.packageParamCallback = { if (hooker.isNotEmpty()) hooker.forEach { it.assignInstance(packageParam = this) } else yLoggerE(msg = "Failed to passing \"encase\" method because your hooker param is empty") @@ -323,7 +274,7 @@ object YukiHookAPI { /** 输出欢迎信息调试日志 */ private fun printSplashLog() { - if (Configs.isDebug.not() || isShowSplashLogOnceTime.not() || isModulePackageXposedEnv) return + if (Configs.isDebug.not() || isShowSplashLogOnceTime.not() || YukiHookXposedBridge.isModulePackageXposedEnv) return isShowSplashLogOnceTime = false yLoggerI(msg = "Welcome to YukiHookAPI $API_VERSION_NAME($API_VERSION_CODE)! Using $executorName API $executorVersion") } diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/annotation/DoNotUseAPI.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/annotation/YukiGenerateApi.kt similarity index 95% rename from yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/annotation/DoNotUseAPI.kt rename to yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/annotation/YukiGenerateApi.kt index 65a2fc1f..b1df6e2a 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/annotation/DoNotUseAPI.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/annotation/YukiGenerateApi.kt @@ -46,8 +46,8 @@ package com.highcapable.yukihookapi.annotation ) @Retention(AnnotationRetention.BINARY) /** - * - ❗不可在非指定区域被使用的隐藏 API + * - ❗标记为自动生成调用的 API * * 此功能除继承和接口外不应该在这里被调用 */ -annotation class DoNotUseAPI \ No newline at end of file +annotation class YukiGenerateApi \ No newline at end of file diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/annotation/YukiPrivateApi.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/annotation/YukiPrivateApi.kt new file mode 100644 index 00000000..b78c167d --- /dev/null +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/annotation/YukiPrivateApi.kt @@ -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 \ No newline at end of file diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/YukiHookCreater.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/YukiHookCreater.kt index 59028533..f2cf826f 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/YukiHookCreater.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/YukiHookCreater.kt @@ -31,7 +31,7 @@ package com.highcapable.yukihookapi.hook.core import android.os.SystemClock 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.core.finder.ConstructorFinder import com.highcapable.yukihookapi.hook.core.finder.FieldFinder @@ -96,7 +96,7 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl * @throws IllegalStateException 如果必要参数没有被设置 * @return [Result] */ - @DoNotUseAPI + @YukiPrivateApi fun hook(): Result { if (YukiHookAPI.hasXposedBridge.not()) return Result() 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] */ - @DoNotUseAPI + @YukiPrivateApi fun build() = Result() /** @@ -378,7 +378,7 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl * * - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法 */ - @DoNotUseAPI + @YukiPrivateApi fun hook() { if (YukiHookAPI.hasXposedBridge.not() || isDisableMemberRunHook) return if (hookClass.instance == null) { diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/ConstructorFinder.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/ConstructorFinder.kt index 0e9f9d0a..a502a316 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/ConstructorFinder.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/ConstructorFinder.kt @@ -29,7 +29,7 @@ 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.finder.base.BaseFinder import com.highcapable.yukihookapi.hook.core.finder.type.ModifierRules @@ -147,7 +147,7 @@ class ConstructorFinder( * - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法 * @return [Result] */ - @DoNotUseAPI + @YukiPrivateApi override fun build(isBind: Boolean) = try { if (classSet != null) { runBlocking { @@ -168,7 +168,7 @@ class ConstructorFinder( * @param throwable 异常 * @return [Result] */ - @DoNotUseAPI + @YukiPrivateApi override fun failure(throwable: Throwable?) = Result(isNoSuch = true, throwable) /** @@ -197,7 +197,7 @@ class ConstructorFinder( * * - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法 */ - @DoNotUseAPI + @YukiPrivateApi internal fun build() { if (classSet == null) return if (remedyPlans.isNotEmpty()) run { diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/FieldFinder.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/FieldFinder.kt index 74f218b8..155d686b 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/FieldFinder.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/FieldFinder.kt @@ -30,7 +30,7 @@ package com.highcapable.yukihookapi.hook.core.finder 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.finder.base.BaseFinder import com.highcapable.yukihookapi.hook.core.finder.type.ModifierRules @@ -123,7 +123,7 @@ class FieldFinder( * @return [Result] * @throws IllegalStateException 如果 [name] 没有被设置 */ - @DoNotUseAPI + @YukiPrivateApi override fun build(isBind: Boolean) = try { if (classSet != null) { runBlocking { @@ -147,7 +147,7 @@ class FieldFinder( * @param throwable 异常 * @return [Result] */ - @DoNotUseAPI + @YukiPrivateApi override fun failure(throwable: Throwable?) = Result(isNoSuch = true, throwable) /** diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/MethodFinder.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/MethodFinder.kt index 179614fb..2f6ea11e 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/MethodFinder.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/MethodFinder.kt @@ -29,7 +29,7 @@ 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.finder.base.BaseFinder import com.highcapable.yukihookapi.hook.core.finder.type.ModifierRules @@ -192,7 +192,7 @@ class MethodFinder( * @param isBind 是否将结果设置到目标 [YukiHookCreater.MemberHookCreater] * @return [Result] */ - @DoNotUseAPI + @YukiPrivateApi override fun build(isBind: Boolean) = try { if (classSet != null) { runBlocking { @@ -213,7 +213,7 @@ class MethodFinder( * @param throwable 异常 * @return [Result] */ - @DoNotUseAPI + @YukiPrivateApi override fun failure(throwable: Throwable?) = Result(isNoSuch = true, throwable) /** @@ -243,7 +243,7 @@ class MethodFinder( * * - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法 */ - @DoNotUseAPI + @YukiPrivateApi internal fun build() { if (classSet == null) return if (remedyPlans.isNotEmpty()) run { diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/BaseFinder.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/BaseFinder.kt index f1be9487..f86d685c 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/BaseFinder.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/BaseFinder.kt @@ -29,7 +29,7 @@ package com.highcapable.yukihookapi.hook.core.finder.base import android.os.SystemClock 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.log.yLoggerE import com.highcapable.yukihookapi.hook.log.yLoggerI @@ -164,7 +164,7 @@ abstract class BaseFinder( * @param isBind 是否将结果设置到目标 [YukiHookCreater.MemberHookCreater] * @return [Any] */ - @DoNotUseAPI + @YukiPrivateApi abstract fun build(isBind: Boolean = false): Any /** @@ -174,6 +174,6 @@ abstract class BaseFinder( * @param throwable 异常 * @return [Any] */ - @DoNotUseAPI + @YukiPrivateApi abstract fun failure(throwable: Throwable?): Any } \ No newline at end of file diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/entity/YukiBaseHooker.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/entity/YukiBaseHooker.kt index 6cf3edab..f6d34d90 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/entity/YukiBaseHooker.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/entity/YukiBaseHooker.kt @@ -28,7 +28,7 @@ package com.highcapable.yukihookapi.hook.entity 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.hook.param.PackageParam import com.highcapable.yukihookapi.hook.xposed.proxy.YukiHookXposedInitProxy @@ -58,7 +58,7 @@ abstract class YukiBaseHooker : PackageParam() { * - ❗此方法为私有功能性 API - 你不应该手动调用此方法 * @param packageParam 需要使用的 [PackageParam] */ - @DoNotUseAPI + @YukiPrivateApi internal fun assignInstance(packageParam: PackageParam) { baseAssignInstance(packageParam) onHook() diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/PackageParam.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/PackageParam.kt index 40d61424..59c7e171 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/PackageParam.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/PackageParam.kt @@ -31,7 +31,7 @@ package com.highcapable.yukihookapi.hook.param import android.app.Application 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.VariousClass import com.highcapable.yukihookapi.hook.core.YukiHookCreater @@ -109,7 +109,7 @@ open class PackageParam(private var wrapper: PackageParamWrapper? = null) { * - ❗此方法为私有功能性 API - 你不应该手动调用此方法 * @param anotherParam 另一个 [PackageParam] */ - @DoNotUseAPI + @YukiPrivateApi internal fun baseAssignInstance(anotherParam: PackageParam) { thisParam.wrapper = anotherParam.wrapper } diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/wrapper/HookParamWrapper.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/wrapper/HookParamWrapper.kt index 67f85aee..4f19bfa8 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/wrapper/HookParamWrapper.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/wrapper/HookParamWrapper.kt @@ -27,7 +27,7 @@ */ 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 de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XposedBridge @@ -39,7 +39,7 @@ import java.lang.reflect.Member * - ❗这是一个私有 API - 请不要在外部使用 * @param baseParam 对接 [XC_MethodHook.MethodHookParam] */ -@DoNotUseAPI +@YukiPrivateApi class HookParamWrapper(private val baseParam: XC_MethodHook.MethodHookParam) { /** diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/wrapper/PackageParamWrapper.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/wrapper/PackageParamWrapper.kt index 303f8e22..5fad189f 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/wrapper/PackageParamWrapper.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/wrapper/PackageParamWrapper.kt @@ -30,7 +30,7 @@ package com.highcapable.yukihookapi.hook.param.wrapper import android.content.pm.ApplicationInfo -import com.highcapable.yukihookapi.annotation.DoNotUseAPI +import com.highcapable.yukihookapi.annotation.YukiPrivateApi import com.highcapable.yukihookapi.hook.param.PackageParam /** @@ -42,7 +42,7 @@ import com.highcapable.yukihookapi.hook.param.PackageParam * @param appClassLoader APP [ClassLoader] * @param appInfo APP [ApplicationInfo] */ -@DoNotUseAPI +@YukiPrivateApi class PackageParamWrapper( var packageName: String, var processName: String, diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/utils/UtilsFactory.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/utils/UtilsFactory.kt index 2c8dc3c3..44bc09c2 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/utils/UtilsFactory.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/utils/UtilsFactory.kt @@ -27,14 +27,14 @@ */ package com.highcapable.yukihookapi.hook.utils -import com.highcapable.yukihookapi.annotation.DoNotUseAPI +import com.highcapable.yukihookapi.annotation.YukiPrivateApi /** * 计算方法执行耗时 * @param block 方法块 * @return [RunBlockResult] */ -@DoNotUseAPI +@YukiPrivateApi inline fun runBlocking(block: () -> R): RunBlockResult { val start = System.currentTimeMillis() block() @@ -45,7 +45,7 @@ inline fun runBlocking(block: () -> R): RunBlockResult { * 构造耗时计算结果类 * @param after 耗时 */ -@DoNotUseAPI +@YukiPrivateApi class RunBlockResult(private val after: Long) { /** diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/YukiHookModuleStatus.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/YukiHookModuleStatus.kt index b7f13d68..ed2f9f44 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/YukiHookModuleStatus.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/YukiHookModuleStatus.kt @@ -29,7 +29,7 @@ package com.highcapable.yukihookapi.hook.xposed import android.app.Activity 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.isTaiChiModuleActive import com.highcapable.yukihookapi.hook.factory.isXposedModuleActive @@ -92,7 +92,7 @@ object YukiHookModuleStatus { * @return [Boolean] */ @Keep - @DoNotUseAPI + @YukiPrivateApi @JvmName(IS_ACTIVE_METHOD_NAME) internal fun isActive(): Boolean { yLoggerD(msg = IS_ACTIVE_METHOD_NAME, isDisableLog = true) diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/bridge/YukiHookXposedBridge.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/bridge/YukiHookXposedBridge.kt new file mode 100644 index 00000000..2b797b1b --- /dev/null +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/bridge/YukiHookXposedBridge.kt @@ -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) +} \ No newline at end of file diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookModulePrefs.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookModulePrefs.kt index 56371179..6f33e4ec 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookModulePrefs.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookModulePrefs.kt @@ -32,6 +32,7 @@ package com.highcapable.yukihookapi.hook.xposed.prefs import android.content.Context import android.content.SharedPreferences import com.highcapable.yukihookapi.YukiHookAPI +import com.highcapable.yukihookapi.hook.xposed.bridge.YukiHookXposedBridge import com.highcapable.yukihookapi.hook.xposed.prefs.data.PrefsData import de.robv.android.xposed.XSharedPreferences import java.io.File @@ -57,7 +58,7 @@ import java.io.File class YukiHookModulePrefs(private val context: Context? = null) { /** 存储名称 - 默认包名 + _preferences */ - private var prefsName = "${YukiHookAPI.modulePackageName.ifBlank { context?.packageName ?: "" }}_preferences" + private var prefsName = "${YukiHookXposedBridge.modulePackageName.ifBlank { context?.packageName ?: "" }}_preferences" /** 是否为 Xposed 环境 */ private val isXposedEnvironment = YukiHookAPI.hasXposedBridge @@ -80,9 +81,11 @@ class YukiHookModulePrefs(private val context: Context? = null) { /** 是否使用键值缓存 */ private var isUsingKeyValueCache = YukiHookAPI.Configs.isEnableModulePrefsCache - /** 检查是否处于自定义 Hook API 状态 */ - private fun checkApiInBaseContext() { + /** 检查 API 装载状态 */ + private fun checkApi() { 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] */ private val xPref - get() = XSharedPreferences(YukiHookAPI.modulePackageName, prefsName).apply { - checkApiInBaseContext() + get() = XSharedPreferences(YukiHookXposedBridge.modulePackageName, prefsName).apply { + checkApi() makeWorldReadable() reload() } @@ -102,11 +105,11 @@ class YukiHookModulePrefs(private val context: Context? = null) { */ private val sPref get() = try { - checkApiInBaseContext() + checkApi() context?.getSharedPreferences(prefsName, Context.MODE_WORLD_READABLE) ?: error("If you want to use module prefs,you must set the context instance first") } catch (_: Throwable) { - checkApiInBaseContext() + checkApi() context?.getSharedPreferences(prefsName, Context.MODE_PRIVATE) ?: error("If you want to use module prefs,you must set the context instance first") }