diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/YukiHookAPI.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/YukiHookAPI.kt index 569383a7..1d0e8721 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/YukiHookAPI.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/YukiHookAPI.kt @@ -44,9 +44,7 @@ import com.highcapable.yukihookapi.hook.core.api.compat.type.ExecutorType import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker import com.highcapable.yukihookapi.hook.factory.isTaiChiModuleActive import com.highcapable.yukihookapi.hook.factory.processName -import com.highcapable.yukihookapi.hook.log.YukiHookLogger -import com.highcapable.yukihookapi.hook.log.yLoggerE -import com.highcapable.yukihookapi.hook.log.yLoggerI +import com.highcapable.yukihookapi.hook.log.YLog import com.highcapable.yukihookapi.hook.param.PackageParam import com.highcapable.yukihookapi.hook.param.wrapper.PackageParamWrapper import com.highcapable.yukihookapi.hook.xposed.application.ModuleApplication @@ -248,23 +246,23 @@ object YukiHookAPI { object Configs { /** - * 配置 [YukiHookLogger.Configs] 相关参数 + * 配置 [YLog.Configs] 相关参数 * @param initiate 方法体 */ - inline fun debugLog(initiate: YukiHookLogger.Configs.() -> Unit) = YukiHookLogger.Configs.apply(initiate).build() + inline fun debugLog(initiate: YLog.Configs.() -> Unit) = YLog.Configs.apply(initiate).build() /** * 这是一个调试日志的全局标识 * * - 此方法已弃用 - 在之后的版本中将直接被删除 * - * - 请现在迁移到 [debugLog] 并使用 [YukiHookLogger.Configs.tag] + * - 请现在迁移到 [debugLog] 并使用 [YLog.Configs.tag] */ @Deprecated(message = "请使用新方式来实现此功能") var debugTag - get() = YukiHookLogger.Configs.tag + get() = YLog.Configs.tag set(value) { - YukiHookLogger.Configs.tag = value + YLog.Configs.tag = value } /** @@ -272,7 +270,7 @@ object YukiHookAPI { * * 启用后将交由日志输出管理器打印详细 Hook 日志到控制台 * - * 当 [YukiHookLogger.Configs.isEnable] 关闭后 [isDebug] 也将同时关闭 + * 当 [YLog.Configs.isEnable] 关闭后 [isDebug] 也将同时关闭 */ var isDebug = true @@ -281,13 +279,13 @@ object YukiHookAPI { * * - 此方法已弃用 - 在之后的版本中将直接被删除 * - * - 请现在迁移到 [debugLog] 并使用 [YukiHookLogger.Configs.isEnable] + * - 请现在迁移到 [debugLog] 并使用 [YLog.Configs.isEnable] */ @Deprecated(message = "请使用新方式来实现此功能") var isAllowPrintingLogs - get() = YukiHookLogger.Configs.isEnable + get() = YLog.Configs.isEnable set(value) { - YukiHookLogger.Configs.isEnable = value + YLog.Configs.isEnable = value } /** @@ -411,7 +409,7 @@ object YukiHookAPI { YukiXposedModule.packageParamCallback = { if (hooker.isNotEmpty()) hooker.forEach { it.assignInstance(packageParam = this) } - else yLoggerE(msg = "Failed to passing \"encase\" method because your hooker param is empty", isImplicit = true) + else YLog.innerE("Failed to passing \"encase\" method because your hooker param is empty", isImplicit = true) } else printNotFoundHookApiError() } @@ -471,7 +469,7 @@ object YukiHookAPI { if (hooker.isNotEmpty()) { printSplashInfo() hooker.forEach { it.assignInstance(packageParam = baseContext.createPackageParam()) } - } else yLoggerE(msg = "Failed to passing \"encase\" method because your hooker param is empty", isImplicit = true)) + } else YLog.innerE("Failed to passing \"encase\" method because your hooker param is empty", isImplicit = true)) else printNotFoundHookApiError() } @@ -479,15 +477,12 @@ object YukiHookAPI { internal fun printSplashInfo() { if (Configs.isDebug.not() || isShowSplashLogOnceTime.not()) return isShowSplashLogOnceTime = false - yLoggerI( - msg = "Welcome to YukiHookAPI $VERSION! Using ${Status.Executor.name} API ${Status.Executor.apiLevel}", - isImplicit = true - ) + YLog.innerI("Welcome to YukiHookAPI $VERSION! Using ${Status.Executor.name} API ${Status.Executor.apiLevel}", isImplicit = true) } /** 输出找不到 Hook API 的错误日志 */ private fun printNotFoundHookApiError() = - yLoggerE(msg = "Could not found any available Hook APIs in current environment! Aborted", isImplicit = true) + YLog.innerE("Could not found any available Hook APIs in current environment! Aborted", isImplicit = true) /** * 通过 baseContext 创建 Hook 入口类 diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/YukiMemberHookCreator.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/YukiMemberHookCreator.kt index a08deadb..dcf1923f 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/YukiMemberHookCreator.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/YukiMemberHookCreator.kt @@ -53,9 +53,7 @@ import com.highcapable.yukihookapi.hook.factory.method import com.highcapable.yukihookapi.hook.factory.notExtends import com.highcapable.yukihookapi.hook.factory.notImplements import com.highcapable.yukihookapi.hook.factory.toJavaPrimitiveType -import com.highcapable.yukihookapi.hook.log.yLoggerD -import com.highcapable.yukihookapi.hook.log.yLoggerE -import com.highcapable.yukihookapi.hook.log.yLoggerW +import com.highcapable.yukihookapi.hook.log.YLog import com.highcapable.yukihookapi.hook.param.HookParam import com.highcapable.yukihookapi.hook.param.PackageParam import com.highcapable.yukihookapi.hook.type.java.AnyClass @@ -161,7 +159,7 @@ class YukiMemberHookCreator internal constructor(private val packageParam: Packa HookApiCategoryHelper.hasAvailableHookApi.not() -> Result() /** 过滤 [HookEntryType.ZYGOTE] and [HookEntryType.PACKAGE] or [HookParam.isCallbackCalled] 已被执行 */ packageParam.wrapper?.type == HookEntryType.RESOURCES && HookParam.isCallbackCalled.not() -> Result() - preHookMembers.isEmpty() -> Result().also { yLoggerW(msg = "Hook Members is empty in [${hookClass.name}], hook aborted") } + preHookMembers.isEmpty() -> Result().also { YLog.innerW(msg = "Hook Members is empty in [${hookClass.name}], hook aborted") } else -> Result().await { when { isDisableCreatorRunHook.not() && hookClass.instance != null -> runCatching { @@ -170,12 +168,12 @@ class YukiMemberHookCreator internal constructor(private val packageParam: Packa preHookMembers.forEach { (_, m) -> m.hook() } }.onFailure { if (onHookClassNotFoundFailureCallback == null) - yLoggerE(msg = "Hook initialization failed because got an Exception", e = it) + YLog.innerE(msg = "Hook initialization failed because got an Exception", e = it) else onHookClassNotFoundFailureCallback?.invoke(it) } isDisableCreatorRunHook.not() && hookClass.instance == null -> if (onHookClassNotFoundFailureCallback == null) - yLoggerE(msg = "HookClass [${hookClass.name}] not found", e = hookClass.throwable) + YLog.innerE(msg = "HookClass [${hookClass.name}] not found", e = hookClass.throwable) else onHookClassNotFoundFailureCallback?.invoke(hookClass.throwable ?: Throwable("[${hookClass.name}] not found")) } } @@ -576,7 +574,7 @@ class YukiMemberHookCreator internal constructor(private val packageParam: Packa onNoSuchMemberFailureCallback?.invoke(it) onHookingFailureCallback?.invoke(it) onAllFailureCallback?.invoke(it) - if (isNotIgnoredNoSuchMemberFailure) yLoggerE( + if (isNotIgnoredNoSuchMemberFailure) YLog.innerE( msg = (if (isHookMemberSetup) "Hooked Member with a finding error by $hookClass [$tag]" else "Hooked Member cannot be non-null by $hookClass [$tag]"), @@ -676,7 +674,7 @@ class YukiMemberHookCreator internal constructor(private val packageParam: Packa * @param msg 调试日志内容 */ private fun hookDebugMsg(msg: String) { - if (YukiHookAPI.Configs.isDebug) yLoggerD(msg = msg) + if (YukiHookAPI.Configs.isDebug) YLog.innerD(msg) } /** @@ -685,7 +683,7 @@ class YukiMemberHookCreator internal constructor(private val packageParam: Packa * @param member 异常 [Member] - 可空 */ private fun hookErrorMsg(e: Throwable, member: Member? = null) = - yLoggerE(msg = "Try to hook [${hookClass.instance ?: hookClass.name}]${member?.let { "[$it]" } ?: ""} got an Exception [$tag]", e = e) + YLog.innerE(msg = "Try to hook [${hookClass.instance ?: hookClass.name}]${member?.let { "[$it]" } ?: ""} got an Exception [$tag]", e = e) /** * 判断是否没有设置 Hook 过程中的任何异常拦截 diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/YukiResourcesHookCreator.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/YukiResourcesHookCreator.kt index 9be4bf44..873d1fb7 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/YukiResourcesHookCreator.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/YukiResourcesHookCreator.kt @@ -34,9 +34,7 @@ import android.util.ArrayMap import com.highcapable.yukihookapi.YukiHookAPI import com.highcapable.yukihookapi.hook.bean.HookResources import com.highcapable.yukihookapi.hook.core.api.compat.HookApiCategoryHelper -import com.highcapable.yukihookapi.hook.log.yLoggerD -import com.highcapable.yukihookapi.hook.log.yLoggerE -import com.highcapable.yukihookapi.hook.log.yLoggerW +import com.highcapable.yukihookapi.hook.log.YLog import com.highcapable.yukihookapi.hook.param.PackageParam import com.highcapable.yukihookapi.hook.xposed.bridge.resources.YukiResources import com.highcapable.yukihookapi.hook.xposed.bridge.type.HookEntryType @@ -66,7 +64,7 @@ class YukiResourcesHookCreator internal constructor(internal val packageParam: P if (HookApiCategoryHelper.hasAvailableHookApi.not()) return /** 过滤 [HookEntryType.ZYGOTE] 与 [HookEntryType.RESOURCES] */ if (packageParam.wrapper?.type == HookEntryType.PACKAGE) return - if (preHookResources.isEmpty()) return yLoggerW(msg = "Hook Resources is empty, hook aborted") + if (preHookResources.isEmpty()) return YLog.innerW("Hook Resources is empty, hook aborted") preHookResources.forEach { (_, r) -> r.hook() } } @@ -174,25 +172,25 @@ class YukiResourcesHookCreator internal constructor(internal val packageParam: P isHooked = true if (isDisableCreatorRunHook.not()) runCatching { when { - conditions == null -> yLoggerE(msg = "You must set the conditions before hook a Resources [$tag]") - replaceInstance == null && layoutInstance == null -> yLoggerE(msg = "Resources Hook got null replaceInstance [$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]") packageParam.wrapper?.type == HookEntryType.RESOURCES && hookResources.instance != null -> if (resourceId == -1) when { layoutInstance != null -> hookResources.instance?.hookLayout( packageParam.packageName, conditions!!.type, conditions!!.name, layoutInstance!! - ) { onHookLogMsg(msg = "Hook Resources Layout $conditions done [$tag]") } + ) { hookDebugMsg(msg = "Hook Resources Layout $conditions done [$tag]") } else -> hookResources.instance?.setReplacement( packageParam.packageName, conditions!!.type, conditions!!.name, compat(replaceInstance) - ) { onHookLogMsg(msg = "Hook Resources Value $conditions done [$tag]") } + ) { hookDebugMsg(msg = "Hook Resources Value $conditions done [$tag]") } } else when { layoutInstance != null -> hookResources.instance?.hookLayout(resourceId, layoutInstance!!) { - onHookLogMsg(msg = "Hook Resources Layout Id $resourceId done [$tag]") + hookDebugMsg(msg = "Hook Resources Layout Id $resourceId done [$tag]") } else -> hookResources.instance?.setReplacement(resourceId, compat(replaceInstance)) { - onHookLogMsg(msg = "Hook Resources Value Id $resourceId done [$tag]") + hookDebugMsg(msg = "Hook Resources Value Id $resourceId done [$tag]") } } packageParam.wrapper?.type == HookEntryType.ZYGOTE -> @@ -201,24 +199,24 @@ class YukiResourcesHookCreator internal constructor(internal val packageParam: P YukiResources.hookSystemWideLayout( packageParam.packageName, conditions!!.type, conditions!!.name, layoutInstance!! - ) { onHookLogMsg(msg = "Hook Wide Resources Layout $conditions done [$tag]") } + ) { hookDebugMsg(msg = "Hook Wide Resources Layout $conditions done [$tag]") } else -> YukiResources.setSystemWideReplacement( packageParam.packageName, conditions!!.type, conditions!!.name, compat(replaceInstance) - ) { onHookLogMsg(msg = "Hook Wide Resources Value $conditions done [$tag]") } + ) { hookDebugMsg(msg = "Hook Wide Resources Value $conditions done [$tag]") } } else when { layoutInstance != null -> YukiResources.hookSystemWideLayout(resourceId, layoutInstance!!) { - onHookLogMsg(msg = "Hook Wide Resources Layout Id $resourceId done [$tag]") + hookDebugMsg(msg = "Hook Wide Resources Layout Id $resourceId done [$tag]") } else -> YukiResources.setSystemWideReplacement(resourceId, compat(replaceInstance)) { - onHookLogMsg(msg = "Hook Wide Resources Value Id $resourceId done [$tag]") + hookDebugMsg(msg = "Hook Wide Resources Value Id $resourceId done [$tag]") } } - else -> yLoggerE(msg = "Resources Hook type is invalid [$tag]") + else -> YLog.innerE("Resources Hook type is invalid [$tag]") } }.onFailure { if (onHookFailureCallback == null) - yLoggerE(msg = "Resources Hook got an Exception [$tag]", e = it) + YLog.innerE("Resources Hook got an Exception [$tag]", it) else onHookFailureCallback?.invoke(it) } } @@ -227,8 +225,8 @@ class YukiResourcesHookCreator internal constructor(internal val packageParam: P * Hook 过程中开启了 [YukiHookAPI.Configs.isDebug] 输出调试信息 * @param msg 调试日志内容 */ - private fun onHookLogMsg(msg: String) { - if (YukiHookAPI.Configs.isDebug) yLoggerD(msg = msg) + private fun hookDebugMsg(msg: String) { + if (YukiHookAPI.Configs.isDebug) YLog.innerD(msg) } /** diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/api/helper/YukiHookHelper.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/api/helper/YukiHookHelper.kt index 55e52053..773ac460 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/api/helper/YukiHookHelper.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/api/helper/YukiHookHelper.kt @@ -35,7 +35,7 @@ import com.highcapable.yukihookapi.hook.core.api.store.YukiHookCacheStore import com.highcapable.yukihookapi.hook.core.finder.base.BaseFinder import com.highcapable.yukihookapi.hook.core.finder.members.ConstructorFinder import com.highcapable.yukihookapi.hook.core.finder.members.MethodFinder -import com.highcapable.yukihookapi.hook.log.yLoggerE +import com.highcapable.yukihookapi.hook.log.YLog import java.lang.reflect.Member /** @@ -56,7 +56,7 @@ internal object YukiHookHelper { else -> error("Unexpected BaseFinder result interface type") } hookMember(member, callback) - }.onFailure { yLoggerE(msg = "An exception occurred when hooking internal function", e = it) }.getOrNull() ?: YukiHookResult() + }.onFailure { YLog.innerE("An exception occurred when hooking internal function", it) }.getOrNull() ?: YukiHookResult() /** * Hook [Member] @@ -99,7 +99,7 @@ internal object YukiHookHelper { if (isMemberHooked(member)) member?.let { runCatching { HookCompatHelper.invokeOriginalMember(member, instance, args) }.onFailure { if (it.message?.lowercase()?.contains("wrong number of arguments") == true) error(it.message ?: it.toString()) - yLoggerE(msg = "Invoke original Member [$member] failed", e = it) + YLog.innerE("Invoke original Member [$member] failed", it) }.getOrNull() } else null diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/base/ClassBaseFinder.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/base/ClassBaseFinder.kt index 1719766e..6fc502dc 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/base/ClassBaseFinder.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/base/ClassBaseFinder.kt @@ -29,8 +29,7 @@ package com.highcapable.yukihookapi.hook.core.finder.base import com.highcapable.yukihookapi.YukiHookAPI import com.highcapable.yukihookapi.hook.core.api.compat.HookApiCategoryHelper -import com.highcapable.yukihookapi.hook.log.yLoggerD -import com.highcapable.yukihookapi.hook.log.yLoggerE +import com.highcapable.yukihookapi.hook.log.YLog /** * 这是 [Class] 查找类功能的基本类实现 @@ -63,7 +62,7 @@ abstract class ClassBaseFinder internal constructor(internal open val loaderSet: * @param msg 消息内容 */ internal fun debugMsg(msg: String) { - if (YukiHookAPI.Configs.isDebug && HookApiCategoryHelper.hasAvailableHookApi) yLoggerD(msg = msg) + if (YukiHookAPI.Configs.isDebug && HookApiCategoryHelper.hasAvailableHookApi) YLog.innerD(msg) } /** @@ -74,7 +73,7 @@ abstract class ClassBaseFinder internal constructor(internal open val loaderSet: if (isIgnoreErrorLogs) return /** 判断是否为 [LOADERSET_IS_NULL] */ if (e?.message == LOADERSET_IS_NULL) return - yLoggerE(msg = "NoClassDefFound happend in [$loaderSet]", e = e) + YLog.innerE("NoClassDefFound happend in [$loaderSet]", e) } override fun failure(throwable: Throwable?) = error("DexClassFinder does not contain this usage") diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/base/MemberBaseFinder.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/base/MemberBaseFinder.kt index b56658fe..753f50d2 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/base/MemberBaseFinder.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/base/MemberBaseFinder.kt @@ -30,8 +30,7 @@ package com.highcapable.yukihookapi.hook.core.finder.base import com.highcapable.yukihookapi.YukiHookAPI import com.highcapable.yukihookapi.hook.core.YukiMemberHookCreator import com.highcapable.yukihookapi.hook.core.api.compat.HookApiCategoryHelper -import com.highcapable.yukihookapi.hook.log.yLoggerD -import com.highcapable.yukihookapi.hook.log.yLoggerE +import com.highcapable.yukihookapi.hook.log.YLog import com.highcapable.yukihookapi.hook.utils.factory.await import java.lang.reflect.Constructor import java.lang.reflect.Field @@ -96,7 +95,7 @@ abstract class MemberBaseFinder internal constructor(private val tag: String, in */ internal fun debugMsg(msg: String) { if (YukiHookAPI.Configs.isDebug && HookApiCategoryHelper.hasAvailableHookApi && hookerManager.instance != null) - yLoggerD(msg = "$msg${hookerManager.tailTag}") + YLog.innerD("$msg${hookerManager.tailTag}") } /** @@ -112,8 +111,8 @@ abstract class MemberBaseFinder internal constructor(private val tag: String, in await { if (isIgnoreErrorLogs || hookerManager.isNotIgnoredNoSuchMemberFailure.not()) return@await if (isAlwaysMode.not() && isUsingRemedyPlan) return@await - yLoggerE(msg = "NoSuch$tag happend in [$classSet] $msg${hookerManager.tailTag}".trim(), e = e) - es.forEachIndexed { index, e -> yLoggerE(msg = "Throwable [${index + 1}]", e = e) } + YLog.innerE("NoSuch$tag happend in [$classSet] $msg${hookerManager.tailTag}".trim(), e) + es.forEachIndexed { index, e -> YLog.innerE("Throwable [${index + 1}]", e) } } } diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/classes/DexClassFinder.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/classes/DexClassFinder.kt index 9aba768a..4ebc6f90 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/classes/DexClassFinder.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/classes/DexClassFinder.kt @@ -48,7 +48,7 @@ import com.highcapable.yukihookapi.hook.core.finder.type.factory.NameConditions import com.highcapable.yukihookapi.hook.factory.hasClass import com.highcapable.yukihookapi.hook.factory.searchClass import com.highcapable.yukihookapi.hook.factory.toClass -import com.highcapable.yukihookapi.hook.log.yLoggerW +import com.highcapable.yukihookapi.hook.log.YLog import com.highcapable.yukihookapi.hook.param.PackageParam import com.highcapable.yukihookapi.hook.utils.factory.await import com.highcapable.yukihookapi.hook.utils.factory.runBlocking @@ -109,7 +109,7 @@ class DexClassFinder internal constructor( */ fun clearCache(context: Context? = currentContext, versionName: String? = null, versionCode: Long? = null) { context?.currentSp(versionName, versionCode)?.edit()?.clear()?.apply() - ?: yLoggerW(msg = "Cannot clear cache for DexClassFinder because got null context instance") + ?: YLog.innerW("Cannot clear cache for DexClassFinder because got null context instance") } } diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/members/ConstructorFinder.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/members/ConstructorFinder.kt index 4c82c0c7..45f4b7f9 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/members/ConstructorFinder.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/members/ConstructorFinder.kt @@ -40,7 +40,7 @@ import com.highcapable.yukihookapi.hook.core.finder.type.factory.CountConditions import com.highcapable.yukihookapi.hook.core.finder.type.factory.ModifierConditions import com.highcapable.yukihookapi.hook.core.finder.type.factory.ObjectsConditions import com.highcapable.yukihookapi.hook.factory.hasExtends -import com.highcapable.yukihookapi.hook.log.yLoggerW +import com.highcapable.yukihookapi.hook.log.YLog import com.highcapable.yukihookapi.hook.type.defined.UndefinedType import com.highcapable.yukihookapi.hook.type.defined.VagueType import com.highcapable.yukihookapi.hook.utils.factory.runBlocking @@ -333,7 +333,7 @@ class ConstructorFinder internal constructor(override val classSet: Class<*>? = if (isFindSuccess) return errorMsg(msg = "RemedyPlan failed after ${remedyPlans.size} attempts", es = errors, isAlwaysMode = true) remedyPlans.clear() - } else yLoggerW(msg = "RemedyPlan is empty, forgot it?${hookerManager.tailTag}") + } else YLog.innerW("RemedyPlan is empty, forgot it?${hookerManager.tailTag}") } /** diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/members/FieldFinder.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/members/FieldFinder.kt index 9c6c227f..093e90c4 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/members/FieldFinder.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/members/FieldFinder.kt @@ -42,7 +42,7 @@ import com.highcapable.yukihookapi.hook.core.finder.type.factory.NameConditions import com.highcapable.yukihookapi.hook.core.finder.type.factory.ObjectConditions import com.highcapable.yukihookapi.hook.factory.current import com.highcapable.yukihookapi.hook.factory.hasExtends -import com.highcapable.yukihookapi.hook.log.yLoggerW +import com.highcapable.yukihookapi.hook.log.YLog import com.highcapable.yukihookapi.hook.utils.factory.runBlocking import java.lang.reflect.Field @@ -282,7 +282,7 @@ class FieldFinder internal constructor(override val classSet: Class<*>? = null) if (isFindSuccess) return errorMsg(msg = "RemedyPlan failed after ${remedyPlans.size} attempts", es = errors, isAlwaysMode = true) remedyPlans.clear() - } else yLoggerW(msg = "RemedyPlan is empty, forgot it?${hookerManager.tailTag}") + } else YLog.innerW("RemedyPlan is empty, forgot it?${hookerManager.tailTag}") } /** diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/members/MethodFinder.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/members/MethodFinder.kt index cf9dbb55..70211b0b 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/members/MethodFinder.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/members/MethodFinder.kt @@ -43,7 +43,7 @@ import com.highcapable.yukihookapi.hook.core.finder.type.factory.NameConditions import com.highcapable.yukihookapi.hook.core.finder.type.factory.ObjectConditions import com.highcapable.yukihookapi.hook.core.finder.type.factory.ObjectsConditions import com.highcapable.yukihookapi.hook.factory.hasExtends -import com.highcapable.yukihookapi.hook.log.yLoggerW +import com.highcapable.yukihookapi.hook.log.YLog import com.highcapable.yukihookapi.hook.type.defined.UndefinedType import com.highcapable.yukihookapi.hook.type.defined.VagueType import com.highcapable.yukihookapi.hook.utils.factory.runBlocking @@ -427,7 +427,7 @@ class MethodFinder internal constructor(override val classSet: Class<*>? = null) if (isFindSuccess) return errorMsg(msg = "RemedyPlan failed after ${remedyPlans.size} attempts", es = errors, isAlwaysMode = true) remedyPlans.clear() - } else yLoggerW(msg = "RemedyPlan is empty, forgot it?${hookerManager.tailTag}") + } else YLog.innerW("RemedyPlan is empty, forgot it?${hookerManager.tailTag}") } /** diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/tools/ReflectionTool.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/tools/ReflectionTool.kt index c5c04b82..249db891 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/tools/ReflectionTool.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/finder/tools/ReflectionTool.kt @@ -37,22 +37,32 @@ import com.highcapable.yukihookapi.hook.core.finder.members.data.ConstructorRule import com.highcapable.yukihookapi.hook.core.finder.members.data.FieldRulesData import com.highcapable.yukihookapi.hook.core.finder.members.data.MemberRulesData import com.highcapable.yukihookapi.hook.core.finder.members.data.MethodRulesData -import com.highcapable.yukihookapi.hook.factory.* -import com.highcapable.yukihookapi.hook.log.yLoggerW +import com.highcapable.yukihookapi.hook.factory.current +import com.highcapable.yukihookapi.hook.factory.field +import com.highcapable.yukihookapi.hook.factory.hasClass +import com.highcapable.yukihookapi.hook.factory.hasExtends +import com.highcapable.yukihookapi.hook.factory.toClass +import com.highcapable.yukihookapi.hook.log.YLog import com.highcapable.yukihookapi.hook.type.defined.UndefinedType import com.highcapable.yukihookapi.hook.type.defined.VagueType import com.highcapable.yukihookapi.hook.type.java.DalvikBaseDexClassLoader import com.highcapable.yukihookapi.hook.type.java.NoClassDefFoundErrorClass import com.highcapable.yukihookapi.hook.type.java.NoSuchFieldErrorClass import com.highcapable.yukihookapi.hook.type.java.NoSuchMethodErrorClass -import com.highcapable.yukihookapi.hook.utils.factory.* +import com.highcapable.yukihookapi.hook.utils.factory.conditions +import com.highcapable.yukihookapi.hook.utils.factory.findLastIndex +import com.highcapable.yukihookapi.hook.utils.factory.lastIndex +import com.highcapable.yukihookapi.hook.utils.factory.let +import com.highcapable.yukihookapi.hook.utils.factory.runOrFalse +import com.highcapable.yukihookapi.hook.utils.factory.takeIf +import com.highcapable.yukihookapi.hook.utils.factory.value import com.highcapable.yukihookapi.hook.xposed.parasitic.AppParasitics import dalvik.system.BaseDexClassLoader import java.lang.reflect.Constructor import java.lang.reflect.Field import java.lang.reflect.Member import java.lang.reflect.Method -import java.util.* +import java.util.Enumeration import kotlin.math.abs /** @@ -192,7 +202,7 @@ internal object ReflectionTool { fun MemberRulesData.exists(vararg type: Any?): Boolean { if (type.isEmpty()) return true for (i in type.indices) if (type[i] == UndefinedType) { - yLoggerW(msg = "$objectName type[$i] mistake, it will be ignored in current conditions") + YLog.innerW("$objectName type[$i] mistake, it will be ignored in current conditions") return false } return true @@ -656,7 +666,7 @@ internal object ReflectionTool { addAll(declaredConstructors.toList()) }.asSequence() }.onFailure { - yLoggerW(msg = "Failed to get the declared Members in [$this] because got an exception\n$it") + YLog.innerW("Failed to get the declared Members in [$this] because got an exception", it) }.getOrNull() /** @@ -665,7 +675,7 @@ internal object ReflectionTool { */ private val Class<*>.existFields get() = runCatching { declaredFields.asSequence() }.onFailure { - yLoggerW(msg = "Failed to get the declared Fields in [$this] because got an exception\n$it") + YLog.innerW("Failed to get the declared Fields in [$this] because got an exception", it) }.getOrNull() /** @@ -674,7 +684,7 @@ internal object ReflectionTool { */ private val Class<*>.existMethods get() = runCatching { declaredMethods.asSequence() }.onFailure { - yLoggerW(msg = "Failed to get the declared Methods in [$this] because got an exception\n$it") + YLog.innerW("Failed to get the declared Methods in [$this] because got an exception", it) }.getOrNull() /** @@ -683,7 +693,7 @@ internal object ReflectionTool { */ private val Class<*>.existConstructors get() = runCatching { declaredConstructors.asSequence() }.onFailure { - yLoggerW(msg = "Failed to get the declared Constructors in [$this] because got an exception\n$it") + YLog.innerW("Failed to get the declared Constructors in [$this] because got an exception", it) }.getOrNull() /** diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/log/LoggerFactory.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/log/LoggerFactory.kt deleted file mode 100644 index 970f4a65..00000000 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/log/LoggerFactory.kt +++ /dev/null @@ -1,447 +0,0 @@ -/* - * YukiHookAPI - An efficient Hook API and Xposed Module solution built in Kotlin. - * Copyright (C) 2019-2023 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/2/3. - */ -@file:Suppress("unused", "MemberVisibilityCanBePrivate") - -package com.highcapable.yukihookapi.hook.log - -import android.system.ErrnoException -import android.util.Log -import com.highcapable.yukihookapi.YukiHookAPI -import com.highcapable.yukihookapi.hook.core.api.helper.YukiHookHelper -import com.highcapable.yukihookapi.hook.factory.current -import com.highcapable.yukihookapi.hook.utils.factory.dumpToString -import com.highcapable.yukihookapi.hook.xposed.bridge.YukiXposedModule -import com.highcapable.yukihookapi.hook.xposed.parasitic.AppParasitics -import java.io.File -import java.io.Serializable -import java.text.SimpleDateFormat -import java.util.Date -import java.util.Locale - -/** - * 需要打印的日志类型 - * - * 决定于模块与 (Xposed) 宿主环境使用的打印方式 - */ -enum class LoggerType { - /** 仅使用 [Log] */ - LOGD, - - /** - * 仅在 (Xposed) 宿主环境使用 - * - * - 此方法已弃用 - 在之后的版本中将直接被删除 - * - * - 请现在迁移到 [XPOSED_ENVIRONMENT] - */ - @Deprecated(message = "请使用新的命名方法", ReplaceWith("XPOSED_ENVIRONMENT")) - XPOSEDBRIDGE, - - /** - * 仅在 (Xposed) 宿主环境使用 - * - * - 只能在 (Xposed) 宿主环境中使用 - 模块环境将不生效 - */ - XPOSED_ENVIRONMENT, - - /** - * 分区使用 - * - * (Xposed) 宿主环境仅使用 [XPOSED_ENVIRONMENT] - * - * 模块环境仅使用 [LOGD] - */ - SCOPE, - - /** - * 同时使用 - * - * (Xposed) 宿主环境使用 [LOGD] 与 [XPOSED_ENVIRONMENT] - * - * 模块环境仅使用 [LOGD] - */ - BOTH -} - -/** - * 调试日志数据实现类 - * @param timestamp 当前时间戳 - * @param time 当前 UTC 时间 - * @param tag 当前标签 - * @param priority 当前优先级 - D、I、W、E - * @param packageName 当前包名 - * @param userId 当前用户 ID - * @param msg 当前日志内容 - * @param throwable 当前异常堆栈 - */ -data class YukiLoggerData internal constructor( - var timestamp: Long = 0L, - var time: String = "", - var tag: String = YukiHookLogger.Configs.tag, - var priority: String = "", - var packageName: String = "", - var userId: Int = 0, - var msg: String = "", - var throwable: Throwable? = null -) : Serializable { - - /** 是否隐式打印 */ - internal var isImplicit = false - - init { - timestamp = System.currentTimeMillis() - time = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.ROOT).format(Date(timestamp)) - packageName = if (YukiXposedModule.isXposedEnvironment) YukiXposedModule.hostProcessName else AppParasitics.currentPackageName - userId = AppParasitics.findUserId(AppParasitics.currentPackageName) - } - - /** - * 获取头部时间字符串 - * @return [String] - */ - internal val head get() = "$time ------ " - - override fun toString(): String { - var content = "" - YukiHookLogger.Configs.elements.takeIf { it.isNotEmpty() }?.forEach { - if (it == YukiHookLogger.Configs.TAG) content += "[$tag]" - if (it == YukiHookLogger.Configs.PRIORITY) content += "[$priority]" - if (it == YukiHookLogger.Configs.PACKAGE_NAME && isImplicit.not() && packageName.isNotBlank()) content += "[$packageName]" - if (it == YukiHookLogger.Configs.USER_ID && isImplicit.not() && userId != 0) content += "[$userId]" - } - return content.takeIf { it.isNotBlank() }?.let { "$content--> $msg" } ?: msg - } -} - -/** - * 调试日志实现类 - */ -object YukiHookLogger { - - /** - * 当前全部已记录的日志数据 - * - * - 获取到的日志数据在 Hook APP (宿主) 及模块进程中是相互隔离的 - */ - val inMemoryData = ArrayList() - - /** - * 获取当前日志文件内容 - * - * 如果当前没有已记录的日志会返回空字符串 - * - * - 获取到的日志数据在 Hook APP (宿主) 及模块进程中是相互隔离的 - * @return [String] - */ - val contents get() = contents() - - /** - * 获取、格式化当前日志文件内容 - * - * 如果当前没有已记录的日志 ([data] 为空) 会返回空字符串 - * - * - 获取到的日志数据在 Hook APP (宿主) 及模块进程中是相互隔离的 - * @param data 日志数据 - 默认为 [inMemoryData] - * @return [String] - */ - fun contents(data: ArrayList = inMemoryData): String { - var content = "" - data.takeIf { it.isNotEmpty() }?.forEach { - content += "${it.head}$it\n" - it.throwable?.also { e -> - content += "${it.head}Dump stack trace for \"${e.current().name}\":\n" - content += e.dumpToString() - } - } - return content - } - - /** - * 清除全部已记录的日志 - * - * 你也可以直接获取 [inMemoryData] 来清除 - * - * - 获取到的日志数据在 Hook APP (宿主) 及模块进程中是相互隔离的 - */ - fun clear() = inMemoryData.clear() - - /** - * 保存当前日志到文件 - * - * 若当前未开启 [Configs.isRecord] 或记录为空则不会进行任何操作 - * - * 日志文件会追加到 [fileName] 的文件结尾 - 若文件不存在会自动创建 - * - * - 文件读写权限取决于当前宿主、模块已获取的权限 - * @param fileName 完整文件名 - 例如 /data/data/.../files/xxx.log - * @param data 日志数据 - 默认为 [inMemoryData] - * @throws ErrnoException 如果目标路径不可写 - */ - fun saveToFile(fileName: String, data: ArrayList = inMemoryData) { - if (data.isNotEmpty()) File(fileName).appendText(contents(data)) - } - - /** - * 配置 [YukiHookLogger] - */ - object Configs { - - /** - * 标签 - * - * 显示效果如下 ↓ - * - * ``` - * [YukiHookAPI][...][...]--> ... - * ``` - */ - const val TAG = 1000 - - /** - * 优先级 - * - * 显示效果如下 ↓ - * - * ``` - * [...][E][...]--> ... - * ``` - */ - const val PRIORITY = 1001 - - /** - * 当前宿主的包名 - * - * 显示效果如下 ↓ - * - * ``` - * [...][com.demo.test][...]--> ... - * ``` - */ - const val PACKAGE_NAME = 1002 - - /** - * 当前宿主的用户 ID (主用户不显示) - * - * 显示效果如下 ↓ - * - * ``` - * [...][...][999]--> ... - * ``` - */ - const val USER_ID = 1003 - - /** 当前已添加的元素顺序列表数组 */ - internal var elements = arrayOf(TAG, PRIORITY, PACKAGE_NAME, USER_ID) - - /** - * 是否启用调试日志的输出功能 - 默认启用 - * - * - 关闭后将会停用 [YukiHookAPI] 对全部日志的输出 - * - * 但是不影响当你手动调用下面这些方法输出日志 - * - * [loggerD]、[loggerI]、[loggerW]、[loggerE] - * - * 当 [isEnable] 关闭后 [YukiHookAPI.Configs.isDebug] 也将同时关闭 - */ - var isEnable = true - - /** - * 是否启用调试日志的记录功能 - 默认不启用 - * - * 开启后将会在内存中记录全部可用的日志和异常堆栈 - * - * 需要同时启用 [isEnable] 才能有效 - * - * - 过量的日志可能会导致宿主运行缓慢或造成频繁 GC - * - * 开启后你可以调用 [YukiHookLogger.saveToFile] 实时保存日志到文件或使用 [YukiHookLogger.contents] 获取实时日志文件 - */ - var isRecord = false - - /** - * 这是一个调试日志的全局标识 - * - * 默认文案为 [YukiHookAPI.TAG] - * - * 你可以修改为你自己的文案 - */ - var tag = YukiHookAPI.TAG - - /** - * 自定义调试日志对外显示的元素 - * - * 只对日志记录和 (Xposed) 宿主环境的日志生效 - * - * 日志元素的排列将按照你在 [item] 中设置的顺序进行显示 - * - * 你还可以留空 [item] 以不显示除日志内容外的全部元素 - * - * 可用的元素有:[TAG]、[PRIORITY]、[PACKAGE_NAME]、[USER_ID] - * - * 默认排列方式如下 ↓ - * - * ``` - * [TAG][PRIORITY][PACKAGE_NAME][USER_ID]--> Message - * ``` - * @param item 自定义的元素数组 - */ - fun elements(vararg item: Int) { - elements = arrayOf(*item.toTypedArray()) - } - - /** 结束方法体 */ - internal fun build() = Unit - } -} - -/** - * 向控制台和 (Xposed) 宿主环境打印日志 - 最终实现方法 - * @param type 日志打印的类型 - * @param data 日志数据 - * @param isImplicit 是否隐式打印 - 不会记录 - 也不会显示包名和用户 ID - */ -private fun baseLogger(type: LoggerType, data: YukiLoggerData, isImplicit: Boolean = false) { - /** 是否为有效日志 */ - val isNotBlankLog = data.msg.isNotBlank() || (data.msg.isBlank() && data.throwable != null) - - /** 打印到 [Log] */ - fun logByLogd() = when (data.priority) { - "D" -> Log.d(data.tag, data.msg) - "I" -> Log.i(data.tag, data.msg) - "W" -> Log.w(data.tag, data.msg) - "E" -> Log.e(data.tag, data.msg, data.throwable) - else -> Log.wtf(data.tag, data.msg, data.throwable) - } - - /** 打印到 (Xposed) 宿主环境 */ - fun logByHooker() { - if (isNotBlankLog) YukiHookHelper.logByHooker(data.also { it.isImplicit = isImplicit }.toString(), data.throwable) - } - @Suppress("DEPRECATION") - when (type) { - LoggerType.LOGD -> logByLogd() - LoggerType.XPOSEDBRIDGE, LoggerType.XPOSED_ENVIRONMENT -> logByHooker() - LoggerType.SCOPE -> if (YukiXposedModule.isXposedEnvironment) logByHooker() else logByLogd() - LoggerType.BOTH -> { - logByLogd() - if (YukiXposedModule.isXposedEnvironment) logByHooker() - } - } - if (isImplicit.not() && YukiHookLogger.Configs.isRecord && isNotBlankLog) YukiHookLogger.inMemoryData.add(data) -} - -/** - * [YukiHookAPI] 向控制台和 (Xposed) 宿主环境打印日志 - D - * @param msg 日志打印的内容 - * @param isImplicit 是否隐式打印 - 不会记录 - 也不会显示包名和用户 ID - * @param isDisableLog 禁止打印日志 - 标识后将什么也不做 - 默认为 false - */ -internal fun yLoggerD(msg: String, isImplicit: Boolean = false, isDisableLog: Boolean = false) { - if (YukiHookLogger.Configs.isEnable.not() || isDisableLog) return - baseLogger(LoggerType.BOTH, YukiLoggerData(priority = "D", msg = msg), isImplicit) -} - -/** - * [YukiHookAPI] 向控制台和 (Xposed) 宿主环境打印日志 - I - * @param msg 日志打印的内容 - * @param isImplicit 是否隐式打印 - 不会记录 - 也不会显示包名和用户 ID - * @param isDisableLog 禁止打印日志 - 标识后将什么也不做 - 默认为 false - */ -internal fun yLoggerI(msg: String, isImplicit: Boolean = false, isDisableLog: Boolean = false) { - if (YukiHookLogger.Configs.isEnable.not() || isDisableLog) return - baseLogger(LoggerType.BOTH, YukiLoggerData(priority = "I", msg = msg), isImplicit) -} - -/** - * [YukiHookAPI] 向控制台和 (Xposed) 宿主环境打印日志 - W - * @param msg 日志打印的内容 - * @param isImplicit 是否隐式打印 - 不会记录 - 也不会显示包名和用户 ID - * @param isDisableLog 禁止打印日志 - 标识后将什么也不做 - 默认为 false - */ -internal fun yLoggerW(msg: String, isImplicit: Boolean = false, isDisableLog: Boolean = false) { - if (YukiHookLogger.Configs.isEnable.not() || isDisableLog) return - baseLogger(LoggerType.BOTH, YukiLoggerData(priority = "W", msg = msg), isImplicit) -} - -/** - * [YukiHookAPI] 向控制台和 (Xposed) 宿主环境打印日志 - E - * @param msg 日志打印的内容 - 默认空 - 如果你仅想打印异常堆栈可只设置 [e] - * @param e 可填入异常堆栈信息 - 将自动完整打印到控制台 - * @param isImplicit 是否隐式打印 - 不会记录 - 也不会显示包名和用户 ID - * @param isDisableLog 禁止打印日志 - 标识后将什么也不做 - 默认为 false - */ -internal fun yLoggerE(msg: String = "", e: Throwable? = null, isImplicit: Boolean = false, isDisableLog: Boolean = false) { - if (YukiHookLogger.Configs.isEnable.not() || isDisableLog) return - baseLogger(LoggerType.BOTH, YukiLoggerData(priority = "E", msg = msg, throwable = e), isImplicit) -} - -/** - * 向控制台和 (Xposed) 宿主环境打印日志 - D - * - * (Xposed) 宿主环境中的日志打印风格为 [[tag]]「类型」--> [msg] - * @param tag 日志打印的标签 - 建议和自己的模块名称设置成一样的 - 默认为 [YukiHookLogger.Configs.tag] - * @param msg 日志打印的内容 - * @param type 日志打印的类型 - 默认为 [LoggerType.BOTH] - */ -fun loggerD(tag: String = YukiHookLogger.Configs.tag, msg: String, type: LoggerType = LoggerType.BOTH) = - baseLogger(type, YukiLoggerData(priority = "D", tag = tag, msg = msg)) - -/** - * 向控制台和 (Xposed) 宿主环境打印日志 - I - * - * (Xposed) 宿主环境中的日志打印风格为 [[tag]]「类型」--> [msg] - * @param tag 日志打印的标签 - 建议和自己的模块名称设置成一样的 - 默认为 [YukiHookLogger.Configs.tag] - * @param msg 日志打印的内容 - * @param type 日志打印的类型 - 默认为 [LoggerType.BOTH] - */ -fun loggerI(tag: String = YukiHookLogger.Configs.tag, msg: String, type: LoggerType = LoggerType.BOTH) = - baseLogger(type, YukiLoggerData(priority = "I", tag = tag, msg = msg)) - -/** - * 向控制台和 (Xposed) 宿主环境打印日志 - W - * - * (Xposed) 宿主环境中的日志打印风格为 [[tag]]「类型」--> [msg] - * @param tag 日志打印的标签 - 建议和自己的模块名称设置成一样的 - 默认为 [YukiHookLogger.Configs.tag] - * @param msg 日志打印的内容 - * @param type 日志打印的类型 - 默认为 [LoggerType.BOTH] - */ -fun loggerW(tag: String = YukiHookLogger.Configs.tag, msg: String, type: LoggerType = LoggerType.BOTH) = - baseLogger(type, YukiLoggerData(priority = "W", tag = tag, msg = msg)) - -/** - * 向控制台和 (Xposed) 宿主环境打印日志 - E - * - * (Xposed) 宿主环境中的日志打印风格为 [[tag]]「类型」--> [msg] - * @param tag 日志打印的标签 - 建议和自己的模块名称设置成一样的 - 默认为 [YukiHookLogger.Configs.tag] - * @param msg 日志打印的内容 - 默认空 - 如果你仅想打印异常堆栈可只设置 [e] - * @param e 可填入异常堆栈信息 - 将自动完整打印到控制台 - * @param type 日志打印的类型 - 默认为 [LoggerType.BOTH] - */ -fun loggerE(tag: String = YukiHookLogger.Configs.tag, msg: String = "", e: Throwable? = null, type: LoggerType = LoggerType.BOTH) = - baseLogger(type, YukiLoggerData(priority = "E", tag = tag, msg = msg, throwable = e)) \ No newline at end of file diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/log/YLog.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/log/YLog.kt new file mode 100644 index 00000000..d968722c --- /dev/null +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/log/YLog.kt @@ -0,0 +1,386 @@ +/* + * YukiHookAPI - An efficient Hook API and Xposed Module solution built in Kotlin. + * Copyright (C) 2019-2023 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 2023/9/27. + */ +package com.highcapable.yukihookapi.hook.log + +import android.system.ErrnoException +import android.util.Log +import com.highcapable.yukihookapi.YukiHookAPI +import com.highcapable.yukihookapi.hook.core.api.helper.YukiHookHelper +import com.highcapable.yukihookapi.hook.factory.current +import com.highcapable.yukihookapi.hook.log.data.YLogData +import com.highcapable.yukihookapi.hook.utils.factory.dumpToString +import com.highcapable.yukihookapi.hook.xposed.bridge.YukiXposedModule +import java.io.File + +/** + * 全局 Log 管理类 + */ +object YLog { + + /** + * 配置 [YLog] + */ + object Configs { + + /** + * 标签 + * + * 显示效果如下 ↓ + * + * ``` + * [YukiHookAPI][...][...] ... + * ``` + */ + const val TAG = 1000 + + /** + * 优先级 + * + * 显示效果如下 ↓ + * + * ``` + * [...][E][...] ... + * ``` + */ + const val PRIORITY = 1001 + + /** + * 当前宿主的包名 + * + * 显示效果如下 ↓ + * + * ``` + * [...][com.demo.test][...] ... + * ``` + */ + const val PACKAGE_NAME = 1002 + + /** + * 当前宿主的用户 ID (主用户不显示) + * + * 显示效果如下 ↓ + * + * ``` + * [...][...][999] ... + * ``` + */ + const val USER_ID = 1003 + + /** + * 这是一个调试日志的全局标识 + * + * 默认文案为 [YukiHookAPI.TAG] + * + * 你可以修改为你自己的文案 + */ + var tag = YukiHookAPI.TAG + + /** + * 是否启用调试日志的输出功能 - 默认启用 + * + * - 关闭后将会停用 [YukiHookAPI] 对全部日志的输出 + * + * 但是不影响当你手动调用下面这些方法输出日志 + * + * [debug]、[info]、[warn]、[error] + * + * 当 [isEnable] 关闭后 [YukiHookAPI.Configs.isDebug] 也将同时关闭 + */ + var isEnable = true + + /** + * 是否启用调试日志的记录功能 - 默认不启用 + * + * 开启后将会在内存中记录全部可用的日志和异常堆栈 + * + * 需要同时启用 [isEnable] 才能有效 + * + * - 过量的日志可能会导致宿主运行缓慢或造成频繁 GC + * + * 开启后你可以调用 [saveToFile] 实时保存日志到文件或使用 [contents] 获取实时日志文件 + */ + var isRecord = false + + /** 当前已添加的元素顺序列表数组 */ + internal var elements = arrayOf(TAG, PRIORITY, PACKAGE_NAME, USER_ID) + + /** + * 自定义调试日志对外显示的元素 + * + * 只对日志记录和 (Xposed) 宿主环境的日志生效 + * + * 日志元素的排列将按照你在 [item] 中设置的顺序进行显示 + * + * 你还可以留空 [item] 以不显示除日志内容外的全部元素 + * + * 可用的元素有:[TAG]、[PRIORITY]、[PACKAGE_NAME]、[USER_ID] + * + * 默认排列方式如下 ↓ + * + * ``` + * [TAG][PRIORITY][PACKAGE_NAME][USER_ID] Message + * ``` + * @param item 自定义的元素数组 + */ + fun elements(vararg item: Int) { + elements = arrayOf(*item.toTypedArray()) + } + + /** 结束方法体 */ + internal fun build() = Unit + } + + /** + * 当前全部已记录的日志数据 + * + * - 获取到的日志数据在 Hook APP (宿主) 及模块进程中是相互隔离的 + */ + val inMemoryData = mutableListOf() + + /** + * 获取当前日志文件内容 + * + * 如果当前没有已记录的日志会返回空字符串 + * + * - 获取到的日志数据在 Hook APP (宿主) 及模块进程中是相互隔离的 + * @return [String] + */ + val contents get() = contents() + + /** + * 获取、格式化当前日志文件内容 + * + * 如果当前没有已记录的日志 ([data] 为空) 会返回空字符串 + * + * - 获取到的日志数据在 Hook APP (宿主) 及模块进程中是相互隔离的 + * @param data 日志数据 - 默认为 [inMemoryData] + * @return [String] + */ + fun contents(data: List = inMemoryData): String { + var content = "" + data.takeIf { it.isNotEmpty() }?.forEach { + content += "${it.head}$it\n" + it.throwable?.also { e -> + content += "${it.head}Dump stack trace for \"${e.current().name}\":\n" + content += e.dumpToString() + } + } + return content + } + + /** + * 清除全部已记录的日志 + * + * 你也可以直接获取 [inMemoryData] 来清除 + * + * - 获取到的日志数据在 Hook APP (宿主) 及模块进程中是相互隔离的 + */ + fun clear() = inMemoryData.clear() + + /** + * 保存当前日志到文件 + * + * 若当前未开启 [Configs.isRecord] 或记录为空则不会进行任何操作 + * + * 日志文件会追加到 [fileName] 的文件结尾 - 若文件不存在会自动创建 + * + * - 文件读写权限取决于当前宿主、模块已获取的权限 + * @param fileName 完整文件名 - 例如 /data/data/.../files/xxx.log + * @param data 日志数据 - 默认为 [inMemoryData] + * @throws ErrnoException 如果目标路径不可写 + */ + fun saveToFile(fileName: String, data: List = inMemoryData) { + if (data.isNotEmpty()) File(fileName).appendText(contents(data)) + } + + /** + * 打印 Debug 级别 Log + * + * 向控制台和 (Xposed) 宿主环境打印日志 + * @param msg 日志打印的内容 - 默认空 - 如果你仅想打印异常堆栈可只设置 [e] + * @param e 可填入异常堆栈信息 - 将自动完整打印到控制台 + * @param tag 日志打印的标签 - 建议和自己的模块名称设置成一样的 - 默认为 [Configs.tag] + * @param env 日志打印的环境 - 默认为 [EnvType.BOTH] + */ + fun debug(msg: String = "", e: Throwable? = null, tag: String = Configs.tag, env: EnvType = EnvType.BOTH) = + log(env, YLogData(priority = "D", tag = tag, msg = msg, throwable = e)) + + /** + * 打印 Info 级别 Log + * + * 向控制台和 (Xposed) 宿主环境打印日志 + * @param msg 日志打印的内容 - 默认空 - 如果你仅想打印异常堆栈可只设置 [e] + * @param e 可填入异常堆栈信息 - 将自动完整打印到控制台 + * @param tag 日志打印的标签 - 建议和自己的模块名称设置成一样的 - 默认为 [Configs.tag] + * @param env 日志打印的环境 - 默认为 [EnvType.BOTH] + */ + fun info(msg: String = "", e: Throwable? = null, tag: String = Configs.tag, env: EnvType = EnvType.BOTH) = + log(env, YLogData(priority = "I", tag = tag, msg = msg, throwable = e)) + + /** + * 打印 Warn 级别 Log + * + * 向控制台和 (Xposed) 宿主环境打印日志 + * @param msg 日志打印的内容 - 默认空 - 如果你仅想打印异常堆栈可只设置 [e] + * @param e 可填入异常堆栈信息 - 将自动完整打印到控制台 + * @param tag 日志打印的标签 - 建议和自己的模块名称设置成一样的 - 默认为 [Configs.tag] + * @param env 日志打印的环境 - 默认为 [EnvType.BOTH] + */ + fun warn(msg: String = "", e: Throwable? = null, tag: String = Configs.tag, env: EnvType = EnvType.BOTH) = + log(env, YLogData(priority = "W", tag = tag, msg = msg, throwable = e)) + + /** + * 打印 Error 级别 Log + * + * 向控制台和 (Xposed) 宿主环境打印日志 + * @param msg 日志打印的内容 - 默认空 - 如果你仅想打印异常堆栈可只设置 [e] + * @param tag 日志打印的标签 - 建议和自己的模块名称设置成一样的 - 默认为 [Configs.tag] + * @param e 可填入异常堆栈信息 - 将自动完整打印到控制台 + * @param env 日志打印的环境 - 默认为 [EnvType.BOTH] + */ + fun error(msg: String = "", e: Throwable? = null, tag: String = Configs.tag, env: EnvType = EnvType.BOTH) = + log(env, YLogData(priority = "E", tag = tag, msg = msg, throwable = e)) + + /** + * [YukiHookAPI] (内部) 打印 Debug 级别 Log + * @param msg 日志打印的内容 - 默认空 - 如果你仅想打印异常堆栈可只设置 [e] + * @param e 可填入异常堆栈信息 - 将自动完整打印到控制台 + * @param isImplicit 是否隐式打印 - 不会记录 - 也不会显示包名和用户 ID + * @param isDisable 禁止打印日志 - 标识后将什么也不做 - 默认否 + */ + internal fun innerD(msg: String = "", e: Throwable? = null, isImplicit: Boolean = false, isDisable: Boolean = false) { + if (Configs.isEnable.not() || isDisable) return + log(EnvType.BOTH, YLogData(priority = "D", msg = msg, throwable = e), isImplicit) + } + + /** + * [YukiHookAPI] (内部) 打印 Info 级别 Log + * @param msg 日志打印的内容 - 默认空 - 如果你仅想打印异常堆栈可只设置 [e] + * @param e 可填入异常堆栈信息 - 将自动完整打印到控制台 + * @param isImplicit 是否隐式打印 - 不会记录 - 也不会显示包名和用户 ID + * @param isDisable 禁止打印日志 - 标识后将什么也不做 - 默认否 + */ + internal fun innerI(msg: String = "", e: Throwable? = null, isImplicit: Boolean = false, isDisable: Boolean = false) { + if (Configs.isEnable.not() || isDisable) return + log(EnvType.BOTH, YLogData(priority = "I", msg = msg, throwable = e), isImplicit) + } + + /** + * [YukiHookAPI] (内部) 打印 Warn 级别 Log + * @param msg 日志打印的内容 - 默认空 - 如果你仅想打印异常堆栈可只设置 [e] + * @param e 可填入异常堆栈信息 - 将自动完整打印到控制台 + * @param isImplicit 是否隐式打印 - 不会记录 - 也不会显示包名和用户 ID + * @param isDisable 禁止打印日志 - 标识后将什么也不做 - 默认否 + */ + internal fun innerW(msg: String = "", e: Throwable? = null, isImplicit: Boolean = false, isDisable: Boolean = false) { + if (Configs.isEnable.not() || isDisable) return + log(EnvType.BOTH, YLogData(priority = "W", msg = msg, throwable = e), isImplicit) + } + + /** + * [YukiHookAPI] (内部) 打印 Error 级别 Log + * @param msg 日志打印的内容 - 默认空 - 如果你仅想打印异常堆栈可只设置 [e] + * @param e 可填入异常堆栈信息 - 将自动完整打印到控制台 + * @param isImplicit 是否隐式打印 - 不会记录 - 也不会显示包名和用户 ID + * @param isDisable 禁止打印日志 - 标识后将什么也不做 - 默认否 + */ + internal fun innerE(msg: String = "", e: Throwable? = null, isImplicit: Boolean = false, isDisable: Boolean = false) { + if (Configs.isEnable.not() || isDisable) return + log(EnvType.BOTH, YLogData(priority = "E", msg = msg, throwable = e), isImplicit) + } + + /** + * 向控制台和 (Xposed) 宿主环境打印日志 - 最终实现方法 + * @param env 日志打印的环境 + * @param data 日志数据 + * @param isImplicit 是否隐式打印 - 不会记录 - 也不会显示包名和用户 ID + */ + private fun log(env: EnvType, data: YLogData, isImplicit: Boolean = false) { + /** 是否为有效日志 */ + val isNotBlankLog = data.msg.isNotBlank() || (data.msg.isBlank() && data.throwable != null) + + /** 打印到 [Log] */ + fun logByLogd() = when (data.priority) { + "D" -> Log.d(data.tag, data.msg) + "I" -> Log.i(data.tag, data.msg) + "W" -> Log.w(data.tag, data.msg) + "E" -> Log.e(data.tag, data.msg, data.throwable) + else -> Log.wtf(data.tag, data.msg, data.throwable) + } + + /** 打印到 (Xposed) 宿主环境 */ + fun logByHooker() { + if (isNotBlankLog) YukiHookHelper.logByHooker(data.also { it.isImplicit = isImplicit }.toString(), data.throwable) + } + when (env) { + EnvType.LOGD -> logByLogd() + EnvType.XPOSED_ENVIRONMENT -> logByHooker() + EnvType.SCOPE -> if (YukiXposedModule.isXposedEnvironment) logByHooker() else logByLogd() + EnvType.BOTH -> { + logByLogd() + if (YukiXposedModule.isXposedEnvironment) logByHooker() + } + } + if (isImplicit.not() && Configs.isRecord && isNotBlankLog) inMemoryData.add(data) + } + + /** + * 需要打印的日志环境类型 + * + * 决定于模块与 (Xposed) 宿主环境使用的打印方式 + */ + enum class EnvType { + /** 仅使用 [Log] */ + LOGD, + + /** + * 仅在 (Xposed) 宿主环境使用 + * + * - 只能在 (Xposed) 宿主环境中使用 - 模块环境将不生效 + */ + XPOSED_ENVIRONMENT, + + /** + * 分区使用 + * + * (Xposed) 宿主环境仅使用 [XPOSED_ENVIRONMENT] + * + * 模块环境仅使用 [LOGD] + */ + SCOPE, + + /** + * 同时使用 + * + * (Xposed) 宿主环境使用 [LOGD] 与 [XPOSED_ENVIRONMENT] + * + * 模块环境仅使用 [LOGD] + */ + BOTH + } +} \ No newline at end of file diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/log/_deprecated.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/log/_deprecated.kt new file mode 100644 index 00000000..d8a3ea20 --- /dev/null +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/log/_deprecated.kt @@ -0,0 +1,235 @@ +/* + * YukiHookAPI - An efficient Hook API and Xposed Module solution built in Kotlin. + * Copyright (C) 2019-2023 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/2/3. + */ +@file:Suppress("unused", "MemberVisibilityCanBePrivate", "DeprecatedCallableAddReplaceWith", "DEPRECATION") + +package com.highcapable.yukihookapi.hook.log + +import java.io.Serializable + +/** + * - LoggerFactory 已被弃用 - 请迁移到 [YLog] + */ +@Deprecated(message = "请迁移到 YLog") +enum class LoggerType { + /** + * - LoggerFactory 已被弃用 - 请迁移到 [YLog] + */ + @Deprecated(message = "请迁移到 YLog") + LOGD, + + /** + * - LoggerFactory 已被弃用 - 请迁移到 [YLog] + */ + @Deprecated(message = "请迁移到 YLog") + XPOSEDBRIDGE, + + /** + * - LoggerFactory 已被弃用 - 请迁移到 [YLog] + */ + @Deprecated(message = "请迁移到 YLog") + XPOSED_ENVIRONMENT, + + /** + * - LoggerFactory 已被弃用 - 请迁移到 [YLog] + */ + @Deprecated(message = "请迁移到 YLog") + SCOPE, + + /** + * - LoggerFactory 已被弃用 - 请迁移到 [YLog] + */ + @Deprecated(message = "请迁移到 YLog") + BOTH +} + +/** + * - LoggerFactory 已被弃用 - 请迁移到 [YLog] + */ +@Deprecated(message = "请迁移到 YLog") +data class YukiLoggerData @Deprecated(message = "请迁移到 YLog") internal constructor( + @Deprecated(message = "请迁移到 YLog") + var timestamp: Long = 0L, + @Deprecated(message = "请迁移到 YLog") + var time: String = "", + @Deprecated(message = "请迁移到 YLog") + var tag: String = YukiHookLogger.Configs.tag, + @Deprecated(message = "请迁移到 YLog") + var priority: String = "", + @Deprecated(message = "请迁移到 YLog") + var packageName: String = "", + @Deprecated(message = "请迁移到 YLog") + var userId: Int = 0, + @Deprecated(message = "请迁移到 YLog") + var msg: String = "", + @Deprecated(message = "请迁移到 YLog") + var throwable: Throwable? = null +) : Serializable + +/** + * - LoggerFactory 已被弃用 - 请迁移到 [YLog] + */ +@Deprecated(message = "请迁移到 YLog") +object YukiHookLogger { + + /** + * - LoggerFactory 已被弃用 - 请迁移到 [YLog] + */ + @Deprecated(message = "请迁移到 YLog") + val inMemoryData = ArrayList() + + /** + * - LoggerFactory 已被弃用 - 请迁移到 [YLog] + */ + @Deprecated(message = "请迁移到 YLog") + val contents get() = "" + + /** + * - LoggerFactory 已被弃用 - 请迁移到 [YLog] + */ + @Deprecated(message = "请迁移到 YLog") + fun contents(data: ArrayList = inMemoryData) = "" + + /** + * - LoggerFactory 已被弃用 - 请迁移到 [YLog] + */ + @Deprecated(message = "请迁移到 YLog") + fun clear() = Unit + + /** + * - LoggerFactory 已被弃用 - 请迁移到 [YLog] + */ + @Deprecated(message = "请迁移到 YLog") + fun saveToFile(fileName: String, data: ArrayList = inMemoryData) = Unit + + /** + * - LoggerFactory 已被弃用 - 请迁移到 [YLog] + */ + @Deprecated(message = "请迁移到 YLog") + object Configs { + + /** + * - LoggerFactory 已被弃用 - 请迁移到 [YLog] + */ + @Deprecated(message = "请迁移到 YLog") + const val TAG = "" + + /** + * - LoggerFactory 已被弃用 - 请迁移到 [YLog] + */ + @Deprecated(message = "请迁移到 YLog") + const val PRIORITY = -1 + + /** + * - LoggerFactory 已被弃用 - 请迁移到 [YLog] + */ + @Deprecated(message = "请迁移到 YLog") + const val PACKAGE_NAME = -1 + + /** + * - LoggerFactory 已被弃用 - 请迁移到 [YLog] + */ + @Deprecated(message = "请迁移到 YLog") + const val USER_ID = -1 + + /** + * - LoggerFactory 已被弃用 - 请迁移到 [YLog] + */ + @Deprecated(message = "请迁移到 YLog") + var isEnable = true + + /** + * - LoggerFactory 已被弃用 - 请迁移到 [YLog] + */ + @Deprecated(message = "请迁移到 YLog") + var isRecord = false + + /** + * - LoggerFactory 已被弃用 - 请迁移到 [YLog] + */ + @Deprecated(message = "请迁移到 YLog") + var tag = "" + + /** + * - LoggerFactory 已被弃用 - 请迁移到 [YLog] + */ + @Deprecated(message = "请迁移到 YLog") + fun elements(vararg item: Int) = Unit + } +} + +/** + * - LoggerFactory 已被弃用 - 请迁移到 [YLog] + */ +@Deprecated(message = "请迁移到 YLog", ReplaceWith("YLog.debug(msg = msg, tag = tag)")) +fun loggerD(tag: String = YLog.Configs.tag, msg: String, type: LoggerType = LoggerType.BOTH) { + YLog.debug(msg, tag = tag, env = when (type) { + LoggerType.BOTH -> YLog.EnvType.BOTH + LoggerType.LOGD -> YLog.EnvType.LOGD + LoggerType.SCOPE -> YLog.EnvType.SCOPE + LoggerType.XPOSEDBRIDGE, LoggerType.XPOSED_ENVIRONMENT -> YLog.EnvType.XPOSED_ENVIRONMENT + }) +} + +/** + * - LoggerFactory 已被弃用 - 请迁移到 [YLog] + */ +@Deprecated(message = "请迁移到 YLog", ReplaceWith("YLog.info(msg = msg, tag = tag)")) +fun loggerI(tag: String = YLog.Configs.tag, msg: String, type: LoggerType = LoggerType.BOTH) { + YLog.info(msg, tag = tag, env = when (type) { + LoggerType.BOTH -> YLog.EnvType.BOTH + LoggerType.LOGD -> YLog.EnvType.LOGD + LoggerType.SCOPE -> YLog.EnvType.SCOPE + LoggerType.XPOSEDBRIDGE, LoggerType.XPOSED_ENVIRONMENT -> YLog.EnvType.XPOSED_ENVIRONMENT + }) +} + +/** + * - LoggerFactory 已被弃用 - 请迁移到 [YLog] + */ +@Deprecated(message = "请迁移到 YLog", ReplaceWith("YLog.warn(msg = msg, tag = tag)")) +fun loggerW(tag: String = YLog.Configs.tag, msg: String, type: LoggerType = LoggerType.BOTH) { + YLog.warn(msg, tag = tag, env = when (type) { + LoggerType.BOTH -> YLog.EnvType.BOTH + LoggerType.LOGD -> YLog.EnvType.LOGD + LoggerType.SCOPE -> YLog.EnvType.SCOPE + LoggerType.XPOSEDBRIDGE, LoggerType.XPOSED_ENVIRONMENT -> YLog.EnvType.XPOSED_ENVIRONMENT + }) +} + +/** + * - LoggerFactory 已被弃用 - 请迁移到 [YLog] + */ +@Deprecated(message = "请迁移到 YLog", ReplaceWith("YLog.error(msg = msg, e = e, tag = tag)")) +fun loggerE(tag: String = YLog.Configs.tag, msg: String = "", e: Throwable? = null, type: LoggerType = LoggerType.BOTH) { + YLog.error(msg, e = e, tag = tag, env = when (type) { + LoggerType.BOTH -> YLog.EnvType.BOTH + LoggerType.LOGD -> YLog.EnvType.LOGD + LoggerType.SCOPE -> YLog.EnvType.SCOPE + LoggerType.XPOSEDBRIDGE, LoggerType.XPOSED_ENVIRONMENT -> YLog.EnvType.XPOSED_ENVIRONMENT + }) +} \ No newline at end of file diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/log/data/YLogData.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/log/data/YLogData.kt new file mode 100644 index 00000000..9f0bc9e1 --- /dev/null +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/log/data/YLogData.kt @@ -0,0 +1,85 @@ +/* + * YukiHookAPI - An efficient Hook API and Xposed Module solution built in Kotlin. + * Copyright (C) 2019-2023 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 2023/9/27. + */ +package com.highcapable.yukihookapi.hook.log.data + +import com.highcapable.yukihookapi.hook.log.YLog +import com.highcapable.yukihookapi.hook.xposed.bridge.YukiXposedModule +import com.highcapable.yukihookapi.hook.xposed.parasitic.AppParasitics +import java.io.Serializable +import java.text.SimpleDateFormat +import java.util.Date +import java.util.Locale + +/** + * 调试日志数据实现类 + * @param timestamp 当前时间戳 + * @param time 当前 UTC 时间 + * @param tag 当前标签 + * @param priority 当前优先级 - D、I、W、E + * @param packageName 当前包名 + * @param userId 当前用户 ID + * @param msg 当前日志内容 + * @param throwable 当前异常堆栈 + */ +data class YLogData internal constructor( + var timestamp: Long = 0L, + var time: String = "", + var tag: String = YLog.Configs.tag, + var priority: String = "", + var packageName: String = "", + var userId: Int = 0, + var msg: String = "", + var throwable: Throwable? = null +) : Serializable { + + /** 是否隐式打印 */ + internal var isImplicit = false + + init { + timestamp = System.currentTimeMillis() + time = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.ROOT).format(Date(timestamp)) + packageName = if (YukiXposedModule.isXposedEnvironment) YukiXposedModule.hostProcessName else AppParasitics.currentPackageName + userId = AppParasitics.findUserId(AppParasitics.currentPackageName) + } + + /** + * 获取头部时间字符串 + * @return [String] + */ + internal val head get() = "$time ------ " + + override fun toString(): String { + var content = "" + YLog.Configs.elements.takeIf { it.isNotEmpty() }?.forEach { + if (it == YLog.Configs.TAG) content += "[$tag]" + if (it == YLog.Configs.PRIORITY) content += "[$priority]" + if (it == YLog.Configs.PACKAGE_NAME && isImplicit.not() && packageName.isNotBlank()) content += "[$packageName]" + if (it == YLog.Configs.USER_ID && isImplicit.not() && userId != 0) content += "[$userId]" + }; return content.takeIf { it.isNotBlank() }?.let { "$content $msg" } ?: msg + } +} \ No newline at end of file diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/param/HookParam.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/param/HookParam.kt index 7abf2c4c..b3cb016a 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/param/HookParam.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/param/HookParam.kt @@ -36,7 +36,7 @@ import com.highcapable.yukihookapi.hook.core.YukiMemberHookCreator.MemberHookCre import com.highcapable.yukihookapi.hook.core.api.helper.YukiHookHelper import com.highcapable.yukihookapi.hook.core.api.proxy.YukiHookCallback import com.highcapable.yukihookapi.hook.factory.classOf -import com.highcapable.yukihookapi.hook.log.yLoggerE +import com.highcapable.yukihookapi.hook.log.YLog import java.lang.reflect.Constructor import java.lang.reflect.Member import java.lang.reflect.Method @@ -179,7 +179,7 @@ class HookParam internal constructor( */ fun Throwable.throwToApp() { param?.throwable = this - yLoggerE(msg = message ?: "", e = this) + YLog.innerE(message ?: "", this) } /** diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/param/PackageParam.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/param/PackageParam.kt index b75f5766..0104dce2 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/param/PackageParam.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/param/PackageParam.kt @@ -47,7 +47,7 @@ import com.highcapable.yukihookapi.hook.core.finder.classes.DexClassFinder import com.highcapable.yukihookapi.hook.core.finder.tools.ReflectionTool import com.highcapable.yukihookapi.hook.core.finder.type.factory.ClassConditions import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker -import com.highcapable.yukihookapi.hook.log.yLoggerW +import com.highcapable.yukihookapi.hook.log.YLog import com.highcapable.yukihookapi.hook.param.wrapper.PackageParamWrapper import com.highcapable.yukihookapi.hook.utils.factory.value import com.highcapable.yukihookapi.hook.xposed.bridge.YukiXposedModule @@ -422,7 +422,7 @@ open class PackageParam internal constructor(internal var wrapper: PackageParamW if (it.packageName.isNotBlank() && it.type != HookEntryType.ZYGOTE) if (it.packageName == wrapper?.packageName) hooker.assignInstance(packageParam = this) - else yLoggerW( + else YLog.innerW( msg = "This Hooker \"${hooker::class.java.name}\" is singleton or reused, " + "but the current process has multiple package name \"${wrapper?.packageName}\", " + "the original is \"${it.packageName}\"\n" + diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/bridge/YukiXposedModule.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/bridge/YukiXposedModule.kt index 2808a500..b0dcd7f6 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/bridge/YukiXposedModule.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/bridge/YukiXposedModule.kt @@ -34,7 +34,7 @@ import android.util.ArrayMap import com.highcapable.yukihookapi.YukiHookAPI import com.highcapable.yukihookapi.hook.core.api.compat.HookApiCategoryHelper import com.highcapable.yukihookapi.hook.factory.hasClass -import com.highcapable.yukihookapi.hook.log.yLoggerE +import com.highcapable.yukihookapi.hook.log.YLog import com.highcapable.yukihookapi.hook.param.PackageParam import com.highcapable.yukihookapi.hook.param.wrapper.PackageParamWrapper import com.highcapable.yukihookapi.hook.xposed.bridge.proxy.IYukiXposedModuleLifecycle @@ -220,7 +220,7 @@ internal object YukiXposedModule : IYukiXposedModuleLifecycle { AppParasitics.hookModuleAppRelated(it.appClassLoader, it.type) if (it.type == HookEntryType.PACKAGE) AppParasitics.registerToAppLifecycle(it.packageName) if (it.type == HookEntryType.RESOURCES) isSupportResourcesHook = true - }.onFailure { yLoggerE(msg = "An exception occurred in the Hooking Process of YukiHookAPI", e = it) } + }.onFailure { YLog.innerE("An exception occurred in the Hooking Process of YukiHookAPI", it) } } } } \ No newline at end of file diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/bridge/caller/YukiXposedModuleCaller.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/bridge/caller/YukiXposedModuleCaller.kt index 3ebb416c..3c71d4ca 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/bridge/caller/YukiXposedModuleCaller.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/bridge/caller/YukiXposedModuleCaller.kt @@ -30,7 +30,7 @@ package com.highcapable.yukihookapi.hook.xposed.bridge.caller import android.content.pm.ApplicationInfo -import com.highcapable.yukihookapi.hook.log.yLoggerE +import com.highcapable.yukihookapi.hook.log.YLog import com.highcapable.yukihookapi.hook.xposed.bridge.YukiXposedModule import com.highcapable.yukihookapi.hook.xposed.bridge.resources.YukiResources import com.highcapable.yukihookapi.hook.xposed.bridge.type.HookEntryType @@ -77,9 +77,9 @@ internal object YukiXposedModuleCaller { ) = YukiXposedModule.onPackageLoaded(type, packageName, processName, appClassLoader, appInfo, appResources) /** - * 打印内部 E 级别的日志 + * 打印 Error 级别 Log * @param msg 日志打印的内容 * @param e 异常堆栈信息 - 默认空 */ - internal fun internalLoggerE(msg: String, e: Throwable? = null) = yLoggerE(msg = msg, e = e) + internal fun callLogError(msg: String, e: Throwable? = null) = YLog.innerE(msg, e) } \ No newline at end of file diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/bridge/resources/YukiResources.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/bridge/resources/YukiResources.kt index 7b8c4499..3f3b54ed 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/bridge/resources/YukiResources.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/bridge/resources/YukiResources.kt @@ -33,7 +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.log.YLog import com.highcapable.yukihookapi.hook.xposed.bridge.resources.YukiResources.LayoutInflatedParam import de.robv.android.xposed.callbacks.XC_LayoutInflated @@ -153,7 +153,7 @@ class YukiResources private constructor(private val baseInstance: XResources) : 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) } + }.onFailure { YLog.innerE("Failed to execute method \"$name\", maybe your Hook Framework not support Resources Hook", it) } } } diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/channel/YukiHookDataChannel.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/channel/YukiHookDataChannel.kt index 5c75595a..2964bfc9 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/channel/YukiHookDataChannel.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/channel/YukiHookDataChannel.kt @@ -45,10 +45,8 @@ import android.os.Parcelable import android.os.TransactionTooLargeException import com.highcapable.yukihookapi.YukiHookAPI import com.highcapable.yukihookapi.annotation.CauseProblemsApi -import com.highcapable.yukihookapi.hook.log.YukiHookLogger -import com.highcapable.yukihookapi.hook.log.YukiLoggerData -import com.highcapable.yukihookapi.hook.log.yLoggerE -import com.highcapable.yukihookapi.hook.log.yLoggerW +import com.highcapable.yukihookapi.hook.log.YLog +import com.highcapable.yukihookapi.hook.log.data.YLogData import com.highcapable.yukihookapi.hook.utils.factory.RandomSeed import com.highcapable.yukihookapi.hook.xposed.application.ModuleApplication import com.highcapable.yukihookapi.hook.xposed.bridge.YukiXposedModule @@ -92,7 +90,7 @@ class YukiHookDataChannel private constructor() { private const val GET_YUKI_LOGGER_INMEMORY_DATA = "yuki_logger_inmemory_data_get" /** 调试日志数据结果标签 */ - private val RESULT_YUKI_LOGGER_INMEMORY_DATA = ChannelData>("yuki_logger_inmemory_data_result") + private val RESULT_YUKI_LOGGER_INMEMORY_DATA = ChannelData>("yuki_logger_inmemory_data_result") /** 仅监听结果键值 */ private const val VALUE_WAIT_FOR_LISTENER = "wait_for_listener_value" @@ -167,7 +165,7 @@ class YukiHookDataChannel private constructor() { destroyedCallbacks.takeIf { it.isNotEmpty() }?.forEach { remove(it) } } } - }.onFailure { yLoggerE(msg = "Received action \"$action\" failed", e = it) } + }.onFailure { YLog.innerE("Received action \"$action\" failed", it) } } } } @@ -191,7 +189,7 @@ class YukiHookDataChannel private constructor() { context is Application || isXposedEnvironment || (((context ?: receiverContext) ?.getSystemService(ACTIVITY_SERVICE) as? ActivityManager?) ?.getRunningTasks(9999)?.filter { context?.javaClass?.name == it?.topActivity?.className }?.size ?: 0) > 0 - }.getOrNull() ?: yLoggerW(msg = "Couldn't got current Activity status because a SecurityException blocked it").let { false } + }.getOrNull() ?: YLog.innerW("Couldn't got current Activity status because a SecurityException blocked it").let { false } /** * 获取宿主广播 Action 名称 @@ -237,7 +235,7 @@ class YukiHookDataChannel private constructor() { } /** 注册监听模块与宿主之间的调试日志数据 */ wait(GET_YUKI_LOGGER_INMEMORY_DATA) { fromPackageName -> - nameSpace(context, fromPackageName).put(RESULT_YUKI_LOGGER_INMEMORY_DATA, YukiHookLogger.inMemoryData) + nameSpace(context, fromPackageName).put(RESULT_YUKI_LOGGER_INMEMORY_DATA, YLog.inMemoryData) } } } @@ -439,17 +437,17 @@ class YukiHookDataChannel private constructor() { } /** - * 获取模块与宿主之间的 [ArrayList]<[YukiLoggerData]> 数据 + * 获取模块与宿主之间的 [List]<[YLogData]> 数据 * * 由于模块与宿主处于不同的进程 - 我们可以使用数据通讯桥访问各自的调试日志数据 * - * - 模块与宿主必须启用 [YukiHookLogger.Configs.isRecord] 才能获取到调试日志数据 + * - 模块与宿主必须启用 [YLog.Configs.isRecord] 才能获取到调试日志数据 * * - 由于 Android 限制了数据传输大小的最大值 - 如果调试日志过多将会自动进行分段发送 - 数据越大速度越慢 * @param priority 响应优先级 - 默认不设置 - * @param result 回调 [ArrayList]<[YukiLoggerData]> + * @param result 回调 [List]<[YLogData]> */ - fun obtainLoggerInMemoryData(priority: ChannelPriority? = null, result: (ArrayList) -> Unit) { + fun obtainLoggerInMemoryData(priority: ChannelPriority? = null, result: (List) -> Unit) { wait(RESULT_YUKI_LOGGER_INMEMORY_DATA, priority) { result(it) } put(GET_YUKI_LOGGER_INMEMORY_DATA, packageName) } @@ -565,10 +563,10 @@ class YukiHookDataChannel private constructor() { segmentsTempData.remove(wrapper.wrapperId) } } - else -> yLoggerE(msg = "Unsupported segments data key of \"${wrapper.instance.key}\"'s type") + else -> YLog.innerE("Unsupported segments data key of \"${wrapper.instance.key}\"'s type") } }.onFailure { - yLoggerE(msg = "YukiHookDataChannel cannot merge this segments data key of \"${wrapper.instance.key}\"", e = it) + YLog.innerE("YukiHookDataChannel cannot merge this segments data key of \"${wrapper.instance.key}\"", it) } else wrapper.instance.value?.let { e -> result(e) } } @@ -583,7 +581,7 @@ class YukiHookDataChannel private constructor() { /** 当前需要发送的数据字节大小 */ val dataByteSize = wrapper.instance.calDataByteSize() - if (dataByteSize < 0 && isAllowSendTooLargeData.not()) return yLoggerE( + if (dataByteSize < 0 && isAllowSendTooLargeData.not()) return YLog.innerE( msg = "YukiHookDataChannel cannot calculate the byte size of the data key of \"${wrapper.instance.key}\" to be sent, " + "so this data cannot be sent\n" + "If you want to lift this restriction, use the allowSendTooLargeData function when calling, " + @@ -595,7 +593,7 @@ class YukiHookDataChannel private constructor() { * @param size 分段总大小 (长度) */ fun loggerForTooLargeData(name: String, size: Int) { - if (YukiHookAPI.Configs.isDebug) yLoggerW( + if (YukiHookAPI.Configs.isDebug) YLog.innerW( msg = "This data key of \"${wrapper.instance.key}\" type $name is too large (total ${dataByteSize / 1024f} KB, " + "limit ${receiverDataMaxByteSize / 1024f} KB), will be segmented to $size piece to send" ) @@ -605,7 +603,7 @@ class YukiHookDataChannel private constructor() { * 如果数据过大且无法分段打印错误信息 * @param suggestionMessage 建议内容 - 默认空 */ - fun loggerForUnprocessableData(suggestionMessage: String = "") = yLoggerE( + fun loggerForUnprocessableData(suggestionMessage: String = "") = YLog.innerE( msg = "YukiHookDataChannel cannot send this data key of \"${wrapper.instance.key}\" type ${wrapper.instance.value?.javaClass}, " + "because it is too large (total ${dataByteSize / 1024f} KB, " + "limit ${receiverDataMaxByteSize / 1024f} KB) and cannot be segmented\n" + @@ -710,7 +708,7 @@ class YukiHookDataChannel private constructor() { if (packageName != AppParasitics.SYSTEM_FRAMEWORK_NAME) setPackage(if (isXposedEnvironment) YukiXposedModule.modulePackageName else packageName) putExtra(wrapper.instance.key + keyNonRepeatName, wrapper) - }) ?: yLoggerE(msg = "Failed to sendBroadcast like \"${wrapper.instance.key}\", because got null context in \"$packageName\"") + }) ?: YLog.innerE("Failed to sendBroadcast like \"${wrapper.instance.key}\", because got null context in \"$packageName\"") } } } \ No newline at end of file diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/parasitic/AppParasitics.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/parasitic/AppParasitics.kt index a7148d90..cc9bcc14 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/parasitic/AppParasitics.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/parasitic/AppParasitics.kt @@ -63,8 +63,7 @@ import com.highcapable.yukihookapi.hook.factory.hasMethod import com.highcapable.yukihookapi.hook.factory.method import com.highcapable.yukihookapi.hook.factory.toClass import com.highcapable.yukihookapi.hook.factory.toClassOrNull -import com.highcapable.yukihookapi.hook.log.yLoggerE -import com.highcapable.yukihookapi.hook.log.yLoggerW +import com.highcapable.yukihookapi.hook.log.YLog import com.highcapable.yukihookapi.hook.type.android.ActivityManagerClass import com.highcapable.yukihookapi.hook.type.android.ActivityManagerNativeClass import com.highcapable.yukihookapi.hook.type.android.ActivityTaskManagerClass @@ -199,7 +198,7 @@ internal object AppParasitics { */ internal fun hookClassLoader(loader: ClassLoader?, result: (Class<*>) -> Unit) { if (loader == null) return - if (YukiXposedModule.isXposedEnvironment.not()) return yLoggerW(msg = "You can only use hook ClassLoader method in Xposed Environment") + if (YukiXposedModule.isXposedEnvironment.not()) return YLog.innerW("You can only use hook ClassLoader method in Xposed Environment") classLoaderCallbacks[loader.hashCode()] = result if (isClassLoaderHooked) return runCatching { @@ -211,7 +210,7 @@ internal object AppParasitics { } }) isClassLoaderHooked = true - }.onFailure { yLoggerW(msg = "Try to hook ClassLoader failed: $it") } + }.onFailure { YLog.innerW("Try to hook ClassLoader failed: $it") } } /** @@ -270,7 +269,7 @@ internal object AppParasitics { */ fun YukiHookCallback.Param.throwToAppOrLogger(throwable: Throwable) { if (AppLifecycleCallback.isOnFailureThrowToApp) this.throwable = throwable - else yLoggerE(msg = "An exception occurred during AppLifecycle event", e = throwable) + else YLog.innerE("An exception occurred during AppLifecycle event", e = throwable) } /** Hook [Application] 装载方法 */ runCatching { @@ -378,14 +377,14 @@ internal object AppParasitics { internal fun injectModuleAppResources(hostResources: Resources) { if (YukiXposedModule.isXposedEnvironment) runCatching { if (currentPackageName == YukiXposedModule.modulePackageName) - return yLoggerE(msg = "You cannot inject module resources into yourself") + return YLog.innerE("You cannot inject module resources into yourself") hostResources.assets.current(ignored = true).method { name = "addAssetPath" param(StringClass) }.call(YukiXposedModule.moduleAppFilePath) }.onFailure { - yLoggerE(msg = "Failed to inject module resources into [$hostResources]", e = it) - } else yLoggerW(msg = "You can only inject module resources in Xposed Environment") + YLog.innerE("Failed to inject module resources into [$hostResources]", it) + } else YLog.innerW("You can only inject module resources in Xposed Environment") } /** @@ -396,9 +395,9 @@ internal object AppParasitics { @RequiresApi(Build.VERSION_CODES.N) internal fun registerModuleAppActivities(context: Context, proxy: Any?) { if (isActivityProxyRegistered) return - if (YukiXposedModule.isXposedEnvironment.not()) return yLoggerW(msg = "You can only register Activity Proxy in Xposed Environment") - if (context.packageName == YukiXposedModule.modulePackageName) return yLoggerE(msg = "You cannot register Activity Proxy into yourself") - if (Build.VERSION.SDK_INT < 24) return yLoggerE(msg = "Activity Proxy only support for Android 7.0 (API 24) or higher") + if (YukiXposedModule.isXposedEnvironment.not()) return YLog.innerW("You can only register Activity Proxy in Xposed Environment") + if (context.packageName == YukiXposedModule.modulePackageName) return YLog.innerE("You cannot register Activity Proxy into yourself") + if (Build.VERSION.SDK_INT < 24) return YLog.innerE("Activity Proxy only support for Android 7.0 (API 24) or higher") runCatching { ActivityProxyConfig.apply { proxyIntentName = "${YukiXposedModule.modulePackageName}.ACTIVITY_PROXY_INTENT" @@ -444,7 +443,7 @@ internal object AppParasitics { } } isActivityProxyRegistered = true - }.onFailure { yLoggerE(msg = "Activity Proxy initialization failed because got an Exception", e = it) } + }.onFailure { YLog.innerE("Activity Proxy initialization failed because got an Exception", it) } } /** diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/parasitic/activity/delegate/caller/HandlerDelegateCaller.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/parasitic/activity/delegate/caller/HandlerDelegateCaller.kt index 67ae84e3..20f84935 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/parasitic/activity/delegate/caller/HandlerDelegateCaller.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/parasitic/activity/delegate/caller/HandlerDelegateCaller.kt @@ -39,7 +39,7 @@ import android.os.Message import com.highcapable.yukihookapi.hook.factory.current import com.highcapable.yukihookapi.hook.factory.field import com.highcapable.yukihookapi.hook.factory.method -import com.highcapable.yukihookapi.hook.log.yLoggerE +import com.highcapable.yukihookapi.hook.log.YLog import com.highcapable.yukihookapi.hook.type.android.ActivityThreadClass import com.highcapable.yukihookapi.hook.type.android.ClientTransactionClass import com.highcapable.yukihookapi.hook.type.android.IBinderClass @@ -76,7 +76,7 @@ internal object HandlerDelegateCaller { set(intent.getParcelableExtra(ActivityProxyConfig.proxyIntentName)) } } - }.onFailure { yLoggerE(msg = "Activity Proxy got an Exception in msg.what [$LAUNCH_ACTIVITY]", e = it) } + }.onFailure { YLog.innerE("Activity Proxy got an Exception in msg.what [$LAUNCH_ACTIVITY]", it) } EXECUTE_TRANSACTION -> msg.obj?.runCatching client@{ ClientTransactionClass.method { name = "getCallbacks" }.ignored().get(this).list().takeIf { it.isNotEmpty() } ?.forEach { item -> @@ -100,7 +100,7 @@ internal object HandlerDelegateCaller { } } } - }?.onFailure { yLoggerE(msg = "Activity Proxy got an Exception in msg.what [$EXECUTE_TRANSACTION]", e = it) } + }?.onFailure { YLog.innerE("Activity Proxy got an Exception in msg.what [$EXECUTE_TRANSACTION]", it) } } return baseInstance?.handleMessage(msg) ?: false } diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookPrefsBridge.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookPrefsBridge.kt index a9f20d80..a5b82b8a 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookPrefsBridge.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookPrefsBridge.kt @@ -37,8 +37,7 @@ import android.content.SharedPreferences import android.util.ArrayMap import androidx.preference.PreferenceFragmentCompat import com.highcapable.yukihookapi.YukiHookAPI -import com.highcapable.yukihookapi.hook.log.yLoggerE -import com.highcapable.yukihookapi.hook.log.yLoggerW +import com.highcapable.yukihookapi.hook.log.YLog import com.highcapable.yukihookapi.hook.xposed.bridge.YukiXposedModule import com.highcapable.yukihookapi.hook.xposed.bridge.delegate.XSharedPreferencesDelegate import com.highcapable.yukihookapi.hook.xposed.parasitic.AppParasitics @@ -150,7 +149,7 @@ class YukiHookPrefsBridge private constructor(private var context: Context? = nu makeWorldReadable() reload() } - }.onFailure { yLoggerE(msg = it.message ?: "Operating system not supported", e = it) }.getOrNull() + }.onFailure { YLog.innerE(it.message ?: "Operating system not supported", it) }.getOrNull() ?: error("Cannot load the XSharedPreferences, maybe is your Hook Framework not support it") } @@ -680,7 +679,7 @@ class YukiHookPrefsBridge private constructor(private var context: Context? = nu */ private inline fun specifiedScope(callback: () -> Unit): Editor { if (isXposedEnvironment.not() || isUsingNativeStorage) callback() - else yLoggerW(msg = "YukiHookPrefsBridge.Editor not allowed in Xposed Environment") + else YLog.innerW("YukiHookPrefsBridge.Editor not allowed in Xposed Environment") return this } } diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/proxy/YukiHookXposedInitProxy.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/proxy/YukiHookXposedInitProxy.kt index f166cd48..e3222ccc 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/proxy/YukiHookXposedInitProxy.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/proxy/YukiHookXposedInitProxy.kt @@ -30,7 +30,6 @@ package com.highcapable.yukihookapi.hook.xposed.proxy import com.highcapable.yukihookapi.YukiHookAPI -import com.highcapable.yukihookapi.hook.log.yLoggerW /** * [YukiHookAPI] 的 Xposed 装载 API 调用接口 @@ -48,7 +47,7 @@ interface YukiHookXposedInitProxy { * - 请将接口迁移到 [IYukiHookXposedInit] */ @Deprecated(message = "请将接口迁移到 IYukiHookXposedInit", level = DeprecationLevel.ERROR) - fun onInit() = yLoggerW(msg = "YukiHookXposedInitProxy was deprecated") + fun onInit() = Unit /** * - 此方法已过时 @@ -56,5 +55,5 @@ interface YukiHookXposedInitProxy { * - 请将接口迁移到 [IYukiHookXposedInit] */ @Deprecated(message = "请将接口迁移到 IYukiHookXposedInit", level = DeprecationLevel.ERROR) - fun onHook() = yLoggerW(msg = "YukiHookXposedInitProxy was deprecated") + fun onHook() = Unit } \ No newline at end of file diff --git a/yukihookapi-ksp-xposed/src/api/kotlin/com/highcapable/yukihookapi/factory/CodeSourceFileFactory.kt b/yukihookapi-ksp-xposed/src/api/kotlin/com/highcapable/yukihookapi/factory/CodeSourceFileFactory.kt index ac2333dd..7826f2cc 100644 --- a/yukihookapi-ksp-xposed/src/api/kotlin/com/highcapable/yukihookapi/factory/CodeSourceFileFactory.kt +++ b/yukihookapi-ksp-xposed/src/api/kotlin/com/highcapable/yukihookapi/factory/CodeSourceFileFactory.kt @@ -346,12 +346,12 @@ fun GenerateData.sources() = mapOf( hookEntry.onXposedEvent() hookEntry.onInit() if (${ExternalCallerName.YukiXposedModuleCaller.second}.isXposedCallbackSetUp) { - ${ExternalCallerName.YukiXposedModuleCaller.second}.internalLoggerE("You cannot load a hooker in \"onInit\" or \"onXposedEvent\" method! Aborted") + ${ExternalCallerName.YukiXposedModuleCaller.second}.callLogError("You cannot load a hooker in \"onInit\" or \"onXposedEvent\" method! Aborted") return } hookEntry.onHook() ${ExternalCallerName.YukiXposedModuleCaller.second}.callOnFinishLoadModule() - }.onFailure { ${ExternalCallerName.YukiXposedModuleCaller.second}.internalLoggerE("YukiHookAPI try to load hook entry class failed", it) } + }.onFailure { ${ExternalCallerName.YukiXposedModuleCaller.second}.callLogError("YukiHookAPI try to load hook entry class failed", it) } ${ExternalCallerName.YukiXposedModuleCaller.second}.callOnPackageLoaded( type = when { isZygoteLoaded -> HookEntryType.ZYGOTE @@ -373,7 +373,7 @@ fun GenerateData.sources() = mapOf( ${ExternalCallerName.YukiXposedModuleCaller.second}.callOnStartLoadModule(modulePackageName, sparam.modulePath) callOnXposedModuleLoaded(isZygoteLoaded = true) isZygoteCalled = true - }.onFailure { ${ExternalCallerName.YukiXposedModuleCaller.second}.internalLoggerE("An exception occurred when YukiHookAPI loading Xposed Module", it) } + }.onFailure { ${ExternalCallerName.YukiXposedModuleCaller.second}.callLogError("An exception occurred when YukiHookAPI loading Xposed Module", it) } } fun callHandleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam?) {