diff --git a/Android/app/build.gradle b/Android/app/build.gradle index 75a8a2af0..fbc4ceffd 100644 --- a/Android/app/build.gradle +++ b/Android/app/build.gradle @@ -107,18 +107,22 @@ android { //dokit 扩展 -//dokitExt { -// //通用设置 -// comm { -// //地图经纬度开关 -// gpsSwitch true -// //网络开关 -// networkSwitch true -// //大图开关 -// bigImgSwitch true -// //webView js 抓包 -// webViewSwitch true -// } + +dokit { + gpsEnable true + bigImageEnable true + webView { + network true + dokitWeb true + vConsole true + } + gps { + didi true + baidu true + } +} + +//dokit { // // slowMethod { // //调用栈模式配置 diff --git a/Android/app/src/main/AndroidManifest.xml b/Android/app/src/main/AndroidManifest.xml index d26be9c8a..a9f41e967 100644 --- a/Android/app/src/main/AndroidManifest.xml +++ b/Android/app/src/main/AndroidManifest.xml @@ -9,8 +9,6 @@ - - diff --git a/Android/app/src/main/res/values-en-rUS/strings.xml b/Android/app/src/main/res/values-en-rUS/strings.xml index cd4e4860b..e8eb0a4e3 100644 --- a/Android/app/src/main/res/values-en-rUS/strings.xml +++ b/Android/app/src/main/res/values-en-rUS/strings.xml @@ -1,5 +1,5 @@ - DoKitDemo + DoKit BuildType Jump Other Activity MC diff --git a/Android/app/src/main/res/values-zh-rCN/strings.xml b/Android/app/src/main/res/values-zh-rCN/strings.xml index 5b7fd0140..1b07c94d7 100644 --- a/Android/app/src/main/res/values-zh-rCN/strings.xml +++ b/Android/app/src/main/res/values-zh-rCN/strings.xml @@ -1,5 +1,5 @@ - DoKitDemo + DoKit 当前编译环境 跳转其他Activity 一机多控 diff --git a/Android/app/src/main/res/values/strings.xml b/Android/app/src/main/res/values/strings.xml index de643544d..a63b20099 100644 --- a/Android/app/src/main/res/values/strings.xml +++ b/Android/app/src/main/res/values/strings.xml @@ -1,5 +1,5 @@ - DoKitDemo + DoKit demo < 当前编译环境 diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitExt.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitExt.kt index 741731104..69f58f014 100644 --- a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitExt.kt +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitExt.kt @@ -87,7 +87,7 @@ fun MethodNode.isEmptyMethod(): Boolean { fun MethodNode.isMainMethod(className: String): Boolean { if (this.name == "main" && this.desc == "([Ljava/lang/String;)V") { -// "====isMainMethod====$className ${this.name} ${this.desc} ${this.access}".println() + "====isMainMethod====$className ${this.name} ${this.desc} ${this.access}".println() return true } diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitExtUtil.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitExtUtil.kt index 97dbec8a0..2fea747c6 100644 --- a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitExtUtil.kt +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitExtUtil.kt @@ -1,9 +1,8 @@ package com.didichuxing.doraemonkit.plugin -import com.didichuxing.doraemonkit.plugin.extension.CommExt -import com.didichuxing.doraemonkit.plugin.extension.DoKitExt -import com.didichuxing.doraemonkit.plugin.extension.SlowMethodExt -import org.gradle.api.Project +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.extension.SlowMethodExtension +import com.didichuxing.doraemonkit.plugin.thirdlib.ThirdLibInfo /** * ================================================ @@ -16,20 +15,11 @@ import org.gradle.api.Project */ object DoKitExtUtil { - /** - * 是否包含dokitx-rpc模块 - */ - var HAS_DOKIT_RPC_MODULE = false - //private var mApplicationId: String = "" - - var HAS_DOKIT_TCP_HOOK_DJ = false - var DOKIT_GPS_MOCK_INCLUDE = false /** * 三方库版本信息 */ -// val THIRD_LIB_INFOS = mutableMapOf() val THIRD_LIB_INFOS = mutableListOf() @@ -64,7 +54,7 @@ object DoKitExtUtil { /** * 慢函数策略 默认为函数调用栈策略 */ - var SLOW_METHOD_STRATEGY = SlowMethodExt.STRATEGY_STACK + var SLOW_METHOD_STRATEGY = SlowMethodExtension.STRATEGY_STACK private val applications: MutableSet = mutableSetOf() @@ -73,9 +63,8 @@ object DoKitExtUtil { */ private var appPackageName: String = "" - var commExt = CommExt() - private set - val slowMethodExt = SlowMethodExt() + + val slowMethodExt = SlowMethodExtension() fun dokitPluginSwitchOpen(): Boolean { @@ -97,9 +86,8 @@ object DoKitExtUtil { * @param dokitEx dokitExtension * @param appExtension appExtension */ - fun init(dokitEx: DoKitExt) { + fun init(dokitEx: DoKitExtension) { //设置普通的配置 - commExt = dokitEx.comm //slowMethodExt.strategy = dokitEx.slowMethod.strategy //slowMethodExt.methodSwitch = dokitEx.slowMethod.methodSwitch /** diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitPlugin.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitPlugin.kt index cb32f8619..255355f63 100644 --- a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitPlugin.kt +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitPlugin.kt @@ -2,18 +2,56 @@ package com.didichuxing.doraemonkit.plugin import com.android.build.gradle.AppExtension import com.android.build.gradle.LibraryExtension -import com.didichuxing.doraemonkit.plugin.extension.DoKitExt -import com.didichuxing.doraemonkit.plugin.extension.SlowMethodExt +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.extension.SlowMethodExtension import com.didichuxing.doraemonkit.plugin.processor.DoKitPluginConfigProcessor import com.didichuxing.doraemonkit.plugin.stack_method.MethodStackNodeUtil +import com.didichuxing.doraemonkit.plugin.thirdlib.ThirdLibVariantProcessor import com.didichuxing.doraemonkit.plugin.transform.* import com.didiglobal.booster.gradle.GTE_V3_4 -import com.didiglobal.booster.gradle.dependencies import com.didiglobal.booster.gradle.getAndroid import com.didiglobal.booster.gradle.getProperty import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.api.artifacts.result.ResolvedArtifactResult + + +/** + * when 也可以用来取代 if-else if链。 + * 如果不提供参数,所有的分支条件都是简单的布尔表达式,而当一个分支的条件为真时则执行该分支: + */ + +/** + * 作用域函数:let、run、with、apply 以及 also + * 它们的唯一目的是在对象的上下文中执行代码块 + * 由于作用域函数本质上都非常相似,因此了解它们之间的区别很重要。每个作用域函数之间有两个主要区别: + * 引用上下文对象的方式: + * 作为 lambda 表达式的接收者(this)或者作为 lambda 表达式的参数(it) + * run、with 以及 apply 通过关键字 this 引用上下文对象 + * let 及 also 将上下文对象作为 lambda 表达式参数 + * + * 返回值: + * apply 及 also 返回上下文对象。 + * let、run 及 with 返回 lambda 表达式结果. + */ +/** + * 函数 对象引用 返回值 是否是扩展函数 + * let it Lambda 表达式结果 是 + * run this Lambda 表达式结果 是 + * run - Lambda 表达式结果 不是:调用无需上下文对象 + * with this Lambda 表达式结果 不是:把上下文对象当做参数 + * apply this 上下文对象 是 + * also it 上下文对象 是 + */ + +/** + *对一个非空(non-null)对象执行 lambda 表达式:let + *将表达式作为变量引入为局部作用域中:let + *对象配置:apply + *对象配置并且计算结果:run + *在需要表达式的地方运行语句:非扩展的 run + *附加效果:also + *一个对象的一组函数调用:with + */ /** * ================================================ @@ -23,58 +61,26 @@ import org.gradle.api.artifacts.result.ResolvedArtifactResult * 描 述: * 修订历史: * ================================================ + * + * DoKit 插件入口 */ + class DoKitPlugin : Plugin { override fun apply(project: Project) { //创建指定扩展 并将project 传入构造函数 - val doKitExt = project.extensions.create("dokitExt", DoKitExt::class.java) + val doKit = project.extensions.create("dokit", DoKitExtension::class.java) + "dokit plugin apply ${doKit}".println() project.gradle.addListener(DoKitTransformTaskExecutionListener(project)) - //println("project.plugins===>${project.plugins}") - /** - * when 也可以用来取代 if-else if链。 - * 如果不提供参数,所有的分支条件都是简单的布尔表达式,而当一个分支的条件为真时则执行该分支: - */ - - /** - * 作用域函数:let、run、with、apply 以及 also - * 它们的唯一目的是在对象的上下文中执行代码块 - * 由于作用域函数本质上都非常相似,因此了解它们之间的区别很重要。每个作用域函数之间有两个主要区别: - * 引用上下文对象的方式: - * 作为 lambda 表达式的接收者(this)或者作为 lambda 表达式的参数(it) - * run、with 以及 apply 通过关键字 this 引用上下文对象 - * let 及 also 将上下文对象作为 lambda 表达式参数 - * - * 返回值: - * apply 及 also 返回上下文对象。 - * let、run 及 with 返回 lambda 表达式结果. - */ - /** - * 函数 对象引用 返回值 是否是扩展函数 - * let it Lambda 表达式结果 是 - * run this Lambda 表达式结果 是 - * run - Lambda 表达式结果 不是:调用无需上下文对象 - * with this Lambda 表达式结果 不是:把上下文对象当做参数 - * apply this 上下文对象 是 - * also it 上下文对象 是 - */ - - /** - *对一个非空(non-null)对象执行 lambda 表达式:let - *将表达式作为变量引入为局部作用域中:let - *对象配置:apply - *对象配置并且计算结果:run - *在需要表达式的地方运行语句:非扩展的 run - *附加效果:also - *一个对象的一组函数调用:with - */ + when { project.plugins.hasPlugin("com.android.application") || project.plugins.hasPlugin("com.android.dynamic-feature") -> { if (!isReleaseTask(project)) { project.getAndroid().let { androidExt -> val pluginSwitch = project.getProperty("DOKIT_PLUGIN_SWITCH", true) val logSwitch = project.getProperty("DOKIT_LOG_SWITCH", false) + val slowMethodSwitch = project.getProperty("DOKIT_METHOD_SWITCH", false) val slowMethodStrategy = project.getProperty("DOKIT_METHOD_STRATEGY", 0) val methodStackLevel = project.getProperty("DOKIT_METHOD_STACK_LEVEL", 5) @@ -94,7 +100,7 @@ class DoKitPlugin : Plugin { if (DoKitExtUtil.DOKIT_PLUGIN_SWITCH) { //注册transform androidExt.registerTransform(commNewInstance(project)) - if (slowMethodSwitch && slowMethodStrategy == SlowMethodExt.STRATEGY_STACK) { + if (slowMethodSwitch && slowMethodStrategy == SlowMethodExtension.STRATEGY_STACK) { MethodStackNodeUtil.METHOD_STACK_KEYS.add(0, mutableSetOf()) val methodStackRange = 1 until methodStackLevel if (methodStackLevel > 1) { @@ -111,14 +117,6 @@ class DoKitPlugin : Plugin { } } - //项目评估完毕回调 -// project.afterEvaluate { project -> -// "===afterEvaluate===".println() -// androidExt.applicationVariants.forEach { variant -> -// DoKitPluginConfigProcessor(project).process(variant) -// } -// } - /** * 所有项目的build.gradle执行完毕 * wiki:https://juejin.im/post/6844903607679057934 @@ -127,6 +125,7 @@ class DoKitPlugin : Plugin { project.gradle.projectsEvaluated { "===projectsEvaluated===".println() androidExt.applicationVariants.forEach { variant -> + ThirdLibVariantProcessor(project).process(variant) DoKitPluginConfigProcessor(project).process(variant) } @@ -136,6 +135,7 @@ class DoKitPlugin : Plugin { //task依赖关系图建立完毕 project.gradle.taskGraph.whenReady { "===taskGraph.whenReady===".println() + "dokit config :: ${doKit}".println() } } @@ -152,6 +152,7 @@ class DoKitPlugin : Plugin { } project.afterEvaluate { libraryExt.libraryVariants.forEach { variant -> + ThirdLibVariantProcessor(project).process(variant) DoKitPluginConfigProcessor(project).process(variant) } } @@ -168,8 +169,8 @@ class DoKitPlugin : Plugin { } private fun commNewInstance(project: Project): DoKitBaseTransform = when { - GTE_V3_4 -> DoKitCommTransformV34(project) - else -> DoKitCommTransform(project) + GTE_V3_4 -> DoKitCommonTransformV34(project) + else -> DoKitCommonTransform(project) } private fun dependNewInstance(project: Project, index: Int): DoKitBaseTransform = when { @@ -178,4 +179,4 @@ class DoKitPlugin : Plugin { } -} \ No newline at end of file +} diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/ServiceLoader.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/ServiceLoader.kt deleted file mode 100644 index aeff63e8f..000000000 --- a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/ServiceLoader.kt +++ /dev/null @@ -1,76 +0,0 @@ -package com.didichuxing.doraemonkit.plugin - -import com.didiglobal.booster.task.spi.VariantProcessor -import com.didiglobal.booster.transform.Transformer -import org.gradle.api.Project -import java.net.URL -import java.nio.charset.StandardCharsets -import java.util.ServiceConfigurationError - -//internal interface ServiceLoader { -// fun load(vararg args: Any): List -//} - -//internal class ServiceLoaderFactory(private val classLoader: ClassLoader, private val service: Class) { -// -// fun newServiceLoader(vararg types: Class<*>) = object : ServiceLoader { -// -// @Suppress("UNCHECKED_CAST") -// override fun load(vararg args: Any) = classLoader.getResources("META-INF/services/${service.name}")?.asSequence()?.map(::parse)?.flatten()?.toSet()?.map { provider -> -// try { -// val providerClass = Class.forName(provider, false, classLoader) -// if (!service.isAssignableFrom(providerClass)) { -// throw ServiceConfigurationError("Provider $provider not a subtype") -// } -// -// try { -// providerClass.getConstructor(*types).newInstance(*args) as T -// } catch (e: NoSuchMethodException) { -// providerClass.newInstance() as T -// } -// } catch (e: ClassNotFoundException) { -// throw ServiceConfigurationError("Provider $provider not found") -// } -// } ?: emptyList() -// -// } -// -//} -// -//internal inline fun newServiceLoader(classLoader: ClassLoader, vararg types: Class<*>) = ServiceLoaderFactory(classLoader, T::class.java).newServiceLoader(*types) - -/** - * Load [Transformer]s with the specified [classLoader] - */ -//@Throws(ServiceConfigurationError::class) -//internal fun loadTransformers(classLoader: ClassLoader) = newServiceLoader(classLoader, ClassLoader::class.java).load(classLoader) - -/** - * Load [VariantProcessor]s with the specified [classLoader] - */ -//@Throws(ServiceConfigurationError::class) -//internal fun loadVariantProcessors(project: Project) = newServiceLoader(project.buildscript.classLoader, Project::class.java).load(project) - -@Throws(ServiceConfigurationError::class) -private fun parse(u: URL) = try { - u.openStream().bufferedReader(StandardCharsets.UTF_8).readLines().filter { - it.isNotEmpty() && it.isNotBlank() && !it.startsWith('#') - }.map(String::trim).filter(::isJavaClassName) -} catch (e: Throwable) { - emptyList() -} - -private fun isJavaClassName(text: String): Boolean { - if (!Character.isJavaIdentifierStart(text[0])) { - throw ServiceConfigurationError("Illegal provider-class name: $text") - } - - for (i in 1 until text.length) { - val cp = text.codePointAt(i) - if (!Character.isJavaIdentifierPart(cp) && cp != '.'.toInt()) { - throw ServiceConfigurationError("Illegal provider-class name: $text") - } - } - - return true -} \ No newline at end of file diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/AbsClassTransformer.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/AbsClassTransformer.kt deleted file mode 100644 index 5c909b387..000000000 --- a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/AbsClassTransformer.kt +++ /dev/null @@ -1,40 +0,0 @@ -package com.didichuxing.doraemonkit.plugin.classtransformer - -import com.didichuxing.doraemonkit.plugin.DoKitExtUtil -import com.didichuxing.doraemonkit.plugin.isRelease -import com.didichuxing.doraemonkit.plugin.println -import com.didiglobal.booster.transform.TransformContext -import com.didiglobal.booster.transform.asm.ClassTransformer -import com.didiglobal.booster.transform.asm.className -import org.objectweb.asm.tree.ClassNode - -/** - * ================================================ - * 作 者:jint(金台) - * 版 本:1.0 - * 创建日期:2021/5/12-18:06 - * 描 述: - * 修订历史: - * ================================================ - */ - -open class AbsClassTransformer : ClassTransformer { - - - fun onCommInterceptor(context: TransformContext, klass: ClassNode): Boolean { -// "===onCommInterceptor--->$this====${klass.className}===".println() - if (context.isRelease()) { - return true - } - - if (!DoKitExtUtil.dokitPluginSwitchOpen()) { - return true - } - //过滤kotlin module-info - if (klass.className == "module-info") { - return true - } - - return false - } -} \ No newline at end of file diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/CommClassTransformer.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/CommClassTransformer.kt deleted file mode 100644 index 75dcfbecb..000000000 --- a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/CommClassTransformer.kt +++ /dev/null @@ -1,1230 +0,0 @@ -package com.didichuxing.doraemonkit.plugin.classtransformer - -import com.didichuxing.doraemonkit.plugin.* -import com.didichuxing.doraemonkit.plugin.extension.SlowMethodExt -import com.didiglobal.booster.annotations.Priority -import com.didiglobal.booster.kotlinx.asIterable -import com.didiglobal.booster.transform.TransformContext -import com.didiglobal.booster.transform.asm.ClassTransformer -import com.didiglobal.booster.transform.asm.className -import com.google.auto.service.AutoService -import org.objectweb.asm.Label -import org.objectweb.asm.Opcodes.* -import org.objectweb.asm.tree.* - -/** - * ================================================ - * 作 者:jint(金台) - * 版 本:1.0 - * 创建日期:2020/5/14-18:07 - * 描 述:wiki:https://juejin.im/post/5e8d87c4f265da47ad218e6b - * 修订历史: - * ================================================ - */ -//@Priority(0) -//@AutoService(ClassTransformer::class) -class CommClassTransformer : AbsClassTransformer() { - - - private val SHADOW_URL = - "com/didichuxing/doraemonkit/aop/urlconnection/HttpUrlConnectionProxyUtil" - private val DESC = "(Ljava/net/URLConnection;)Ljava/net/URLConnection;" - - - /** - * 转化 - */ - override fun transform(context: TransformContext, klass: ClassNode): ClassNode { - - if (onCommInterceptor(context, klass)) { - return klass - } - - - val className = klass.className - val superName = klass.formatSuperName - -// if (className.contains("didihttp")) { -// "${context.projectDir.lastPath()}==className===>$className".println() -// } - - //查找DoraemonKitReal&pluginConfig方法并插入指定字节码 - if (className == "com.didichuxing.doraemonkit.DoKitReal") { - //插件配置 - klass.methods?.find { - it.name == "pluginConfig" - }.let { methodNode -> - "${context.projectDir.lastPath()}->insert map to the DoKitReal pluginConfig succeed".println() - methodNode?.instructions?.insert(createPluginConfigInsnList()) - } - //三方库信息注入 - klass.methods?.find { - it.name == "initThirdLibraryInfo" - }.let { methodNode -> - "${context.projectDir.lastPath()}->insert map to the DoKitReal initThirdLibraryInfo succeed".println() - methodNode?.instructions?.insert(createThirdLibInfoInsnList()) - } - } - - //gps字节码操作 - if (DoKitExtUtil.commExt.gpsSwitch && DoKitExtUtil.DOKIT_GPS_MOCK_INCLUDE) { - //系统 gpsStatus hook - klass.methods.forEach { method -> - method.instructions?.iterator()?.asIterable() - ?.filterIsInstance(MethodInsnNode::class.java)?.filter { - it.opcode == INVOKEVIRTUAL && - it.owner == "android/location/LocationManager" && - it.name == "getGpsStatus" && - it.desc == "(Landroid/location/GpsStatus;)Landroid/location/GpsStatus;" - }?.forEach { - "${context.projectDir.lastPath()}->hook LocationManager#getGpsStatus method succeed in : ${className}_${method.name}_${method.desc}".println() - method.instructions.insert( - it, - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/gps_mock/location/GpsStatusUtil", - "wrap", - "(Landroid/location/GpsStatus;)Landroid/location/GpsStatus;", - false - ) - ) - } - } - - //插入高德地图定位相关字节码 - if (className == "com.amap.api.location.AMapLocationClient") { - //设置监听器 - klass.methods?.find { - it.name == "setLocationListener" - }.let { methodNode -> - "${context.projectDir.lastPath()}->hook amap map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() - methodNode?.instructions?.insert(createAmapLocationInsnList()) - } - - //反注册监听器 - klass.methods?.find { - it.name == "unRegisterLocationListener" - }.let { methodNode -> - "${context.projectDir.lastPath()}->hook amap map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() - methodNode?.instructions?.insert( - createAmapLocationUnRegisterInsnList() - ) - } - - //代理getLastKnownLocation - klass.methods?.find { - it.name == "getLastKnownLocation" - }.let { methodNode -> - "${context.projectDir.lastPath()}->hook AMapLocationClient getLastKnownLocation succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() - methodNode?.instructions?.insert(createAMapClientLastKnownLocation()) - } - - } - //插入高德 地图定位相关字节码 -// if (className == "com.amap.api.maps.AMap") { -// //设置LocationSource代理 -// klass.methods?.find { -// it.name == "setLocationSource" -// }.let { methodNode -> -// "${context.projectDir.lastPath()}->hook amap map LocationSource succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() -// methodNode?.instructions?.insert(createAmapLocationSourceInsnList()) -// } -// } - - //插入高德地图导航相关字节码 - if (className == "com.amap.api.navi.AMapNavi") { - //设置监听器 - klass.methods?.find { - it.name == "addAMapNaviListener" - }.let { methodNode -> - "${context.projectDir.lastPath()}->hook amap map navi succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() - methodNode?.instructions?.insert(createAmapNaviInsnList()) - } -// -// //反注册监听器 - klass.methods?.find { - it.name == "removeAMapNaviListener" - }.let { methodNode -> - "${context.projectDir.lastPath()}->hook amap map navi succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() - methodNode?.instructions?.insert( - createAmapNaviUnRegisterInsnList() - ) - } - } - - - //插入腾讯地图相关字节码 - if (className == "com.tencent.map.geolocation.TencentLocationManager") { - //持续定位和单次定位 - klass.methods?.filter { - it.name == "requestSingleFreshLocation" || it.name == "requestLocationUpdates" - }?.forEach { methodNode -> - "${context.projectDir.lastPath()}->hook tencent map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() - methodNode?.instructions?.insert(createTencentLocationInsnList()) - } - - - //反注册监听器 - klass.methods?.find { - it.name == "removeUpdates" - }.let { methodNode -> - "${context.projectDir.lastPath()}->hook tencent map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() - methodNode?.instructions?.insert( - createTencentLocationUnRegisterInsnList() - ) - } - } - - //插入百度地图相关字节码 - if (className == "com.baidu.location.LocationClient") { - //拦截注册监听器 - klass.methods?.filter { - it.name == "registerLocationListener" - && (it.desc == "(Lcom/baidu/location/BDLocationListener;)V" || it.desc == "(Lcom/baidu/location/BDAbstractLocationListener;)V") - }?.forEach { methodNode -> - "${context.projectDir.lastPath()}->hook baidu map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() - if (methodNode.desc == "(Lcom/baidu/location/BDLocationListener;)V") { - methodNode?.instructions?.insert(createBDLocationListenerInsnList()) - } else if (methodNode.desc == "(Lcom/baidu/location/BDAbstractLocationListener;)V") { - methodNode?.instructions?.insert(createBDLocationAbsListenerInsnList()) - } - } - - - //反注册监听器 - klass.methods?.find { - it.name == "unRegisterLocationListener" && it.desc == "(Lcom/baidu/location/BDLocationListener;)V" - }.let { methodNode -> - "${context.projectDir.lastPath()}->hook baidu map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() - methodNode?.instructions?.insert( - createBDLocationUnRegisterInsnList() - ) - } - - - //反注册监听器 - klass.methods?.find { - it.name == "unRegisterLocationListener" && it.desc == "(Lcom/baidu/location/BDAbstractLocationListener;)V" - }.let { methodNode -> - "${context.projectDir.lastPath()}->hook baidu map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() - methodNode?.instructions?.insert( - createBDAbsLocationUnRegisterInsnList() - ) - } - } - } - - - //网络 OkHttp&didi platform aop - if (DoKitExtUtil.commExt.networkSwitch) { - //hook OkhttpClient - if (className == "okhttp3.OkHttpClient") { - klass.methods?.find { - it.name == "" && it.desc != "()V" - }.let { - "${context.projectDir.lastPath()}->hook OkhttpClient succeed: ${className}_${it?.name}_${it?.desc}".println() - it?.instructions - ?.iterator() - ?.asIterable() - ?.filterIsInstance(FieldInsnNode::class.java) - ?.filter { fieldInsnNode -> - fieldInsnNode.opcode == PUTFIELD - && fieldInsnNode.owner == "okhttp3/OkHttpClient" - && fieldInsnNode.name == "networkInterceptors" - && fieldInsnNode.desc == "Ljava/util/List;" - }?.forEach { fieldInsnNode -> - it.instructions.insert(fieldInsnNode, createOkHttpClientInsnList()) - } - } - } - - //didi platform 判断是否引入了dokit-rpc模块 - if (className == "didihttp.DidiHttpClient" && DoKitExtUtil.commExt.didinetSwitch && DoKitExtUtil.HAS_DOKIT_RPC_MODULE) { - klass.methods?.find { - it.name == "" && it.desc != "()V" - }.let { - "${context.projectDir.lastPath()}->hook DidiHttpClient succeed: ${className}_${it?.name}_${it?.desc}".println() - it?.instructions - ?.iterator() - ?.asIterable() - ?.filterIsInstance(FieldInsnNode::class.java) - ?.filter { fieldInsnNode -> - fieldInsnNode.opcode == PUTFIELD - && fieldInsnNode.owner == "didihttp/DidiHttpClient" - && fieldInsnNode.name == "networkInterceptors" - && fieldInsnNode.desc == "Ljava/util/List;" - } - ?.forEach { fieldInsnNode -> - it.instructions.insert( - fieldInsnNode, - createDidiHttpClientInsnList() - ) - } - } - } - - - //hook tcp 支持tcp消息hook - if (className == "com.didi.daijia.tcp.message.MessageSender") { - klass.methods?.find { - it.name == "sendMessage" && it.desc == "(Ljava/lang/String;)Z" - }.let { - "${context.projectDir.lastPath()}->hook tcp MessageSender succeed: ${className}_${it?.name}_${it?.desc}".println() - val first = it?.instructions?.first - if (first != null) { - it.instructions.insert(first, createMessageSenderHookInsnList()) - } - } - } - if (className == "com.didi.daijia.tcp.message.MessageReceiver") { - klass.methods?.find { - it.name == "channelRead" && it.desc == "(Ljava/lang/Object;)V" - }.let { - "${context.projectDir.lastPath()}->hook tcp MessageReceiver succeed: ${className}_${it?.name}_${it?.desc}".println() - val first = it?.instructions?.first - if (first != null) { - it.instructions.insert(first, createMessageReceiverHookInsnList()) - } - } - } - - - //webView 字节码操作 - if (DoKitExtUtil.commExt.webViewSwitch) { - //普通的webview - klass.methods.forEach { method -> - method.instructions?.iterator()?.asIterable() - ?.filterIsInstance(MethodInsnNode::class.java)?.filter { - if ("loadUrl".equals(it.name)) { - "hook loadUrl() all ${className} ^${superName}^${it.owner} :: ${it.name} , ${it.desc} ,${it.opcode}".println() - } - (it.opcode == INVOKEVIRTUAL || it.opcode == INVOKESPECIAL) && - it.name == "loadUrl" && - (it.desc == "(Ljava/lang/String;)V" || it.desc == "(Ljava/lang/String;Ljava/util/Map;)V") && - isWebViewOwnerNameMatched(it.owner) - }?.forEach { - "${context.projectDir.lastPath()}->hook WebView#loadurl method succeed in : ${className}_${method.name}_${method.desc} | ${it.owner}".println() - if (it.desc == "(Ljava/lang/String;)V") { - method.instructions.insertBefore( - it, - createWebViewInsnList() - ) - } else { - val size = method.localVariables.size - val insn = with(InsnList()) { - add(VarInsnNode(ASTORE, size + 1)) - add(VarInsnNode(ASTORE, size)) - add(InsnNode(DUP)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/aop/WebViewHook", - "inject", - "(Ljava/lang/Object;)V", - false - ) - ) - add(VarInsnNode(ALOAD, size)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/aop/WebViewHook", - "getSafeUrl", - "(Ljava/lang/String;)Ljava/lang/String;", - false - ) - ) - add(VarInsnNode(ALOAD, size + 1)) - this - } - method.instructions.insertBefore(it, insn) - } - - } - } - } - - // url connection - klass.methods.forEach { method -> - method.instructions?.iterator()?.asIterable() - ?.filterIsInstance(MethodInsnNode::class.java)?.filter { - it.opcode == INVOKEVIRTUAL && - it.owner == "java/net/URL" && - it.name == "openConnection" && - it.desc == "()Ljava/net/URLConnection;" - }?.forEach { - "${context.projectDir.lastPath()}->hook URL#openConnection method succeed in : ${className}_${method.name}_${method.desc}".println() - method.instructions.insert( - it, - MethodInsnNode(INVOKESTATIC, SHADOW_URL, "proxy", DESC, false) - ) - } - } - - } - - - //hook Androidx的ComponentActivity - if (className != "com.didichuxing.doraemonkit.aop.mc.DoKitProxyActivity" && superName == "android.app.Activity") { - createComponentActivitySuperActivityImpl(klass) - } - - - //hook androidx的AppCompatDelegateImpl -// if (className == "androidx.appcompat.app.AppCompatDelegate") { -// klass.methods?.filter { -// it.name == "create" -// && (it.desc == "(Landroid/app/Activity;Landroidx/appcompat/app/AppCompatCallback;)Landroidx/appcompat/app/AppCompatDelegate;" -// || it.desc == "(Landroid/app/Dialog;Landroidx/appcompat/app/AppCompatCallback;)Landroidx/appcompat/app/AppCompatDelegate;" -// || it.desc == "(Landroid/content/Context;Landroid/view/Window;Landroidx/appcompat/app/AppCompatCallback;)Landroidx/appcompat/app/AppCompatDelegate;" -// || it.desc == "(Landroid/content/Context;Landroid/app/Activity;Landroidx/appcompat/app/AppCompatCallback;)Landroidx/appcompat/app/AppCompatDelegate;") -// }?.asIterable() -// ?.forEach { methodNode -> -// //操作方法 -// val typeInsnNodes = methodNode.instructions -// ?.iterator() -// ?.asIterable() -// ?.filterIsInstance(TypeInsnNode::class.java) -// //操作New指令 -// typeInsnNodes?.filter { -// it.opcode == NEW && it.desc == "androidx/appcompat/app/AppCompatDelegateImpl" -// }?.forEach { -// "${context.projectDir.lastPath()}->hook ${klass.name}-${methodNode.name}-${it.opcode}-${it.desc} succeed".println() -// methodNode.instructions.insertBefore( -// it, -// createNewDoKitAppCompatDelegateImplInsnList() -// ) -// } -// -// //操作方法 -// val methodInsnNodes = methodNode.instructions -// ?.iterator() -// ?.asIterable() -// ?.filterIsInstance(MethodInsnNode::class.java) -// -// methodInsnNodes?.filter { -// //"${context.projectDir.lastPath()}->hook AppCompatDelegate create matched ${it.opcode} ${it.ownerClassName} ${it.name}".println() -// it.opcode == INVOKESPECIAL -// && it.ownerClassName == "androidx.appcompat.app.AppCompatDelegateImpl" -// && it.name == "" -// }?.forEach { -// //"${context.projectDir.lastPath()}->hook AppCompatDelegate create method succeed".println() -// "${context.projectDir.lastPath()}->hook ${klass.name}-${methodNode.name}-${it.owner}-${it.name}-${it.desc} succeed".println() -// methodNode.instructions.insert( -// it, -// MethodInsnNode( -// INVOKESPECIAL, -// "androidx/appcompat/app/DoKitAppCompatDelegateImpl", -// "", -// "(Landroidx/appcompat/app/AppCompatDelegate;)V", -// false -// ) -// ) -// } -// } -// } - - //hook 所有的view的事件 -// klass.methods?.forEach { methodNode -> -// if (methodNode.name == "onClick" && methodNode.desc == "(Landroid/view/View;)V") { -// val insnList = with(InsnList()) { -// add(VarInsnNode(ALOAD, 1)) -// add( -// MethodInsnNode( -// INVOKESTATIC, -// "com/didichuxing/doraemonkit/aop/mc/DoKitListenerHelper", -// "hookViewClickListener", -// "(Landroid/view/View;)V", -// false -// ) -// ) -// this -// } -// methodNode.instructions.insert(insnList) -// } -// } - - - // hook 所有的View -// if (className != "com.didichuxing.doraemonkit.aop.mc.DoKitProxyView" && superName == "android.view.View") { -// createViewImpl(klass) -// } - - // hook 所有的ViewGroup -// if (className != "com.didichuxing.doraemonkit.aop.mc.DoKitProxyViewGroup" && superName == "android.view.ViewGroup") { -// createViewGroupImpl(klass) -// } - -// if (className == "androidx.appcompat.app.AppCompatDelegateImpl") { -// //插件配置 -// klass.methods?.find { -// it.name == "onCreateView" && it.desc == "(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;" -// }.let { method -> -// method?.instructions?.iterator()?.asIterable() -// ?.filterIsInstance(MethodInsnNode::class.java)?.filter { -// it.opcode == INVOKEVIRTUAL && -// it.owner == "androidx/appcompat/app/AppCompatDelegateImpl" && -// it.name == "createView" && -// it.desc == "(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;" -// }?.forEach { -// "${context.projectDir.lastPath()}->hook AppCompatDelegateImpl onCreateView method succeed".println() -// method.instructions.insert( -// it, -// MethodInsnNode( -// INVOKESTATIC, -// "com/didichuxing/doraemonkit/aop/mc/AppCompatDelegateImplProxy", -// "onCreateView", -// "(Landroid/view/View;)Landroid/view/View;", -// false -// ) -// ) -// } -// } -// } - - return klass - } - - private fun isWebViewOwnerNameMatched(ownerName: String): Boolean { - return ownerName == "android/webkit/WebView" || - ownerName == "com/tencent/smtt/sdk/WebView" || - ownerName.contentEquals("WebView") || - ownerName == DoKitExtUtil.WEBVIEW_CLASS_NAME - } - - - /** - * 创建pluginConfig代码指令 - */ - private fun createPluginConfigInsnList(): InsnList { - //val insnList = InsnList() - return with(InsnList()) { - //new HashMap - add(TypeInsnNode(NEW, "java/util/HashMap")) - add(InsnNode(DUP)) - add(MethodInsnNode(INVOKESPECIAL, "java/util/HashMap", "", "()V", false)) - //保存变量 - add(VarInsnNode(ASTORE, 0)) - //获取第一个变量 - //put("dokitPluginSwitch",true) - add(VarInsnNode(ALOAD, 0)) - add(LdcInsnNode("dokitPluginSwitch")) - add(InsnNode(if (DoKitExtUtil.dokitPluginSwitchOpen()) ICONST_1 else ICONST_0)) - add( - MethodInsnNode( - INVOKESTATIC, - "java/lang/Boolean", - "valueOf", - "(Z)Ljava/lang/Boolean;", - false - ) - ) - add( - MethodInsnNode( - INVOKEINTERFACE, - "java/util/Map", - "put", - "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", - true - ) - ) - add(InsnNode(POP)) - - //put("gpsSwitch",true) - add(VarInsnNode(ALOAD, 0)) - add(LdcInsnNode("gpsSwitch")) - add(InsnNode(if (DoKitExtUtil.commExt.gpsSwitch) ICONST_1 else ICONST_0)) - add( - MethodInsnNode( - INVOKESTATIC, - "java/lang/Boolean", - "valueOf", - "(Z)Ljava/lang/Boolean;", - false - ) - ) - add( - MethodInsnNode( - INVOKEINTERFACE, - "java/util/Map", - "put", - "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", - true - ) - ) - add(InsnNode(POP)) - - //put("networkSwitch",true) - add(VarInsnNode(ALOAD, 0)) - add(LdcInsnNode("networkSwitch")) - add(InsnNode(if (DoKitExtUtil.commExt.networkSwitch) ICONST_1 else ICONST_0)) - add( - MethodInsnNode( - INVOKESTATIC, - "java/lang/Boolean", - "valueOf", - "(Z)Ljava/lang/Boolean;", - false - ) - ) - add( - MethodInsnNode( - INVOKEINTERFACE, - "java/util/Map", - "put", - "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", - true - ) - ) - add(InsnNode(POP)) - - //put("bigImgSwitch",true) - add(VarInsnNode(ALOAD, 0)) - add(LdcInsnNode("bigImgSwitch")) - add(InsnNode(if (DoKitExtUtil.commExt.bigImgSwitch) ICONST_1 else ICONST_0)) - add( - MethodInsnNode( - INVOKESTATIC, - "java/lang/Boolean", - "valueOf", - "(Z)Ljava/lang/Boolean;", - false - ) - ) - add( - MethodInsnNode( - INVOKEINTERFACE, - "java/util/Map", - "put", - "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", - true - ) - ) - add(InsnNode(POP)) - - //put("methodSwitch",true) - add(VarInsnNode(ALOAD, 0)) - add(LdcInsnNode("methodSwitch")) - add(InsnNode(if (DoKitExtUtil.dokitSlowMethodSwitchOpen()) ICONST_1 else ICONST_0)) - add( - MethodInsnNode( - INVOKESTATIC, - "java/lang/Boolean", - "valueOf", - "(Z)Ljava/lang/Boolean;", - false - ) - ) - add( - MethodInsnNode( - INVOKEINTERFACE, - "java/util/Map", - "put", - "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", - true - ) - ) - add(InsnNode(POP)) - - - //put("methodStrategy",0) - add(VarInsnNode(ALOAD, 0)) - add(LdcInsnNode("methodStrategy")) - add(InsnNode(if (DoKitExtUtil.SLOW_METHOD_STRATEGY == SlowMethodExt.STRATEGY_STACK) ICONST_0 else ICONST_1)) - add( - MethodInsnNode( - INVOKESTATIC, - "java/lang/Integer", - "valueOf", - "(I)Ljava/lang/Integer;", - false - ) - ) - add( - MethodInsnNode( - INVOKEINTERFACE, - "java/util/Map", - "put", - "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", - true - ) - ) - add(InsnNode(POP)) - - //将HashMap注入到DokitPluginConfig中 - add(VarInsnNode(ALOAD, 0)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/aop/DokitPluginConfig", - "inject", - "(Ljava/util/Map;)V", - false - ) - ) - - this - } - - //return insnList - - } - - - /** - * 创建pluginConfig代码指令 - */ - private fun createThirdLibInfoInsnList(): InsnList { - //val insnList = InsnList() - return with(InsnList()) { - //new HashMap - add(TypeInsnNode(NEW, "java/util/HashMap")) - add(InsnNode(DUP)) - add(MethodInsnNode(INVOKESPECIAL, "java/util/HashMap", "", "()V", false)) - //保存变量 - add(VarInsnNode(ASTORE, 0)) - DoKitExtUtil.THIRD_LIB_INFOS.forEach { thirdLibInfo -> - add(VarInsnNode(ALOAD, 0)) - add(LdcInsnNode(thirdLibInfo.variant)) - add(LdcInsnNode(thirdLibInfo.fileSize.toString())) - - add( - MethodInsnNode( - INVOKEINTERFACE, - "java/util/Map", - "put", - "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", - false - ) - ) - add(InsnNode(POP)) - } - - - //将HashMap注入到DokitPluginConfig中 - add(VarInsnNode(ALOAD, 0)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/aop/DokitThirdLibInfo", - "inject", - "(Ljava/util/Map;)V", - false - ) - ) - - this - } - - //return insnList - - } - - - /** - * 创建Amap地图代码指令 - */ - private fun createAmapLocationInsnList(): InsnList { - return with(InsnList()) { - //在AMapLocationClient的 setLocationListener 方法之中插入自定义代理回调类 - add(TypeInsnNode(NEW, "com/didichuxing/doraemonkit/gps_mock/map/AMapLocationListenerProxy")) - add(InsnNode(DUP)) - //访问第一个参数 - add(VarInsnNode(ALOAD, 1)) - add( - MethodInsnNode( - INVOKESPECIAL, - "com/didichuxing/doraemonkit/gps_mock/map/AMapLocationListenerProxy", - "", - "(Lcom/amap/api/location/AMapLocationListener;)V", - false - ) - ) - //对第一个参数进行重新赋值 - add(VarInsnNode(ASTORE, 1)) - this - } - - } - - /** - * 创建Amap地图导航代码指令 - */ - private fun createAmapNaviInsnList(): InsnList { - return with(InsnList()) { - //在AMapNavi的addAMapNaviListener方法之中插入自定义代理回调类 - add(TypeInsnNode(NEW, "com/didichuxing/doraemonkit/gps_mock/map/AMapNaviListenerProxy")) - add(InsnNode(DUP)) - //访问第一个参数 - add(VarInsnNode(ALOAD, 1)) - add( - MethodInsnNode( - INVOKESPECIAL, - "com/didichuxing/doraemonkit/gps_mock/map/AMapNaviListenerProxy", - "", - "(Lcom/amap/api/navi/AMapNaviListener;)V", - false - ) - ) - //对第一个参数进行重新赋值 - add(VarInsnNode(ASTORE, 1)) - this - } - - } - - - /** - * 创建Amap LocationSource代码指令 - */ - private fun createAmapLocationSourceInsnList(): InsnList { - return with(InsnList()) { - //在AMapNavi的addAMapNaviListener方法之中插入自定义代理回调类 - add(TypeInsnNode(NEW, "com/didichuxing/doraemonkit/gps_mock/map/AMapLocationSourceProxy")) - add(InsnNode(DUP)) - //访问第一个参数 - add(VarInsnNode(ALOAD, 1)) - add( - MethodInsnNode( - INVOKESPECIAL, - "com/didichuxing/doraemonkit/gps_mock/map/AMapLocationSourceProxy", - "", - "(Lcom/amap/api/maps/LocationSource;)V", - false - ) - ) - //对第一个参数进行重新赋值 - add(VarInsnNode(ASTORE, 1)) - this - } - - } - - /** - * 创建AMapLocationClient#LastKnownLocation 字节码替换 - */ - private fun createAMapClientLastKnownLocation(): InsnList { - return with(InsnList()) { - add(VarInsnNode(ALOAD, 0)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/gps_mock/map/AMapLocationClientProxy", - "getLastKnownLocation", - "(Lcom/amap/api/location/AMapLocationClient;)Lcom/amap/api/location/AMapLocation;", - false - ) - ) -// add(VarInsnNode(ASTORE, 1)) -// add(VarInsnNode(ALOAD, 1)) - add(InsnNode(ARETURN)) - this - } - - } - - /** - * 创建Amap地图UnRegister代码指令 - */ - private fun createAmapLocationUnRegisterInsnList(): InsnList { - return with(InsnList()) { - //访问第一个参数 - add(VarInsnNode(ALOAD, 1)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/gps_mock/map/ThirdMapLocationListenerUtil", - "unRegisterAmapLocationListener", - "(Lcom/amap/api/location/AMapLocationListener;)Lcom/didichuxing/doraemonkit/gps_mock/map/AMapLocationListenerProxy;", - false - ) - ) - add(VarInsnNode(ASTORE, 1)) - this - } - } - - /** - * 创建Amap地图 Navi UnRegister代码指令 - */ - private fun createAmapNaviUnRegisterInsnList(): InsnList { - return with(InsnList()) { - //访问第一个参数 - add(VarInsnNode(ALOAD, 1)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/gps_mock/map/ThirdMapLocationListenerUtil", - "unRegisterAmapNaviListener", - "(Lcom/amap/api/navi/AMapNaviListener;)Lcom/didichuxing/doraemonkit/gps_mock/map/AMapNaviListenerProxy;", - false - ) - ) - add(VarInsnNode(ASTORE, 1)) - this - } - - } - - - /** - * 创建tencent地图代码指令 - */ - private fun createTencentLocationInsnList(): InsnList { - return with(InsnList()) { - //在AMapLocationClient的setLocationListener方法之中插入自定义代理回调类 - add( - TypeInsnNode( - NEW, - "com/didichuxing/doraemonkit/gps_mock/map/TencentLocationListenerProxy" - ) - ) - add(InsnNode(DUP)) - //访问第一个参数 - add(VarInsnNode(ALOAD, 2)) - add( - MethodInsnNode( - INVOKESPECIAL, - "com/didichuxing/doraemonkit/gps_mock/map/TencentLocationListenerProxy", - "", - "(Lcom/tencent/map/geolocation/TencentLocationListener;)V", - false - ) - ) - //对第二个参数进行重新赋值 - add(VarInsnNode(ASTORE, 2)) - - this - } - - } - - - /** - * 创建Tencent地图UnRegister代码指令 - */ - private fun createTencentLocationUnRegisterInsnList(): InsnList { - return with(InsnList()) { - //访问第一个参数 - add(VarInsnNode(ALOAD, 1)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/gps_mock/map/ThirdMapLocationListenerUtil", - "unRegisterTencentLocationListener", - "(Lcom/tencent/map/geolocation/TencentLocationListener;)Lcom/didichuxing/doraemonkit/gps_mock/map/TencentLocationListenerProxy;", - false - ) - ) - add(VarInsnNode(ASTORE, 1)) - this - } - - } - - - /** - * 创建百度地图代码指令 - */ - private fun createBDLocationListenerInsnList(): InsnList { - return with(InsnList()) { - //在LocationClient的registerLocationListener方法之中插入自定义代理回调类 - add(TypeInsnNode(NEW, "com/didichuxing/doraemonkit/gps_mock/map/BDLocationListenerProxy")) - add(InsnNode(DUP)) - //访问第一个参数 - add(VarInsnNode(ALOAD, 1)) - add( - MethodInsnNode( - INVOKESPECIAL, - "com/didichuxing/doraemonkit/gps_mock/map/BDLocationListenerProxy", - "", - "(Lcom/baidu/location/BDLocationListener;)V", - false - ) - ) - //对第一个参数进行重新赋值 - add(VarInsnNode(ASTORE, 1)) - - this - } - - } - - /** - * 创建百度地图代码指令 - */ - private fun createBDLocationAbsListenerInsnList(): InsnList { - return with(InsnList()) { - //在LocationClient的registerLocationListener方法之中插入自定义代理回调类 - add(TypeInsnNode(NEW, "com/didichuxing/doraemonkit/gps_mock/map/BDAbsLocationListenerProxy")) - add(InsnNode(DUP)) - //访问第一个参数 - add(VarInsnNode(ALOAD, 1)) - add( - MethodInsnNode( - INVOKESPECIAL, - "com/didichuxing/doraemonkit/gps_mock/map/BDAbsLocationListenerProxy", - "", - "(Lcom/baidu/location/BDAbstractLocationListener;)V", - false - ) - ) - //对第一个参数进行重新赋值 - add(VarInsnNode(ASTORE, 1)) - this - } - } - - - /** - * 创建百度地图UnRegister代码指令 - */ - private fun createBDLocationUnRegisterInsnList(): InsnList { - return with(InsnList()) { - //访问第一个参数 - add(VarInsnNode(ALOAD, 1)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/gps_mock/map/ThirdMapLocationListenerUtil", - "unRegisterBDLocationListener", - "(Lcom/baidu/location/BDLocationListener;)Lcom/didichuxing/doraemonkit/gps_mock/map/BDLocationListenerProxy;", - false - ) - ) - add(VarInsnNode(ASTORE, 1)) - this - } - - } - - /** - * 创建百度地图UnRegister代码指令 - */ - private fun createBDAbsLocationUnRegisterInsnList(): InsnList { - return with(InsnList()) { - //访问第一个参数 - add(VarInsnNode(ALOAD, 1)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/gps_mock/map/ThirdMapLocationListenerUtil", - "unRegisterBDLocationListener", - "(Lcom/baidu/location/BDAbstractLocationListener;)Lcom/didichuxing/doraemonkit/gps_mock/map/BDAbsLocationListenerProxy;", - false - ) - ) - //对第一个参数进行重新赋值 - add(VarInsnNode(ASTORE, 1)) - this - } - - } - - /** - * 创建百度地图代码指令 - */ - private fun createBaiduLocationInsnList(): InsnList { - return with(InsnList()) { - //在AMapLocationClient的setLocationListener方法之中插入自定义代理回调类 - add(VarInsnNode(ALOAD, 1)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/gps_mock/map/BDLocationUtil", - "proxy", - "(Lcom/baidu/location/BDLocation;)Lcom/baidu/location/BDLocation;", - false - ) - ) - //对第一个参数进行重新赋值 - add(VarInsnNode(ASTORE, 1)) - this - } - - } - - /** - * 创建OkhttpClient一个数构造函数指令 - */ - private fun createOkHttpClientInsnList(): InsnList { - return with(InsnList()) { - //插入application 拦截器 - add(VarInsnNode(ALOAD, 0)) - - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/aop/OkHttpHook", - "addDoKitIntercept", - "(Lokhttp3/OkHttpClient;)V", - false - ) - ) - this - } - - } - - /** - * 创建OkhttpClient一个数构造函数指令 - */ - private fun createMessageSenderHookInsnList(): InsnList { - return with(InsnList()) { - //插入application 拦截器 - val l0= LabelNode() - add(l0) - add(VarInsnNode(ALOAD, 0)) - add(VarInsnNode(ALOAD, 1)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/tcp/ability/MessageSenderHook", - "hookSendMessage", - "(Lcom/didi/daijia/tcp/message/MessageSender;Ljava/lang/Object;)Z", - false - ) - ) - val l1= LabelNode() - add(JumpInsnNode(IFEQ,l1)) - val l2= LabelNode() - add(l2) - add(InsnNode(ICONST_1)) - add(InsnNode(IRETURN)) - add(l1) - add(FrameNode(F_SAME,0,null,0,null)) - this - } - - } - /** - * 创建OkhttpClient一个数构造函数指令 - */ - private fun createMessageReceiverHookInsnList(): InsnList { - return with(InsnList()) { - //插入application 拦截器 - val l0= LabelNode() - add(l0) - add(VarInsnNode(ALOAD, 0)) - add(VarInsnNode(ALOAD, 1)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/tcp/ability/MessageReceiverHook", - "hookChannelRead", - "(Lcom/didi/daijia/tcp/message/MessageReceiver;Ljava/lang/Object;)Z", - false - ) - ) - val l1= LabelNode() - add(JumpInsnNode(IFEQ,l1)) - val l2= LabelNode() - add(l2) - add(InsnNode(RETURN)) - add(l1) - add(FrameNode(F_SAME,0,null,0,null)) - this - } - - } - - /** - * 创建OkhttpClient一个数构造函数指令 - */ - private fun createDidiHttpClientInsnList(): InsnList { - return with(InsnList()) { - //插入application 拦截器 - add(VarInsnNode(ALOAD, 0)) - - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/foundation/net/rpc/http/DidiHttpHook", - "addRpcIntercept", - "(Ldidihttp/DidiHttpClient;)V", - false - ) - ) - this - } - - } - - /** - * 创建webView函数指令集 - * 参考:https://www.jianshu.com/p/7d623f441bed - */ - private fun createWebViewInsnList(): InsnList { - return with(InsnList()) { - //复制栈顶的2个指令 指令集变为 比如 aload 2 aload0 / aload 2 aload0 - add(InsnNode(DUP2)) - //抛出最上面的指令 指令集变为 aload 2 aload0 / aload 2 其中 aload 2即为我们所需要的对象 - add(InsnNode(POP)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/aop/WebViewHook", - "inject", - "(Ljava/lang/Object;)V", - false - ) - ) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/aop/WebViewHook", - "getSafeUrl", - "(Ljava/lang/String;)Ljava/lang/String;", - false - ) - ) - this - } - } - - - /** - * 创建new DoKitAppCompatDelegateImpl指令集 - */ - private fun createNewDoKitAppCompatDelegateImplInsnList(): InsnList { - return with(InsnList()) { - add(TypeInsnNode(NEW, "androidx/appcompat/app/DoKitAppCompatDelegateImpl")) - add(InsnNode(DUP)) - this - } - } - - - /** - * 重置ComponentActivity的父类 - */ - private fun createComponentActivitySuperActivityImpl(klass: ClassNode) { - /** - * 修改继承的父类 - */ - klass.superName = "com/didichuxing/doraemonkit/aop/mc/DoKitProxyActivity" - } - - - /** - * 重置View的父类 - */ - private fun createViewImpl(klass: ClassNode) { - /** - * 修改继承的父类 - */ - klass.superName = "com/didichuxing/doraemonkit/aop/mc/DoKitProxyView" - } - - - /** - * 重置ViewGroup的父类 - */ - private fun createViewGroupImpl(klass: ClassNode) { - /** - * 修改继承的父类 - */ - klass.superName = "com/didichuxing/doraemonkit/aop/mc/DoKitProxyViewGroup" - } - -} diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/UrlConnectionTransformer.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/UrlConnectionTransformer.kt deleted file mode 100644 index 641f7950b..000000000 --- a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/UrlConnectionTransformer.kt +++ /dev/null @@ -1,68 +0,0 @@ -package com.didichuxing.doraemonkit.plugin.classtransformer - -import com.didichuxing.doraemonkit.plugin.DoKitExtUtil -import com.didichuxing.doraemonkit.plugin.isRelease -import com.didichuxing.doraemonkit.plugin.lastPath -import com.didichuxing.doraemonkit.plugin.println -import com.didiglobal.booster.annotations.Priority -import com.didiglobal.booster.kotlinx.asIterable -import com.didiglobal.booster.transform.TransformContext -import com.didiglobal.booster.transform.asm.ClassTransformer -import com.didiglobal.booster.transform.asm.className -import com.google.auto.service.AutoService -import org.objectweb.asm.Opcodes.INVOKESTATIC -import org.objectweb.asm.Opcodes.INVOKEVIRTUAL -import org.objectweb.asm.tree.ClassNode -import org.objectweb.asm.tree.MethodInsnNode - -/** - * ================================================ - * 作 者:jint(金台) - * 版 本:1.0 - * 创建日期:2020/5/14-18:07 - * 描 述:wiki:https://juejin.im/post/5e8d87c4f265da47ad218e6b - * 修订历史: - * ================================================ - */ -//@Priority(1) -//@AutoService(ClassTransformer::class) -class UrlConnectionTransformer : AbsClassTransformer() { - private val SHADOW_URL = - "com/didichuxing/doraemonkit/aop/urlconnection/HttpUrlConnectionProxyUtil" - private val DESC = "(Ljava/net/URLConnection;)Ljava/net/URLConnection;" - - override fun transform(context: TransformContext, klass: ClassNode): ClassNode { - if (onCommInterceptor(context, klass)) { - return klass - } - - if (!DoKitExtUtil.commExt.networkSwitch) { - return klass - } - - if (DoKitExtUtil.ignorePackageNames(klass.className)) { - return klass - } - - klass.methods.forEach { method -> - method.instructions?.iterator()?.asIterable() - ?.filterIsInstance(MethodInsnNode::class.java)?.filter { - it.opcode == INVOKEVIRTUAL && - it.owner == "java/net/URL" && - it.name == "openConnection" && - it.desc == "()Ljava/net/URLConnection;" - }?.forEach { - "${context.projectDir.lastPath()}-> hook urlconnection succeed:${klass.name}_${it.name}_${it.desc}".println() - method.instructions.insert( - it, - MethodInsnNode(INVOKESTATIC, SHADOW_URL, "proxy", DESC, false) - ) - } - } - - return klass - } - - -} - diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/BigImageExtension.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/BigImageExtension.kt new file mode 100644 index 000000000..b96d6d8ba --- /dev/null +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/BigImageExtension.kt @@ -0,0 +1,48 @@ +package com.didichuxing.doraemonkit.plugin.extension + + +/** + * didi Create on 2023/3/21 . + * + * Copyright (c) 2023/3/21 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/21 6:07 下午 + * @Description 用一句话说明文件功能 + */ + +open class BigImageExtension( + var glide: Boolean = true, + var picasso: Boolean = true, + var fresco: Boolean = true, + var imageLoader: Boolean = true, + var coil: Boolean = true +) { + + + fun glide(boolean: Boolean) { + glide = boolean + } + + fun picasso(boolean: Boolean) { + picasso = boolean + } + + fun fresco(boolean: Boolean) { + fresco = boolean + } + + fun imageLoader(boolean: Boolean) { + imageLoader = boolean + } + + fun coil(boolean: Boolean) { + coil = boolean + } + + + override fun toString(): String { + return "BigImageExtension(glide=$glide, picasso=$picasso, Fresco=$fresco, imageLoader=$imageLoader, coil=$coil)" + } +} diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/CommExt.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/CommExt.kt deleted file mode 100644 index 4daa03899..000000000 --- a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/CommExt.kt +++ /dev/null @@ -1,46 +0,0 @@ -package com.didichuxing.doraemonkit.plugin.extension - -/** - * ================================================ - * 作 者:jint(金台) - * 版 本:1.0 - * 创建日期:2020/4/28-14:56 - * 描 述: - * 修订历史: - * ================================================ - */ -open class CommExt( - var gpsSwitch: Boolean = true, - var networkSwitch: Boolean = true, - var bigImgSwitch: Boolean = true, - var webViewSwitch: Boolean = true, - var didinetSwitch: Boolean = true -) { - - fun gpsSwitch(gpsSwitch: Boolean) { - this.gpsSwitch = gpsSwitch - } - - fun networkSwitch(networkSwitch: Boolean) { - this.networkSwitch = networkSwitch - } - - fun didinetSwitch(didinetSwitch: Boolean) { - this.didinetSwitch = didinetSwitch - } - - - fun bigImgSwitch(bigImgSwitch: Boolean) { - this.bigImgSwitch = bigImgSwitch - } - - fun webViewSwitch(webViewSwitch: Boolean) { - this.webViewSwitch = webViewSwitch - } - - override fun toString(): String { - return "CommExt(gpsSwitch=$gpsSwitch, networkSwitch=$networkSwitch,didinetSwitch=$didinetSwitch, bigImgSwitch=$bigImgSwitch, webviewSwitch=$webViewSwitch)" - } - - -} \ No newline at end of file diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/DoKitExt.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/DoKitExt.kt deleted file mode 100644 index b88b95f22..000000000 --- a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/DoKitExt.kt +++ /dev/null @@ -1,42 +0,0 @@ -package com.didichuxing.doraemonkit.plugin.extension - -import org.gradle.api.Action - -/** - * Created by jint on 07/10/2018. - */ -open class DoKitExt( - //var dokitPluginSwitch: Boolean = true, - var comm: CommExt = CommExt(), - var slowMethod: SlowMethodExt = SlowMethodExt()) { - - - //方法名必须和插件配置一直才能进行反射注入 -// fun dokitPluginSwitch(dokitPluginSwitch: Boolean) { -// this.dokitPluginSwitch = dokitPluginSwitch -// } - - /** - * 让comm 支持 DSL 语法 - * - * @param action - */ - fun comm(action: Action) { - action.execute(comm) - } - - /** - * 让slowMethod 支持 DSL 语法 - * - * @param action - */ - fun slowMethod(action: Action) { - action.execute(slowMethod) - } - - override fun toString(): String { - return "DoKitExt(comm=$comm, slowMethod=$slowMethod)" - } - - -} \ No newline at end of file diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/DoKitExtension.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/DoKitExtension.kt new file mode 100644 index 000000000..0f29b26d8 --- /dev/null +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/DoKitExtension.kt @@ -0,0 +1,82 @@ +package com.didichuxing.doraemonkit.plugin.extension + +import org.gradle.api.Action + +/** + * Created by jint on 07/10/2018. + * + * DoKit plugin 配置实例 @see DoKitExtension + * + * 支持DSL语法可以在插件中直接配置 + */ +open class DoKitExtension( + var pluginEnable: Boolean = true, + var logEnable: Boolean = true, + var thirdLibEnable: Boolean = true, + + var gpsEnable: Boolean = true, + var gps: GpsExtension = GpsExtension(), + + var networkEnable: Boolean = true, + var network: NetworkExtension = NetworkExtension(), + + var bigImageEnable: Boolean = true, + var bigImage: BigImageExtension = BigImageExtension(), + + var webViewEnable: Boolean = true, + var webView: WebViewExtension = WebViewExtension(), + + var slowMethodEnable: Boolean = true, + var slowMethod: SlowMethodExtension = SlowMethodExtension() +) { + + + /** + * gps 支持 DSL 语法 + * + * @param action + */ + fun gps(action: Action) { + action.execute(gps) + } + + /** + * network 支持 DSL 语法 + * + * @param action + */ + fun network(action: Action) { + action.execute(network) + } + + /** + * bigImage 支持 DSL 语法 + * + * @param action + */ + fun bigImage(action: Action) { + action.execute(bigImage) + } + + fun webView(action: Action) { + action.execute(webView) + } + + /** + * 让slowMethod 支持 DSL 语法 + * + * @param action + */ + fun slowMethod(action: Action) { + action.execute(slowMethod) + } + + + + + override fun toString(): String { + return "DoKitExtension(pluginEnable=$pluginEnable, logEnable=$logEnable, thirdLibEnable=$thirdLibEnable, gpsEnable=$gpsEnable, gps=$gps, networkEnable=$networkEnable, network=$network, bigImageEnable=$bigImageEnable, bigImage=$bigImage, webViewEnable=$webViewEnable, webView=$webView, slowMethodEnable=$slowMethodEnable, slowMethod=$slowMethod)" + } + + +} diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/GpsExtension.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/GpsExtension.kt new file mode 100644 index 000000000..dc97004e2 --- /dev/null +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/GpsExtension.kt @@ -0,0 +1,48 @@ +package com.didichuxing.doraemonkit.plugin.extension + + +/** + * didi Create on 2023/3/21 . + * + * Copyright (c) 2023/3/21 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/21 5:36 下午 + * @Description 用一句话说明文件功能 + * @see DoKitExtension + */ + +open class GpsExtension( + var local: Boolean = true, + var baidu: Boolean = true, + var tencent: Boolean = true, + var amap: Boolean = true, + var didi: Boolean = true +) { + + + fun local(boolean: Boolean) { + local = boolean + } + + fun baidu(boolean: Boolean) { + baidu = boolean + } + + fun tencent(boolean: Boolean) { + tencent = boolean + } + + fun amap(boolean: Boolean) { + amap = boolean + } + + fun didi(boolean: Boolean) { + didi = boolean + } + + override fun toString(): String { + return "GpsExtension(local=$local, baidu=$baidu, tencent=$tencent, didi=$didi)" + } +} diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/NetworkExtension.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/NetworkExtension.kt new file mode 100644 index 000000000..6bd287b86 --- /dev/null +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/NetworkExtension.kt @@ -0,0 +1,47 @@ +package com.didichuxing.doraemonkit.plugin.extension + + +/** + * didi Create on 2023/3/21 . + * + * Copyright (c) 2023/3/21 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/21 5:36 下午 + * @Description 用一句话说明文件功能 + */ + +open class NetworkExtension( + var okHttp: Boolean = true, + var urlConnect: Boolean = true, + var didiHttp: Boolean = true, + var didiSocket: Boolean = true, + var didiDjSocket: Boolean = true +) { + + + fun okHttp(boolean: Boolean) { + okHttp = boolean + } + + fun urlConnect(boolean: Boolean) { + urlConnect = boolean + } + + fun didiHttp(boolean: Boolean) { + didiHttp = boolean + } + + fun didiSocket(boolean: Boolean) { + didiSocket = boolean + } + + fun didiDjSocket(boolean: Boolean) { + didiDjSocket = boolean + } + + override fun toString(): String { + return "NetworkExtension(okHttp=$okHttp, urlConnect=$urlConnect, didiHttp=$didiHttp, didiSocket=$didiSocket, didiDjSocket=$didiDjSocket)" + } +} diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/SlowMethodExt.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/SlowMethodExtension.kt similarity index 98% rename from Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/SlowMethodExt.kt rename to Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/SlowMethodExtension.kt index 82844403e..ede80d619 100644 --- a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/SlowMethodExt.kt +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/SlowMethodExtension.kt @@ -2,7 +2,6 @@ package com.didichuxing.doraemonkit.plugin.extension import groovy.lang.Closure import org.gradle.util.ConfigureUtil -import java.util.* /** * ================================================ @@ -14,7 +13,7 @@ import java.util.* * ================================================ */ -open class SlowMethodExt( +open class SlowMethodExtension( //0:打印函数调用栈 1:普通模式 运行时打印某个函数的耗时 全局业务代码函数插入 @Deprecated("已弃用,请在项目根目录的gradle.properties中通过DOKIT_METHOD_STRATEGY=0|1 来控制") var strategy: Int = STRATEGY_STACK, @@ -125,4 +124,4 @@ open class SlowMethodExt( const val STRATEGY_STACK = 0 const val STRATEGY_NORMAL = 1 } -} \ No newline at end of file +} diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/WebViewExtension.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/WebViewExtension.kt new file mode 100644 index 000000000..1351b8df7 --- /dev/null +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/WebViewExtension.kt @@ -0,0 +1,38 @@ +package com.didichuxing.doraemonkit.plugin.extension + + +/** + * didi Create on 2023/3/21 . + * + * Copyright (c) 2023/3/21 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/21 6:10 下午 + * @Description 用一句话说明文件功能 + */ + +open class WebViewExtension( + var network: Boolean = true, + var dokitWeb: Boolean = false, + var vConsole: Boolean = false +) { + + fun network(boolean: Boolean) { + network = boolean + } + + fun dokitWeb(boolean: Boolean) { + dokitWeb = boolean + } + + fun vConsole(boolean: Boolean) { + vConsole = boolean + } + + override fun toString(): String { + return "WebViewExtension(network=$network, dokitWeb=$dokitWeb, vConsole=$vConsole)" + } + + +} diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/processor/DoKitComponentHandler.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/processor/DoKitComponentHandler.kt index ba6c0d60e..dc50de67d 100644 --- a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/processor/DoKitComponentHandler.kt +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/processor/DoKitComponentHandler.kt @@ -1,6 +1,5 @@ package com.didichuxing.doraemonkit.plugin.processor -import com.didichuxing.doraemonkit.plugin.println import org.xml.sax.Attributes import org.xml.sax.helpers.DefaultHandler @@ -58,4 +57,4 @@ class DoKitComponentHandler : DefaultHandler() { } } -} \ No newline at end of file +} diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/processor/DoKitPluginConfigProcessor.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/processor/DoKitPluginConfigProcessor.kt index 1525e60d9..8684e507e 100644 --- a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/processor/DoKitPluginConfigProcessor.kt +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/processor/DoKitPluginConfigProcessor.kt @@ -3,20 +3,16 @@ package com.didichuxing.doraemonkit.plugin.processor import com.android.build.gradle.AppExtension import com.android.build.gradle.api.ApplicationVariant import com.android.build.gradle.api.BaseVariant -import com.android.build.gradle.internal.pipeline.TransformTask import com.didichuxing.doraemonkit.plugin.* -import com.didichuxing.doraemonkit.plugin.extension.DoKitExt +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.thirdlib.ThirdLibInfo import com.didiglobal.booster.gradle.dependencies import com.didiglobal.booster.gradle.getAndroid import com.didiglobal.booster.gradle.mergedManifests import com.didiglobal.booster.gradle.project import com.didiglobal.booster.task.spi.VariantProcessor -import com.didiglobal.booster.transform.ArtifactManager -import com.didiglobal.booster.transform.artifacts -import com.didiglobal.booster.transform.util.ComponentHandler import org.gradle.api.Project import org.gradle.api.artifacts.result.ResolvedArtifactResult -import java.lang.NullPointerException import javax.xml.parsers.SAXParserFactory /** @@ -42,96 +38,32 @@ class DoKitPluginConfigProcessor(val project: Project) : VariantProcessor { if (DoKitExtUtil.THIRD_LIBINFO_SWITCH) { //遍历三方库 val dependencies = variant.dependencies - DoKitExtUtil.THIRD_LIB_INFOS.clear() for (artifactResult: ResolvedArtifactResult in dependencies) { - //println("三方库信息===>${artifactResult.variant.displayName}____${artifactResult.file.toString()}") - ///Users/didi/project/android/dokit_github/DoraemonKit/Android/java/app/libs/BaiduLBS_Android.jar - ///Users/didi/.gradle/caches/modules-2/files-2.1/androidx.activity/activity-ktx/1.2.0/c16aac66e6c4617b01118ab2509f009bb7919b3b/activity-ktx-1.2.0.aar - //println("三方库信息===>${artifactResult.variant.displayName}____${artifactResult.file.toString()}") -// "artifactResult===>${artifactResult.file}|${artifactResult.variant}|${artifactResult.id}|${artifactResult.type}".println() - //"artifactResult===>${artifactResult.variant.owner}|${artifactResult.variant.attributes}|${artifactResult.variant.displayName}|${artifactResult.variant.capabilities}|${artifactResult.variant.externalVariant}".println() - //"artifactResult===>${artifactResult.variant.displayName}".println() val variants = artifactResult.variant.displayName.split(" ") var thirdLibInfo: ThirdLibInfo? = null if (variants.size == 3) { - thirdLibInfo = ThirdLibInfo( - variants[0], - artifactResult.file.length() - ) - if (thirdLibInfo.variant.contains("dokitx-rpc")) { - DoKitExtUtil.HAS_DOKIT_RPC_MODULE = true - } - if (thirdLibInfo.variant.contains("dokitx-tcp-hook-dj")) { - DoKitExtUtil.HAS_DOKIT_TCP_HOOK_DJ = true - } - - if (thirdLibInfo.variant.contains("dokitx-gps-mock") || thirdLibInfo.variant.contains("dokit-gps-mock")){ - DoKitExtUtil.DOKIT_GPS_MOCK_INCLUDE = true; - } -// "thirdLibInfo.variant===>${thirdLibInfo.variant}".println() - DoKitExtUtil.THIRD_LIB_INFOS.add(thirdLibInfo) + thirdLibInfo = ThirdLibInfo(variants[0], artifactResult.file.length()) + checkConfig(thirdLibInfo.variant) } else if (variants.size == 4) { - thirdLibInfo = ThirdLibInfo( - "porject ${variants[1]}", - artifactResult.file.length() - ) - if (thirdLibInfo.variant.contains("doraemonkit-rpc")) { - DoKitExtUtil.HAS_DOKIT_RPC_MODULE = true - } - if (thirdLibInfo.variant.contains("dokitx-tcp-hook-dj")) { - DoKitExtUtil.HAS_DOKIT_TCP_HOOK_DJ = true - } - - if (thirdLibInfo.variant.contains("dokitx-gps-mock") || thirdLibInfo.variant.contains("dokit-gps-mock")){ - DoKitExtUtil.DOKIT_GPS_MOCK_INCLUDE = true; - } - -// "thirdLibInfo.variant===>${thirdLibInfo.variant}".println() - DoKitExtUtil.THIRD_LIB_INFOS.add(thirdLibInfo) + thirdLibInfo = ThirdLibInfo("porject ${variants[1]}", artifactResult.file.length()) + checkConfig(thirdLibInfo.variant) } + } + } + //查找AndroidManifest.xml 文件 并处理 + processApplicationVariant(variant) + + } - // val paths = artifactResult.file.toString().split("/") -// var fileName: String = "" -// var groupId: String = "" -// var artifactId: String = "" -// var version: String = "" -// if (artifactResult.file.toString().contains(".gradle/caches")) { -// if (paths.size >= 5) { -// groupId = paths[paths.size - 5] -// artifactId = paths[paths.size - 4] -// version = paths[paths.size - 3] -// fileName = -// "$groupId:$artifactId:$version" -// } else { -// fileName = paths[paths.size - 1] -// } -// } else { -// fileName = paths[paths.size - 1] -// } -// -// val thirdLibInfo = -// ThirdLibInfo( -// groupId, -// artifactId, -// version, -// fileName, -// artifactResult.file.length(), -// artifactResult.variant.displayName -// ) -// val key = "$groupId:$artifactId" -// if (DoKitExtUtil.THIRD_LIB_INFOS[key] == null) { -// DoKitExtUtil.THIRD_LIB_INFOS[key] = thirdLibInfo -// } else { -// val libInfo = DoKitExtUtil.THIRD_LIB_INFOS[key] -// if (DoKitPluginUtil.compareVersion(thirdLibInfo.version, libInfo!!.version) > 0) { -// DoKitExtUtil.THIRD_LIB_INFOS[key] = thirdLibInfo -// } -// } - } + private fun checkConfig(variant: String) { + if (variant.contains("dokitx-gps-mock") || variant.contains("dokit-gps-mock")) { + DoKitExtUtil.DOKIT_GPS_MOCK_INCLUDE = true; } + } + private fun processApplicationVariant(variant: BaseVariant) { //查找application module下的配置 if (variant is ApplicationVariant) { @@ -161,13 +93,12 @@ class DoKitPluginConfigProcessor(val project: Project) : VariantProcessor { //读取插件配置 variant.project.getAndroid().let { appExt -> //查找Application路径 - val doKitExt = variant.project.extensions.getByType(DoKitExt::class.java) + val doKitExt = variant.project.extensions.getByType(DoKitExtension::class.java) DoKitExtUtil.init(doKitExt) } } } - } else { "${variant.project.name}-不建议在Library Module下引入dokit插件".println() } diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/stack_method/MethodStackNodeUtil.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/stack_method/MethodStackNodeUtil.kt index b048260fa..a629f10cb 100644 --- a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/stack_method/MethodStackNodeUtil.kt +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/stack_method/MethodStackNodeUtil.kt @@ -1,6 +1,5 @@ package com.didichuxing.doraemonkit.plugin.stack_method -import org.gradle.internal.impldep.org.apache.commons.lang.mutable.Mutable import java.util.* /** @@ -27,4 +26,4 @@ object MethodStackNodeUtil { } -} \ No newline at end of file +} diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/ThirdLibInfo.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/thirdlib/ThirdLibInfo.kt similarity index 56% rename from Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/ThirdLibInfo.kt rename to Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/thirdlib/ThirdLibInfo.kt index 0e641f234..0ef8309f6 100644 --- a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/ThirdLibInfo.kt +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/thirdlib/ThirdLibInfo.kt @@ -1,4 +1,4 @@ -package com.didichuxing.doraemonkit.plugin +package com.didichuxing.doraemonkit.plugin.thirdlib /** * ================================================ @@ -9,14 +9,6 @@ package com.didichuxing.doraemonkit.plugin * 修订历史: * ================================================ */ -//data class ThirdLibInfo( -// val groupId: String, -// val artifactId: String, -// val version: String, -// val fileName: String, -// val fileSize: Long, -// val variant: String -//) data class ThirdLibInfo(val variant: String, val fileSize: Long) diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/thirdlib/ThirdLibVariantProcessor.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/thirdlib/ThirdLibVariantProcessor.kt new file mode 100644 index 000000000..e12718765 --- /dev/null +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/thirdlib/ThirdLibVariantProcessor.kt @@ -0,0 +1,55 @@ +package com.didichuxing.doraemonkit.plugin.thirdlib + +import com.android.build.gradle.api.BaseVariant +import com.didichuxing.doraemonkit.plugin.DoKitExtUtil +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.isRelease +import com.didiglobal.booster.gradle.dependencies +import com.didiglobal.booster.task.spi.VariantProcessor +import org.gradle.api.Project +import org.gradle.api.artifacts.result.ResolvedArtifactResult + + +/** + * didi Create on 2023/3/22 . + * + * Copyright (c) 2023/3/22 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/22 2:57 下午 + * @Description 用一句话说明文件功能 + */ + +class ThirdLibVariantProcessor(val project: Project) : VariantProcessor { + + override fun process(variant: BaseVariant) { + if (!DoKitExtUtil.DOKIT_PLUGIN_SWITCH) { + return + } + + if (variant.isRelease()) { + return + } + + val dokit = project.extensions.getByType(DoKitExtension::class.java) + + //统计三方库信息 + if (dokit.thirdLibEnable && DoKitExtUtil.THIRD_LIBINFO_SWITCH) { + //遍历三方库 + val dependencies = variant.dependencies + DoKitExtUtil.THIRD_LIB_INFOS.clear() + for (artifactResult: ResolvedArtifactResult in dependencies) { + val variants = artifactResult.variant.displayName.split(" ") + var thirdLibInfo: ThirdLibInfo? = null + if (variants.size == 3) { + thirdLibInfo = ThirdLibInfo(variants[0], artifactResult.file.length()) + DoKitExtUtil.THIRD_LIB_INFOS.add(thirdLibInfo) + } else if (variants.size == 4) { + thirdLibInfo = ThirdLibInfo("porject ${variants[1]}", artifactResult.file.length()) + DoKitExtUtil.THIRD_LIB_INFOS.add(thirdLibInfo) + } + } + } + } +} diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitBaseTransform.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitBaseTransform.kt index 87aeab06c..af3072809 100644 --- a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitBaseTransform.kt +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitBaseTransform.kt @@ -5,9 +5,6 @@ import com.android.build.api.transform.Transform import com.android.build.api.transform.TransformInvocation import com.android.build.gradle.BaseExtension import com.android.build.gradle.internal.pipeline.TransformManager -import com.didichuxing.doraemonkit.plugin.DoKitTransformInvocation -import com.didichuxing.doraemonkit.plugin.println -import com.didiglobal.booster.annotations.Priority import com.didiglobal.booster.gradle.* import com.didiglobal.booster.transform.AbstractKlassPool import com.didiglobal.booster.transform.Transformer @@ -18,6 +15,7 @@ import org.gradle.api.Project * DoKitCommTransform 作用于 CommTransformer、BigImgTransformer、UrlConnectionTransformer、GlobalSlowMethodTransformer * @author johnsonlee */ + open class DoKitBaseTransform protected constructor(val project: Project) : Transform() { /*transformers @@ -80,7 +78,6 @@ open class DoKitBaseTransform protected constructor(val project: Project) : Tran } - } /** diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitCommTransform.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitCommTransform.kt deleted file mode 100644 index 6735e152a..000000000 --- a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitCommTransform.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.didichuxing.doraemonkit.plugin.transform - -import com.didichuxing.doraemonkit.plugin.asmtransformer.DoKitAsmTransformer -import com.didichuxing.doraemonkit.plugin.classtransformer.BigImgClassTransformer -import com.didichuxing.doraemonkit.plugin.classtransformer.CommClassTransformer -import com.didichuxing.doraemonkit.plugin.classtransformer.EnterMSClassTransformer -import com.didichuxing.doraemonkit.plugin.classtransformer.GSMClassTransformer -import com.didiglobal.booster.transform.Transformer -import org.gradle.api.Project - -/** - * Represents the transform base - * DoKitCommTransform 作用于 CommTransformer、BigImgTransformer、UrlConnectionTransformer、GlobalSlowMethodTransformer、EnterMethodStackTransformer - * @author johnsonlee - */ -class DoKitCommTransform(androidProject: Project) : DoKitBaseTransform(androidProject) { - - override val transformers = listOf( - DoKitAsmTransformer( - listOf( - CommClassTransformer(), - BigImgClassTransformer(), - GSMClassTransformer(), - EnterMSClassTransformer() - ) - ) - ) - -} diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitCommonTransform.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitCommonTransform.kt new file mode 100644 index 000000000..28b5f72e8 --- /dev/null +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitCommonTransform.kt @@ -0,0 +1,40 @@ +package com.didichuxing.doraemonkit.plugin.transform + +import com.didichuxing.doraemonkit.plugin.transform.asmtransform.DoKitAsmTransformer +import com.didichuxing.doraemonkit.plugin.transform.classtransform.* +import com.didiglobal.booster.transform.Transformer +import org.gradle.api.Project + +/** + * Represents the transform base + * DoKitCommTransform 作用于 CommTransformer、BigImgTransformer、UrlConnectionTransformer、GlobalSlowMethodTransformer、EnterMethodStackTransformer + * @author johnsonlee + */ +class DoKitCommonTransform(androidProject: Project) : DoKitBaseTransform(androidProject) { + + override val transformers = listOf( + DoKitAsmTransformer( + listOf( + CommClassTransformer(), + ThirdLibsClassTransformer(), + //网络 + Okhttp3ClassTransformer(), + UrlConnectionTransformer(), + WebViewClassTransformer(), + + //地图GPS + GPSClassTransformer(), + GPSAMapClassTransformer(), + GPSBDClassTransformer(), + GPSTencentClassTransformer(), + //大图检测 + BigImgClassTransformer(), + //全局慢函数 + GSMClassTransformer(), + //入口慢函数 + EnterMSClassTransformer() + ) + ) + ) + +} diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitCommTransformV34.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitCommonTransformV34.kt similarity index 60% rename from Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitCommTransformV34.kt rename to Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitCommonTransformV34.kt index 40a7342b6..e40e76de6 100644 --- a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitCommTransformV34.kt +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitCommonTransformV34.kt @@ -1,23 +1,34 @@ package com.didichuxing.doraemonkit.plugin.transform import com.android.build.api.variant.VariantInfo -import com.didichuxing.doraemonkit.plugin.DoKitExtUtil -import com.didichuxing.doraemonkit.plugin.asmtransformer.DoKitAsmTransformer -import com.didichuxing.doraemonkit.plugin.classtransformer.* -import com.didichuxing.doraemonkit.plugin.extension.SlowMethodExt -import com.didichuxing.doraemonkit.plugin.stack_method.MethodStackNodeUtil +import com.didichuxing.doraemonkit.plugin.transform.asmtransform.DoKitAsmTransformer +import com.didichuxing.doraemonkit.plugin.transform.classtransform.* import com.didiglobal.booster.transform.Transformer import org.gradle.api.Project -class DoKitCommTransformV34(project: Project) : DoKitBaseTransform(project) { +class DoKitCommonTransformV34(project: Project) : DoKitBaseTransform(project) { override val transformers = listOf( DoKitAsmTransformer( listOf( CommClassTransformer(), + ThirdLibsClassTransformer(), + //网络 + Okhttp3ClassTransformer(), + UrlConnectionTransformer(), + WebViewClassTransformer(), + + //地图GPS + GPSClassTransformer(), + GPSAMapClassTransformer(), + GPSBDClassTransformer(), + GPSTencentClassTransformer(), + //大图检测 BigImgClassTransformer(), + //全局慢函数 GSMClassTransformer(), + //入口慢函数 EnterMSClassTransformer() ) ) diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitDependTransform.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitDependTransform.kt index 9a61ad742..8c1068913 100644 --- a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitDependTransform.kt +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitDependTransform.kt @@ -1,7 +1,7 @@ package com.didichuxing.doraemonkit.plugin.transform -import com.didichuxing.doraemonkit.plugin.asmtransformer.DoKitAsmTransformer -import com.didichuxing.doraemonkit.plugin.classtransformer.MSDClassTransformer +import com.didichuxing.doraemonkit.plugin.transform.asmtransform.DoKitAsmTransformer +import com.didichuxing.doraemonkit.plugin.transform.classtransform.MSDClassTransformer import com.didiglobal.booster.transform.Transformer import org.gradle.api.Project diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitDependTransformV34.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitDependTransformV34.kt index 42b03fe03..6f527aed2 100644 --- a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitDependTransformV34.kt +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitDependTransformV34.kt @@ -1,8 +1,8 @@ package com.didichuxing.doraemonkit.plugin.transform import com.android.build.api.variant.VariantInfo -import com.didichuxing.doraemonkit.plugin.asmtransformer.DoKitAsmTransformer -import com.didichuxing.doraemonkit.plugin.classtransformer.MSDClassTransformer +import com.didichuxing.doraemonkit.plugin.transform.asmtransform.DoKitAsmTransformer +import com.didichuxing.doraemonkit.plugin.transform.classtransform.MSDClassTransformer import com.didiglobal.booster.transform.Transformer import org.gradle.api.Project diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitTransformContext.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitTransformContext.kt new file mode 100644 index 000000000..02b9a56c1 --- /dev/null +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitTransformContext.kt @@ -0,0 +1,23 @@ +package com.didichuxing.doraemonkit.plugin.transform + +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import org.gradle.api.Project + + +/** + * didi Create on 2023/3/21 . + * + * Copyright (c) 2023/3/21 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/21 6:31 下午 + * @Description 用一句话说明文件功能 + */ + +interface DoKitTransformContext { + + fun project(): Project + + fun dokitExtension(): DoKitExtension +} diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitTransformInvocation.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitTransformInvocation.kt similarity index 90% rename from Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitTransformInvocation.kt rename to Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitTransformInvocation.kt index aeea0c9da..a4b193d90 100644 --- a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitTransformInvocation.kt +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitTransformInvocation.kt @@ -1,20 +1,20 @@ -package com.didichuxing.doraemonkit.plugin +package com.didichuxing.doraemonkit.plugin.transform import com.android.build.api.transform.* import com.android.build.api.transform.Status.* import com.android.dex.DexFormat -import com.android.dx.command.dexer.Main -import com.didichuxing.doraemonkit.plugin.transform.DoKitBaseTransform +import com.didichuxing.doraemonkit.plugin.dex +import com.didichuxing.doraemonkit.plugin.dokitTransform +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.println import com.didiglobal.booster.gradle.* import com.didiglobal.booster.kotlinx.NCPU import com.didiglobal.booster.kotlinx.file import com.didiglobal.booster.kotlinx.green import com.didiglobal.booster.kotlinx.red -import com.didiglobal.booster.transform.AbstractKlassPool -import com.didiglobal.booster.transform.ArtifactManager -import com.didiglobal.booster.transform.TransformContext -import com.didiglobal.booster.transform.artifacts +import com.didiglobal.booster.transform.* import com.didiglobal.booster.transform.util.transform +import org.gradle.api.Project import java.io.File import java.net.URI import java.util.concurrent.* @@ -24,10 +24,10 @@ import java.util.concurrent.* * * @author johnsonlee */ -internal class DoKitTransformInvocation( +internal class DoKitTransformInvocation( private val delegate: TransformInvocation, internal val transform: DoKitBaseTransform -) : TransformInvocation by delegate, TransformContext, ArtifactManager { +) : TransformInvocation by delegate, TransformContext, ArtifactManager,DoKitTransformContext { private val project = transform.project @@ -234,4 +234,22 @@ internal class DoKitTransformInvocation( transformer.transform(this@DoKitTransformInvocation, bytes) } } -} \ No newline at end of file + + override fun project(): Project { + return project + } + + override fun dokitExtension(): DoKitExtension { + return project.extensions.getByType(DoKitExtension::class.java) + } + + override fun registerCollector(collector: Collector) { + TODO("Not yet implemented") + } + + override fun unregisterCollector(collector: Collector) { + TODO("Not yet implemented") + } + + +} diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/asmtransformer/BaseDoKitAsmTransformer.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/asmtransform/BaseDoKitAsmTransformer.kt similarity index 96% rename from Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/asmtransformer/BaseDoKitAsmTransformer.kt rename to Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/asmtransform/BaseDoKitAsmTransformer.kt index a5f01256d..cb4e393c2 100644 --- a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/asmtransformer/BaseDoKitAsmTransformer.kt +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/asmtransform/BaseDoKitAsmTransformer.kt @@ -1,6 +1,5 @@ -package com.didichuxing.doraemonkit.plugin.asmtransformer +package com.didichuxing.doraemonkit.plugin.transform.asmtransform -import com.didichuxing.doraemonkit.plugin.println import com.didiglobal.booster.annotations.Priority import com.didiglobal.booster.transform.TransformContext import com.didiglobal.booster.transform.Transformer diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/asmtransformer/DoKitAsmTransformer.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/asmtransform/DoKitAsmTransformer.kt similarity index 86% rename from Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/asmtransformer/DoKitAsmTransformer.kt rename to Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/asmtransform/DoKitAsmTransformer.kt index aa3581105..21a48a94d 100644 --- a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/asmtransformer/DoKitAsmTransformer.kt +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/asmtransform/DoKitAsmTransformer.kt @@ -1,4 +1,4 @@ -package com.didichuxing.doraemonkit.plugin.asmtransformer +package com.didichuxing.doraemonkit.plugin.transform.asmtransform import com.didiglobal.booster.transform.asm.ClassTransformer diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/AbsClassTransformer.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/AbsClassTransformer.kt new file mode 100644 index 000000000..96aa23380 --- /dev/null +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/AbsClassTransformer.kt @@ -0,0 +1,59 @@ +package com.didichuxing.doraemonkit.plugin.transform.classtransform + +import com.didichuxing.doraemonkit.plugin.DoKitExtUtil +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.isRelease +import com.didichuxing.doraemonkit.plugin.transform.DoKitTransformContext +import com.didiglobal.booster.transform.TransformContext +import com.didiglobal.booster.transform.asm.ClassTransformer +import com.didiglobal.booster.transform.asm.className +import org.gradle.api.Project +import org.objectweb.asm.tree.ClassNode + +/** + * ================================================ + * 作 者:jint(金台) + * 版 本:1.0 + * 创建日期:2021/5/12-18:06 + * 描 述: + * 修订历史: + * ================================================ + */ + +open class AbsClassTransformer : ClassTransformer { + + + open fun onDoKitClassInterceptor(context: TransformContext, klass: ClassNode): Boolean { + if (context.isRelease()) { + return true + } + if (!DoKitExtUtil.dokitPluginSwitchOpen()) { + return true + } + + //过滤kotlin module-info + if (klass.className == "module-info") { + return true + } + return false + } + + override fun transform(context: TransformContext, klass: ClassNode): ClassNode { + if (onDoKitClassInterceptor(context, klass)) { + return klass + } + + if (DoKitExtUtil.ignorePackageNames(klass.className)) { + return klass + } + + if (context is DoKitTransformContext) { + val project = context.project() + val dokit = context.dokitExtension() + transform(project, dokit, context, klass) + } + return klass + } + + open fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode = klass +} diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/BigImgClassTransformer.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/BigImgClassTransformer.kt similarity index 79% rename from Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/BigImgClassTransformer.kt rename to Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/BigImgClassTransformer.kt index 855367894..8bc57b91f 100644 --- a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/BigImgClassTransformer.kt +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/BigImgClassTransformer.kt @@ -1,12 +1,13 @@ -package com.didichuxing.doraemonkit.plugin.classtransformer +package com.didichuxing.doraemonkit.plugin.transform.classtransform -import com.didichuxing.doraemonkit.plugin.* -import com.didiglobal.booster.annotations.Priority +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.getMethodExitInsnNodes +import com.didichuxing.doraemonkit.plugin.lastPath +import com.didichuxing.doraemonkit.plugin.println import com.didiglobal.booster.transform.TransformContext -import com.didiglobal.booster.transform.asm.ClassTransformer import com.didiglobal.booster.transform.asm.className -import com.google.auto.service.AutoService -import org.objectweb.asm.Opcodes.* +import org.gradle.api.Project +import org.objectweb.asm.Opcodes import org.objectweb.asm.tree.ClassNode import org.objectweb.asm.tree.InsnList import org.objectweb.asm.tree.MethodInsnNode @@ -21,28 +22,17 @@ import org.objectweb.asm.tree.VarInsnNode * 修订历史: * ================================================ */ -//@Priority(1) -//@AutoService(ClassTransformer::class) class BigImgClassTransformer : AbsClassTransformer() { - override fun transform(context: TransformContext, klass: ClassNode): ClassNode { - if (onCommInterceptor(context, klass)) { - return klass - } - - if (!DoKitExtUtil.commExt.bigImgSwitch) { + override fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode { + if (!dokit.bigImageEnable) { return klass } - if (DoKitExtUtil.ignorePackageNames(klass.className)) { - return klass - } - - val className = klass.className //glide - if (className == "com.bumptech.glide.request.SingleRequest") { + if (dokit.bigImage.glide && className == "com.bumptech.glide.request.SingleRequest") { klass.methods.find { methodNode -> (methodNode.name == "init" || methodNode.name == "") && methodNode.desc != null }.let { methodNode -> @@ -55,7 +45,7 @@ class BigImgClassTransformer : AbsClassTransformer() { } //picasso - if (className == "com.squareup.picasso.Request") { + if (dokit.bigImage.picasso && className == "com.squareup.picasso.Request") { klass.methods.find { methodNode -> methodNode.name == "" && methodNode.desc != null }.let { methodNode -> @@ -68,7 +58,7 @@ class BigImgClassTransformer : AbsClassTransformer() { } //Fresco - if (className == "com.facebook.imagepipeline.request.ImageRequest") { + if (dokit.bigImage.fresco && className == "com.facebook.imagepipeline.request.ImageRequest") { klass.methods.find { methodNode -> methodNode.name == "" && methodNode.desc != null }.let { methodNode -> @@ -79,7 +69,7 @@ class BigImgClassTransformer : AbsClassTransformer() { } //ImageLoader - if (className == "com.nostra13.universalimageloader.core.ImageLoadingInfo") { + if (dokit.bigImage.imageLoader && className == "com.nostra13.universalimageloader.core.ImageLoadingInfo") { klass.methods.find { methodNode -> methodNode.name == "" && methodNode.desc != null }.let { methodNode -> @@ -89,7 +79,7 @@ class BigImgClassTransformer : AbsClassTransformer() { } //Coil - if (className == "coil.request.ImageRequest") { + if (dokit.bigImage.coil && className == "coil.request.ImageRequest") { "hook Coil Start".println() klass.methods.find { methodNode -> methodNode.name == "" && methodNode.desc != null @@ -101,8 +91,6 @@ class BigImgClassTransformer : AbsClassTransformer() { } } } - - return klass } @@ -111,10 +99,10 @@ class BigImgClassTransformer : AbsClassTransformer() { */ private fun createGlideInsnList(): InsnList { return with(InsnList()) { - add(VarInsnNode(ALOAD, 0)) + add(VarInsnNode(Opcodes.ALOAD, 0)) add( MethodInsnNode( - INVOKESTATIC, + Opcodes.INVOKESTATIC, "com/didichuxing/doraemonkit/aop/bigimg/glide/GlideHook", "proxy", "(Ljava/lang/Object;)V", @@ -130,10 +118,10 @@ class BigImgClassTransformer : AbsClassTransformer() { */ private fun createPicassoInsnList(): InsnList { return with(InsnList()) { - add(VarInsnNode(ALOAD, 0)) + add(VarInsnNode(Opcodes.ALOAD, 0)) add( MethodInsnNode( - INVOKESTATIC, + Opcodes.INVOKESTATIC, "com/didichuxing/doraemonkit/aop/bigimg/picasso/PicassoHook", "proxy", "(Ljava/lang/Object;)V", @@ -145,27 +133,26 @@ class BigImgClassTransformer : AbsClassTransformer() { } - /** * 创建Fresco Aop代码指令 */ private fun createFrescoInsnList(): InsnList { return with(InsnList()) { - add(VarInsnNode(ALOAD, 1)) - add(VarInsnNode(ALOAD, 1)) + add(VarInsnNode(Opcodes.ALOAD, 1)) + add(VarInsnNode(Opcodes.ALOAD, 1)) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/facebook/imagepipeline/request/ImageRequestBuilder", "getSourceUri", "()Landroid/net/Uri;", false ) ) - add(VarInsnNode(ALOAD, 1)) + add(VarInsnNode(Opcodes.ALOAD, 1)) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/facebook/imagepipeline/request/ImageRequestBuilder", "getPostprocessor", "()Lcom/facebook/imagepipeline/request/Postprocessor;", @@ -174,7 +161,7 @@ class BigImgClassTransformer : AbsClassTransformer() { ) add( MethodInsnNode( - INVOKESTATIC, + Opcodes.INVOKESTATIC, "com/didichuxing/doraemonkit/aop/bigimg/fresco/FrescoHook", "proxy", "(Landroid/net/Uri;Lcom/facebook/imagepipeline/request/Postprocessor;)Lcom/facebook/imagepipeline/request/Postprocessor;", @@ -183,7 +170,7 @@ class BigImgClassTransformer : AbsClassTransformer() { ) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/facebook/imagepipeline/request/ImageRequestBuilder", "setPostprocessor", "(Lcom/facebook/imagepipeline/request/Postprocessor;)Lcom/facebook/imagepipeline/request/ImageRequestBuilder;", @@ -195,32 +182,32 @@ class BigImgClassTransformer : AbsClassTransformer() { } - /** * 创建ImageLoader Aop代码指令 */ private fun createImageLoaderInsnList(): InsnList { return with(InsnList()) { - add(VarInsnNode(ALOAD, 6)) + add(VarInsnNode(Opcodes.ALOAD, 6)) add( MethodInsnNode( - INVOKESTATIC, + Opcodes.INVOKESTATIC, "com/didichuxing/doraemonkit/aop/bigimg/imageloader/ImageLoaderHook", "proxy", "(Lcom/nostra13/universalimageloader/core/listener/ImageLoadingListener;)Lcom/nostra13/universalimageloader/core/listener/ImageLoadingListener;", false ) ) - add(VarInsnNode(ASTORE, 6)) + add(VarInsnNode(Opcodes.ASTORE, 6)) this } } + private fun createCoilInsnList(): InsnList { return with(InsnList()) { - add(VarInsnNode(ALOAD, 0)) + add(VarInsnNode(Opcodes.ALOAD, 0)) add( MethodInsnNode( - INVOKESTATIC, + Opcodes.INVOKESTATIC, "com/didichuxing/doraemonkit/aop/bigimg/coil/CoilHook", "proxy", "(Ljava/lang/Object;)V", @@ -231,4 +218,3 @@ class BigImgClassTransformer : AbsClassTransformer() { } } } - diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/CommClassTransformer.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/CommClassTransformer.kt new file mode 100644 index 000000000..9a41231ee --- /dev/null +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/CommClassTransformer.kt @@ -0,0 +1,238 @@ +package com.didichuxing.doraemonkit.plugin.transform.classtransform + +import com.didichuxing.doraemonkit.plugin.DoKitExtUtil +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.extension.SlowMethodExtension +import com.didichuxing.doraemonkit.plugin.formatSuperName +import com.didichuxing.doraemonkit.plugin.lastPath +import com.didichuxing.doraemonkit.plugin.println +import com.didiglobal.booster.transform.TransformContext +import com.didiglobal.booster.transform.asm.className +import org.gradle.api.Project +import org.objectweb.asm.Opcodes +import org.objectweb.asm.tree.* + +/** + * ================================================ + * 作 者:jint(金台) + * 版 本:1.0 + * 创建日期:2020/5/14-18:07 + * 描 述:wiki:https://juejin.im/post/5e8d87c4f265da47ad218e6b + * 修订历史: + * ================================================ + */ +class CommClassTransformer : AbsClassTransformer() { + + override fun transform(context: TransformContext, klass: ClassNode): ClassNode { + + val className = klass.className + val superName = klass.formatSuperName + + //hook Androidx的ComponentActivity + if (className != "com.didichuxing.doraemonkit.aop.mc.DoKitProxyActivity" && superName == "android.app.Activity") { + createComponentActivitySuperActivityImpl(klass) + } + + return super.transform(context, klass) + } + + /** + * 类处理转化实现 + */ + override fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode { + val className = klass.className + + //查找DoraemonKitReal&pluginConfig方法并插入指定字节码 + if (className == "com.didichuxing.doraemonkit.DoKitReal") { + //插件配置 + klass.methods?.find { + it.name == "pluginConfig" + }.let { methodNode -> + "${context.projectDir.lastPath()}->insert map to the DoKitReal pluginConfig succeed".println() + methodNode?.instructions?.insert(createPluginConfigInsnList(dokit.gpsEnable, dokit.networkEnable, dokit.bigImageEnable)) + } + } + return klass + } + + /** + * 创建pluginConfig代码指令 + */ + private fun createPluginConfigInsnList(gpsSwitch: Boolean, networkSwitch: Boolean, bigImgSwitch: Boolean): InsnList { + return with(InsnList()) { + //new HashMap + add(TypeInsnNode(Opcodes.NEW, "java/util/HashMap")) + add(InsnNode(Opcodes.DUP)) + add(MethodInsnNode(Opcodes.INVOKESPECIAL, "java/util/HashMap", "", "()V", false)) + //保存变量 + add(VarInsnNode(Opcodes.ASTORE, 0)) + //获取第一个变量 + //put("dokitPluginSwitch",true) + add(VarInsnNode(Opcodes.ALOAD, 0)) + add(LdcInsnNode("dokitPluginSwitch")) + add(InsnNode(if (DoKitExtUtil.dokitPluginSwitchOpen()) Opcodes.ICONST_1 else Opcodes.ICONST_0)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "java/lang/Boolean", + "valueOf", + "(Z)Ljava/lang/Boolean;", + false + ) + ) + add( + MethodInsnNode( + Opcodes.INVOKEINTERFACE, + "java/util/Map", + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + true + ) + ) + add(InsnNode(Opcodes.POP)) + + //put("gpsSwitch",true) + add(VarInsnNode(Opcodes.ALOAD, 0)) + add(LdcInsnNode("gpsSwitch")) + add(InsnNode(if (gpsSwitch) Opcodes.ICONST_1 else Opcodes.ICONST_0)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "java/lang/Boolean", + "valueOf", + "(Z)Ljava/lang/Boolean;", + false + ) + ) + add( + MethodInsnNode( + Opcodes.INVOKEINTERFACE, + "java/util/Map", + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + true + ) + ) + add(InsnNode(Opcodes.POP)) + + //put("networkSwitch",true) + add(VarInsnNode(Opcodes.ALOAD, 0)) + add(LdcInsnNode("networkSwitch")) + add(InsnNode(if (networkSwitch) Opcodes.ICONST_1 else Opcodes.ICONST_0)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "java/lang/Boolean", + "valueOf", + "(Z)Ljava/lang/Boolean;", + false + ) + ) + add( + MethodInsnNode( + Opcodes.INVOKEINTERFACE, + "java/util/Map", + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + true + ) + ) + add(InsnNode(Opcodes.POP)) + + add(VarInsnNode(Opcodes.ALOAD, 0)) + add(LdcInsnNode("bigImgSwitch")) + add(InsnNode(if (bigImgSwitch) Opcodes.ICONST_1 else Opcodes.ICONST_0)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "java/lang/Boolean", + "valueOf", + "(Z)Ljava/lang/Boolean;", + false + ) + ) + add( + MethodInsnNode( + Opcodes.INVOKEINTERFACE, + "java/util/Map", + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + true + ) + ) + add(InsnNode(Opcodes.POP)) + + add(VarInsnNode(Opcodes.ALOAD, 0)) + add(LdcInsnNode("methodSwitch")) + add(InsnNode(if (DoKitExtUtil.dokitSlowMethodSwitchOpen()) Opcodes.ICONST_1 else Opcodes.ICONST_0)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "java/lang/Boolean", + "valueOf", + "(Z)Ljava/lang/Boolean;", + false + ) + ) + add( + MethodInsnNode( + Opcodes.INVOKEINTERFACE, + "java/util/Map", + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + true + ) + ) + add(InsnNode(Opcodes.POP)) + + + //put("methodStrategy",0) + add(VarInsnNode(Opcodes.ALOAD, 0)) + add(LdcInsnNode("methodStrategy")) + add(InsnNode(if (DoKitExtUtil.SLOW_METHOD_STRATEGY == SlowMethodExtension.STRATEGY_STACK) Opcodes.ICONST_0 else Opcodes.ICONST_1)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "java/lang/Integer", + "valueOf", + "(I)Ljava/lang/Integer;", + false + ) + ) + add( + MethodInsnNode( + Opcodes.INVOKEINTERFACE, + "java/util/Map", + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + true + ) + ) + add(InsnNode(Opcodes.POP)) + + //将HashMap注入到DokitPluginConfig中 + add(VarInsnNode(Opcodes.ALOAD, 0)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/aop/DokitPluginConfig", + "inject", + "(Ljava/util/Map;)V", + false + ) + ) + this + } + } + + /** + * 重置ComponentActivity的父类 + */ + private fun createComponentActivitySuperActivityImpl(klass: ClassNode) { + /** + * 修改继承的父类 + */ + klass.superName = "com/didichuxing/doraemonkit/aop/mc/DoKitProxyActivity" + } + +} diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/EnterMSClassTransformer.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/EnterMSClassTransformer.kt similarity index 79% rename from Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/EnterMSClassTransformer.kt rename to Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/EnterMSClassTransformer.kt index 8502967a5..5062fd614 100644 --- a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/EnterMSClassTransformer.kt +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/EnterMSClassTransformer.kt @@ -1,16 +1,15 @@ -package com.didichuxing.doraemonkit.plugin.classtransformer +package com.didichuxing.doraemonkit.plugin.transform.classtransform import com.didichuxing.doraemonkit.plugin.* -import com.didichuxing.doraemonkit.plugin.extension.SlowMethodExt +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.extension.SlowMethodExtension import com.didichuxing.doraemonkit.plugin.stack_method.MethodStackNode import com.didichuxing.doraemonkit.plugin.stack_method.MethodStackNodeUtil -import com.didiglobal.booster.annotations.Priority import com.didiglobal.booster.transform.TransformContext -import com.didiglobal.booster.transform.asm.ClassTransformer import com.didiglobal.booster.transform.asm.asIterable import com.didiglobal.booster.transform.asm.className -import com.google.auto.service.AutoService -import org.objectweb.asm.Opcodes.* +import org.gradle.api.Project +import org.objectweb.asm.Opcodes import org.objectweb.asm.tree.* /** @@ -20,31 +19,25 @@ import org.objectweb.asm.tree.* * 创建日期:2020/5/14-18:07 * 描 述:入口函数 慢函数调用栈 wiki:https://juejin.im/post/5e8d87c4f265da47ad218e6b * 修订历史:不要指定自动注入 需要手动在DoKitAsmTransformer中通过配置创建 - * 原理:transform()方法的调用是无序的 原因:哪一个class会先被transformer执行是不确定的 但是每一个class被transformer执行顺序是遵循transformer的Priority规则的 + * + * 原理:transform()方法的调用是无序的 + * 原因:哪一个class会先被transformer执行是不确定的 但是每一个class被transformer执行顺序是遵循transformer的Priority规则的 * ================================================ + * + * 入口函数 慢函数调用栈 + * */ -//@Priority(3) -//@AutoService(ClassTransformer::class) class EnterMSClassTransformer : AbsClassTransformer() { private val thresholdTime = DoKitExtUtil.slowMethodExt.stackMethod.thresholdTime private val level = 0 - override fun transform(context: TransformContext, klass: ClassNode): ClassNode { - - - if (onCommInterceptor(context, klass)) { - return klass - } + override fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode { if (!DoKitExtUtil.dokitSlowMethodSwitchOpen()) { return klass } - if (DoKitExtUtil.SLOW_METHOD_STRATEGY == SlowMethodExt.STRATEGY_NORMAL) { - return klass - } - - if (DoKitExtUtil.ignorePackageNames(klass.className)) { + if (DoKitExtUtil.SLOW_METHOD_STRATEGY == SlowMethodExtension.STRATEGY_NORMAL) { return klass } @@ -121,26 +114,26 @@ class EnterMSClassTransformer : AbsClassTransformer() { desc: String, access: Int ): InsnList { - val isStaticMethod = access and ACC_STATIC != 0 + val isStaticMethod = access and Opcodes.ACC_STATIC != 0 return with(InsnList()) { if (isStaticMethod) { add( FieldInsnNode( - GETSTATIC, + Opcodes.GETSTATIC, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "INSTANCE", "Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;" ) ) - add(IntInsnNode(BIPUSH, DoKitExtUtil.STACK_METHOD_LEVEL)) - add(IntInsnNode(BIPUSH, thresholdTime)) - add(IntInsnNode(BIPUSH, level)) + add(IntInsnNode(Opcodes.BIPUSH, DoKitExtUtil.STACK_METHOD_LEVEL)) + add(IntInsnNode(Opcodes.BIPUSH, thresholdTime)) + add(IntInsnNode(Opcodes.BIPUSH, level)) add(LdcInsnNode(className)) add(LdcInsnNode(methodName)) add(LdcInsnNode(desc)) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "recodeStaticMethodCostStart", "(IIILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", @@ -150,22 +143,22 @@ class EnterMSClassTransformer : AbsClassTransformer() { } else { add( FieldInsnNode( - GETSTATIC, + Opcodes.GETSTATIC, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "INSTANCE", "Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;" ) ) - add(IntInsnNode(BIPUSH, DoKitExtUtil.STACK_METHOD_LEVEL)) - add(IntInsnNode(BIPUSH, thresholdTime)) - add(IntInsnNode(BIPUSH, level)) + add(IntInsnNode(Opcodes.BIPUSH, DoKitExtUtil.STACK_METHOD_LEVEL)) + add(IntInsnNode(Opcodes.BIPUSH, thresholdTime)) + add(IntInsnNode(Opcodes.BIPUSH, level)) add(LdcInsnNode(className)) add(LdcInsnNode(methodName)) add(LdcInsnNode(desc)) - add(VarInsnNode(ALOAD, 0)) + add(VarInsnNode(Opcodes.ALOAD, 0)) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "recodeObjectMethodCostStart", "(IIILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V", @@ -190,26 +183,26 @@ class EnterMSClassTransformer : AbsClassTransformer() { desc: String, access: Int ): InsnList { - val isStaticMethod = access and ACC_STATIC != 0 + val isStaticMethod = access and Opcodes.ACC_STATIC != 0 return with(InsnList()) { if (isStaticMethod) { add( FieldInsnNode( - GETSTATIC, + Opcodes.GETSTATIC, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "INSTANCE", "Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;" ) ) - add(IntInsnNode(BIPUSH, thresholdTime)) - add(IntInsnNode(BIPUSH, level)) + add(IntInsnNode(Opcodes.BIPUSH, thresholdTime)) + add(IntInsnNode(Opcodes.BIPUSH, level)) add(LdcInsnNode(className)) add(LdcInsnNode(methodName)) add(LdcInsnNode(desc)) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "recodeStaticMethodCostEnd", "(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", @@ -219,21 +212,21 @@ class EnterMSClassTransformer : AbsClassTransformer() { } else { add( FieldInsnNode( - GETSTATIC, + Opcodes.GETSTATIC, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "INSTANCE", "Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;" ) ) - add(IntInsnNode(BIPUSH, thresholdTime)) - add(IntInsnNode(BIPUSH, level)) + add(IntInsnNode(Opcodes.BIPUSH, thresholdTime)) + add(IntInsnNode(Opcodes.BIPUSH, level)) add(LdcInsnNode(className)) add(LdcInsnNode(methodName)) add(LdcInsnNode(desc)) - add(VarInsnNode(ALOAD, 0)) + add(VarInsnNode(Opcodes.ALOAD, 0)) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "recodeObjectMethodCostEnd", "(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V", @@ -247,4 +240,3 @@ class EnterMSClassTransformer : AbsClassTransformer() { } } - diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GPSAMapClassTransformer.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GPSAMapClassTransformer.kt new file mode 100644 index 000000000..8bdc5fc81 --- /dev/null +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GPSAMapClassTransformer.kt @@ -0,0 +1,250 @@ +package com.didichuxing.doraemonkit.plugin.transform.classtransform + +import com.didichuxing.doraemonkit.plugin.DoKitExtUtil +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.lastPath +import com.didichuxing.doraemonkit.plugin.println +import com.didiglobal.booster.transform.TransformContext +import com.didiglobal.booster.transform.asm.className +import org.gradle.api.Project +import org.objectweb.asm.Opcodes +import org.objectweb.asm.tree.* + + +/** + * didi Create on 2023/3/21 . + * + * Copyright (c) 2023/3/21 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/21 3:06 下午 + * @Description 高德地图 hooks + */ + +class GPSAMapClassTransformer : AbsClassTransformer() { + + override fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode { + val className = klass.className + + if (dokit.gpsEnable && dokit.gps.amap && DoKitExtUtil.DOKIT_GPS_MOCK_INCLUDE) { + //插入高德地图定位相关字节码 + if (className == "com.amap.api.location.AMapLocationClient") { + //设置监听器 + klass.methods?.find { + it.name == "setLocationListener" + }.let { methodNode -> + "${context.projectDir.lastPath()}->hook amap map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() + methodNode?.instructions?.insert(createAmapLocationInsnList()) + } + //反注册监听器 + klass.methods?.find { + it.name == "unRegisterLocationListener" + }.let { methodNode -> + "${context.projectDir.lastPath()}->hook amap map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() + methodNode?.instructions?.insert( + createAmapLocationUnRegisterInsnList() + ) + } + //代理getLastKnownLocation + klass.methods?.find { + it.name == "getLastKnownLocation" + }.let { methodNode -> + "${context.projectDir.lastPath()}->hook AMapLocationClient getLastKnownLocation succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() + methodNode?.instructions?.insert(createAMapClientLastKnownLocation()) + } + + } +// //插入高德 地图定位相关字节码 +// if (className == "com.amap.api.maps.AMap") { +// //设置LocationSource代理 +// klass.methods?.find { +// it.name == "setLocationSource" +// }.let { methodNode -> +// "${context.projectDir.lastPath()}->hook amap map LocationSource succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() +// methodNode?.instructions?.insert(createAmapLocationSourceInsnList()) +// } +// } + + //插入高德地图导航相关字节码 + if (className == "com.amap.api.navi.AMapNavi") { + //设置监听器 + klass.methods?.find { + it.name == "addAMapNaviListener" + }.let { methodNode -> + "${context.projectDir.lastPath()}->hook amap map navi succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() + methodNode?.instructions?.insert(createAmapNaviInsnList()) + } + //反注册监听器 + klass.methods?.find { + it.name == "removeAMapNaviListener" + }.let { methodNode -> + "${context.projectDir.lastPath()}->hook amap map navi succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() + methodNode?.instructions?.insert( + createAmapNaviUnRegisterInsnList() + ) + } + } + } + return klass + } + + /** + * 创建Amap地图代码指令 + */ + private fun createAmapLocationInsnList(): InsnList { + return with(InsnList()) { + //在AMapLocationClient的 setLocationListener 方法之中插入自定义代理回调类 + add( + TypeInsnNode( + Opcodes.NEW, + "com/didichuxing/doraemonkit/gps_mock/map/AMapLocationListenerProxy" + ) + ) + add(InsnNode(Opcodes.DUP)) + //访问第一个参数 + add(VarInsnNode(Opcodes.ALOAD, 1)) + add( + MethodInsnNode( + Opcodes.INVOKESPECIAL, + "com/didichuxing/doraemonkit/gps_mock/map/AMapLocationListenerProxy", + "", + "(Lcom/amap/api/location/AMapLocationListener;)V", + false + ) + ) + //对第一个参数进行重新赋值 + add(VarInsnNode(Opcodes.ASTORE, 1)) + this + } + + } + + /** + * 创建Amap地图导航代码指令 + */ + private fun createAmapNaviInsnList(): InsnList { + return with(InsnList()) { + //在AMapNavi的addAMapNaviListener方法之中插入自定义代理回调类 + add( + TypeInsnNode( + Opcodes.NEW, + "com/didichuxing/doraemonkit/gps_mock/map/AMapNaviListenerProxy" + ) + ) + add(InsnNode(Opcodes.DUP)) + //访问第一个参数 + add(VarInsnNode(Opcodes.ALOAD, 1)) + add( + MethodInsnNode( + Opcodes.INVOKESPECIAL, + "com/didichuxing/doraemonkit/gps_mock/map/AMapNaviListenerProxy", + "", + "(Lcom/amap/api/navi/AMapNaviListener;)V", + false + ) + ) + //对第一个参数进行重新赋值 + add(VarInsnNode(Opcodes.ASTORE, 1)) + this + } + + } + + + /** + * 创建Amap LocationSource代码指令 + */ + private fun createAmapLocationSourceInsnList(): InsnList { + return with(InsnList()) { + //在AMapNavi的addAMapNaviListener方法之中插入自定义代理回调类 + add( + TypeInsnNode( + Opcodes.NEW, + "com/didichuxing/doraemonkit/gps_mock/map/AMapLocationSourceProxy" + ) + ) + add(InsnNode(Opcodes.DUP)) + //访问第一个参数 + add(VarInsnNode(Opcodes.ALOAD, 1)) + add( + MethodInsnNode( + Opcodes.INVOKESPECIAL, + "com/didichuxing/doraemonkit/gps_mock/map/AMapLocationSourceProxy", + "", + "(Lcom/amap/api/maps/LocationSource;)V", + false + ) + ) + //对第一个参数进行重新赋值 + add(VarInsnNode(Opcodes.ASTORE, 1)) + this + } + + } + + /** + * 创建AMapLocationClient#LastKnownLocation 字节码替换 + */ + private fun createAMapClientLastKnownLocation(): InsnList { + return with(InsnList()) { + add(VarInsnNode(Opcodes.ALOAD, 0)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/gps_mock/map/AMapLocationClientProxy", + "getLastKnownLocation", + "(Lcom/amap/api/location/AMapLocationClient;)Lcom/amap/api/location/AMapLocation;", + false + ) + ) + add(InsnNode(Opcodes.ARETURN)) + this + } + + } + + /** + * 创建Amap地图UnRegister代码指令 + */ + private fun createAmapLocationUnRegisterInsnList(): InsnList { + return with(InsnList()) { + //访问第一个参数 + add(VarInsnNode(Opcodes.ALOAD, 1)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/gps_mock/map/ThirdMapLocationListenerUtil", + "unRegisterAmapLocationListener", + "(Lcom/amap/api/location/AMapLocationListener;)Lcom/didichuxing/doraemonkit/gps_mock/map/AMapLocationListenerProxy;", + false + ) + ) + add(VarInsnNode(Opcodes.ASTORE, 1)) + this + } + } + + /** + * 创建Amap地图 Navi UnRegister代码指令 + */ + private fun createAmapNaviUnRegisterInsnList(): InsnList { + return with(InsnList()) { + //访问第一个参数 + add(VarInsnNode(Opcodes.ALOAD, 1)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/gps_mock/map/ThirdMapLocationListenerUtil", + "unRegisterAmapNaviListener", + "(Lcom/amap/api/navi/AMapNaviListener;)Lcom/didichuxing/doraemonkit/gps_mock/map/AMapNaviListenerProxy;", + false + ) + ) + add(VarInsnNode(Opcodes.ASTORE, 1)) + this + } + + } + +} diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GPSBDClassTransformer.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GPSBDClassTransformer.kt new file mode 100644 index 000000000..2b25126c5 --- /dev/null +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GPSBDClassTransformer.kt @@ -0,0 +1,197 @@ +package com.didichuxing.doraemonkit.plugin.transform.classtransform + +import com.didichuxing.doraemonkit.plugin.DoKitExtUtil +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.lastPath +import com.didichuxing.doraemonkit.plugin.println +import com.didiglobal.booster.transform.TransformContext +import com.didiglobal.booster.transform.asm.className +import org.gradle.api.Project +import org.objectweb.asm.Opcodes +import org.objectweb.asm.tree.* + + +/** + * didi Create on 2023/3/21 . + * + * Copyright (c) 2023/3/21 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/21 3:06 下午 + * @Description 百度地图 hooks + */ + +class GPSBDClassTransformer : AbsClassTransformer() { + + override fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode { + val className = klass.className + + if (dokit.gpsEnable && dokit.gps.baidu && DoKitExtUtil.DOKIT_GPS_MOCK_INCLUDE) { + //插入百度地图相关字节码 + if (className == "com.baidu.location.LocationClient") { + //拦截注册监听器 + klass.methods?.filter { + it.name == "registerLocationListener" + && (it.desc == "(Lcom/baidu/location/BDLocationListener;)V" || it.desc == "(Lcom/baidu/location/BDAbstractLocationListener;)V") + }?.forEach { methodNode -> + "${context.projectDir.lastPath()}->hook baidu map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() + if (methodNode.desc == "(Lcom/baidu/location/BDLocationListener;)V") { + methodNode?.instructions?.insert(createBDLocationListenerInsnList()) + } else if (methodNode.desc == "(Lcom/baidu/location/BDAbstractLocationListener;)V") { + methodNode?.instructions?.insert(createBDLocationAbsListenerInsnList()) + } + } + //反注册监听器 + klass.methods?.find { + it.name == "unRegisterLocationListener" && it.desc == "(Lcom/baidu/location/BDLocationListener;)V" + }.let { methodNode -> + "${context.projectDir.lastPath()}->hook baidu map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() + methodNode?.instructions?.insert( + createBDLocationUnRegisterInsnList() + ) + } + //反注册监听器 + klass.methods?.find { + it.name == "unRegisterLocationListener" && it.desc == "(Lcom/baidu/location/BDAbstractLocationListener;)V" + }.let { methodNode -> + "${context.projectDir.lastPath()}->hook baidu map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() + methodNode?.instructions?.insert( + createBDAbsLocationUnRegisterInsnList() + ) + } + } + } + return klass + } + + /** + * 创建百度地图代码指令 + */ + private fun createBDLocationListenerInsnList(): InsnList { + return with(InsnList()) { + //在LocationClient的registerLocationListener方法之中插入自定义代理回调类 + add( + TypeInsnNode( + Opcodes.NEW, + "com/didichuxing/doraemonkit/gps_mock/map/BDLocationListenerProxy" + ) + ) + add(InsnNode(Opcodes.DUP)) + //访问第一个参数 + add(VarInsnNode(Opcodes.ALOAD, 1)) + add( + MethodInsnNode( + Opcodes.INVOKESPECIAL, + "com/didichuxing/doraemonkit/gps_mock/map/BDLocationListenerProxy", + "", + "(Lcom/baidu/location/BDLocationListener;)V", + false + ) + ) + //对第一个参数进行重新赋值 + add(VarInsnNode(Opcodes.ASTORE, 1)) + + this + } + + } + + /** + * 创建百度地图代码指令 + */ + private fun createBDLocationAbsListenerInsnList(): InsnList { + return with(InsnList()) { + //在LocationClient的registerLocationListener方法之中插入自定义代理回调类 + add( + TypeInsnNode( + Opcodes.NEW, + "com/didichuxing/doraemonkit/gps_mock/map/BDAbsLocationListenerProxy" + ) + ) + add(InsnNode(Opcodes.DUP)) + //访问第一个参数 + add(VarInsnNode(Opcodes.ALOAD, 1)) + add( + MethodInsnNode( + Opcodes.INVOKESPECIAL, + "com/didichuxing/doraemonkit/gps_mock/map/BDAbsLocationListenerProxy", + "", + "(Lcom/baidu/location/BDAbstractLocationListener;)V", + false + ) + ) + //对第一个参数进行重新赋值 + add(VarInsnNode(Opcodes.ASTORE, 1)) + this + } + } + + /** + * 创建百度地图UnRegister代码指令 + */ + private fun createBDLocationUnRegisterInsnList(): InsnList { + return with(InsnList()) { + //访问第一个参数 + add(VarInsnNode(Opcodes.ALOAD, 1)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/gps_mock/map/ThirdMapLocationListenerUtil", + "unRegisterBDLocationListener", + "(Lcom/baidu/location/BDLocationListener;)Lcom/didichuxing/doraemonkit/gps_mock/map/BDLocationListenerProxy;", + false + ) + ) + add(VarInsnNode(Opcodes.ASTORE, 1)) + this + } + + } + + /** + * 创建百度地图UnRegister代码指令 + */ + private fun createBDAbsLocationUnRegisterInsnList(): InsnList { + return with(InsnList()) { + //访问第一个参数 + add(VarInsnNode(Opcodes.ALOAD, 1)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/gps_mock/map/ThirdMapLocationListenerUtil", + "unRegisterBDLocationListener", + "(Lcom/baidu/location/BDAbstractLocationListener;)Lcom/didichuxing/doraemonkit/gps_mock/map/BDAbsLocationListenerProxy;", + false + ) + ) + //对第一个参数进行重新赋值 + add(VarInsnNode(Opcodes.ASTORE, 1)) + this + } + + } + + /** + * 创建百度地图代码指令 + */ + private fun createBaiduLocationInsnList(): InsnList { + return with(InsnList()) { + //在AMapLocationClient的setLocationListener方法之中插入自定义代理回调类 + add(VarInsnNode(Opcodes.ALOAD, 1)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/gps_mock/map/BDLocationUtil", + "proxy", + "(Lcom/baidu/location/BDLocation;)Lcom/baidu/location/BDLocation;", + false + ) + ) + //对第一个参数进行重新赋值 + add(VarInsnNode(Opcodes.ASTORE, 1)) + this + } + + } +} diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GPSClassTransformer.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GPSClassTransformer.kt new file mode 100644 index 000000000..51f7037f2 --- /dev/null +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GPSClassTransformer.kt @@ -0,0 +1,61 @@ +package com.didichuxing.doraemonkit.plugin.transform.classtransform + +import com.didichuxing.doraemonkit.plugin.DoKitExtUtil +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.lastPath +import com.didichuxing.doraemonkit.plugin.println +import com.didiglobal.booster.kotlinx.asIterable +import com.didiglobal.booster.transform.TransformContext +import com.didiglobal.booster.transform.asm.className +import org.gradle.api.Project +import org.objectweb.asm.Opcodes +import org.objectweb.asm.tree.ClassNode +import org.objectweb.asm.tree.MethodInsnNode + + +/** + * didi Create on 2023/3/21 . + * + * Copyright (c) 2023/3/21 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/21 3:06 下午 + * @Description 系统定位hooks + */ + +class GPSClassTransformer : AbsClassTransformer() { + + override fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode { + val className = klass.className + + //gps字节码操作 + if (dokit.gpsEnable && dokit.gps.local && DoKitExtUtil.DOKIT_GPS_MOCK_INCLUDE) { + //系统 gpsStatus hook + klass.methods.forEach { method -> + method.instructions?.iterator()?.asIterable() + ?.filterIsInstance(MethodInsnNode::class.java)?.filter { + it.opcode == Opcodes.INVOKEVIRTUAL && + it.owner == "android/location/LocationManager" && + it.name == "getGpsStatus" && + it.desc == "(Landroid/location/GpsStatus;)Landroid/location/GpsStatus;" + }?.forEach { + "${context.projectDir.lastPath()}->hook LocationManager#getGpsStatus method succeed in : ${className}_${method.name}_${method.desc}".println() + method.instructions.insert( + it, + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/gps_mock/location/GpsStatusUtil", + "wrap", + "(Landroid/location/GpsStatus;)Landroid/location/GpsStatus;", + false + ) + ) + } + } + } + return klass + } + + +} diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GPSTencentClassTransformer.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GPSTencentClassTransformer.kt new file mode 100644 index 000000000..e90d29e52 --- /dev/null +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GPSTencentClassTransformer.kt @@ -0,0 +1,110 @@ +package com.didichuxing.doraemonkit.plugin.transform.classtransform + +import com.didichuxing.doraemonkit.plugin.DoKitExtUtil +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.lastPath +import com.didichuxing.doraemonkit.plugin.println +import com.didiglobal.booster.transform.TransformContext +import com.didiglobal.booster.transform.asm.className +import org.gradle.api.Project +import org.objectweb.asm.Opcodes +import org.objectweb.asm.tree.* + + +/** + * didi Create on 2023/3/21 . + * + * Copyright (c) 2023/3/21 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/21 3:06 下午 + * @Description 腾讯地图 hooks + */ + +class GPSTencentClassTransformer : AbsClassTransformer() { + + override fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode { + val className = klass.className + + if (dokit.gpsEnable && dokit.gps.tencent && DoKitExtUtil.DOKIT_GPS_MOCK_INCLUDE) { + //插入腾讯地图相关字节码 + if (className == "com.tencent.map.geolocation.TencentLocationManager") { + //持续定位和单次定位 + klass.methods?.filter { + it.name == "requestSingleFreshLocation" || it.name == "requestLocationUpdates" + }?.forEach { methodNode -> + "${context.projectDir.lastPath()}->hook tencent map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() + methodNode?.instructions?.insert(createTencentLocationInsnList()) + } + + //反注册监听器 + klass.methods?.find { + it.name == "removeUpdates" + }.let { methodNode -> + "${context.projectDir.lastPath()}->hook tencent map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() + methodNode?.instructions?.insert( + createTencentLocationUnRegisterInsnList() + ) + } + } + } + return klass + } + + /** + * 创建tencent地图代码指令 + */ + private fun createTencentLocationInsnList(): InsnList { + return with(InsnList()) { + //在AMapLocationClient的setLocationListener方法之中插入自定义代理回调类 + add( + TypeInsnNode( + Opcodes.NEW, + "com/didichuxing/doraemonkit/gps_mock/map/TencentLocationListenerProxy" + ) + ) + add(InsnNode(Opcodes.DUP)) + //访问第一个参数 + add(VarInsnNode(Opcodes.ALOAD, 2)) + add( + MethodInsnNode( + Opcodes.INVOKESPECIAL, + "com/didichuxing/doraemonkit/gps_mock/map/TencentLocationListenerProxy", + "", + "(Lcom/tencent/map/geolocation/TencentLocationListener;)V", + false + ) + ) + //对第二个参数进行重新赋值 + add(VarInsnNode(Opcodes.ASTORE, 2)) + + this + } + + } + + /** + * 创建Tencent地图UnRegister代码指令 + */ + private fun createTencentLocationUnRegisterInsnList(): InsnList { + return with(InsnList()) { + //访问第一个参数 + add(VarInsnNode(Opcodes.ALOAD, 1)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/gps_mock/map/ThirdMapLocationListenerUtil", + "unRegisterTencentLocationListener", + "(Lcom/tencent/map/geolocation/TencentLocationListener;)Lcom/didichuxing/doraemonkit/gps_mock/map/TencentLocationListenerProxy;", + false + ) + ) + add(VarInsnNode(Opcodes.ASTORE, 1)) + this + } + + } + + +} diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/GSMClassTransformer.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GSMClassTransformer.kt similarity index 79% rename from Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/GSMClassTransformer.kt rename to Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GSMClassTransformer.kt index e6f4a857b..b0d21c920 100644 --- a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/GSMClassTransformer.kt +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GSMClassTransformer.kt @@ -1,14 +1,13 @@ -package com.didichuxing.doraemonkit.plugin.classtransformer +package com.didichuxing.doraemonkit.plugin.transform.classtransform import com.didichuxing.doraemonkit.plugin.* -import com.didichuxing.doraemonkit.plugin.extension.SlowMethodExt -import com.didiglobal.booster.annotations.Priority +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.extension.SlowMethodExtension import com.didiglobal.booster.transform.TransformContext -import com.didiglobal.booster.transform.asm.ClassTransformer import com.didiglobal.booster.transform.asm.asIterable import com.didiglobal.booster.transform.asm.className -import com.google.auto.service.AutoService -import org.objectweb.asm.Opcodes.* +import org.gradle.api.Project +import org.objectweb.asm.Opcodes import org.objectweb.asm.tree.* /** @@ -16,25 +15,26 @@ import org.objectweb.asm.tree.* * 作 者:jint(金台) * 版 本:1.0 * 创建日期:2020/5/14-18:07 - * 描 述:全局慢函数业务代码慢函数 wiki:https://juejin.im/post/5e8d87c4f265da47ad218e6b + * 描 述: + * 全局慢函数业务代码慢函数 + * wiki:https://juejin.im/post/5e8d87c4f265da47ad218e6b + * * 修订历史: * ================================================ + * + * 全局慢函数 + * */ -//@Priority(2) -//@AutoService(ClassTransformer::class) class GSMClassTransformer : AbsClassTransformer() { val thresholdTime = DoKitExtUtil.slowMethodExt.normalMethod.thresholdTime - override fun transform(context: TransformContext, klass: ClassNode): ClassNode { - if (onCommInterceptor(context, klass)) { - return klass - } + override fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode { if (!DoKitExtUtil.dokitSlowMethodSwitchOpen()) { return klass } - if (DoKitExtUtil.SLOW_METHOD_STRATEGY == SlowMethodExt.STRATEGY_STACK) { + if (DoKitExtUtil.SLOW_METHOD_STRATEGY == SlowMethodExtension.STRATEGY_STACK) { return klass } @@ -50,10 +50,10 @@ class GSMClassTransformer : AbsClassTransformer() { if (className.contains(packageName) && notMatchedBlackList(className)) { klass.methods.filter { methodNode -> methodNode.name != "" && - !methodNode.isEmptyMethod() && - !methodNode.isSingleMethod() && - !methodNode.isGetSetMethod() && - !methodNode.isMainMethod(className) + !methodNode.isEmptyMethod() && + !methodNode.isSingleMethod() && + !methodNode.isGetSetMethod() && + !methodNode.isMainMethod(className) }.forEach { methodNode -> methodNode.instructions.asIterable() .filterIsInstance(MethodInsnNode::class.java).let { methodInsnNodes -> @@ -105,22 +105,22 @@ class GSMClassTransformer : AbsClassTransformer() { methodName: String, access: Int ): InsnList { - val isStaticMethod = access and ACC_STATIC != 0 + val isStaticMethod = access and Opcodes.ACC_STATIC != 0 return with(InsnList()) { if (isStaticMethod) { add( FieldInsnNode( - GETSTATIC, + Opcodes.GETSTATIC, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "INSTANCE", "Lcom/didichuxing/doraemonkit/aop/MethodCostUtil;" ) ) - add(IntInsnNode(SIPUSH, thresholdTime)) + add(IntInsnNode(Opcodes.SIPUSH, thresholdTime)) add(LdcInsnNode("$className&$methodName")) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "recodeStaticMethodCostStart", "(ILjava/lang/String;)V", @@ -130,18 +130,18 @@ class GSMClassTransformer : AbsClassTransformer() { } else { add( FieldInsnNode( - GETSTATIC, + Opcodes.GETSTATIC, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "INSTANCE", "Lcom/didichuxing/doraemonkit/aop/MethodCostUtil;" ) ) - add(IntInsnNode(SIPUSH, thresholdTime)) + add(IntInsnNode(Opcodes.SIPUSH, thresholdTime)) add(LdcInsnNode("$className&$methodName")) - add(VarInsnNode(ALOAD, 0)) + add(VarInsnNode(Opcodes.ALOAD, 0)) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "recodeObjectMethodCostStart", "(ILjava/lang/String;Ljava/lang/Object;)V", @@ -164,22 +164,22 @@ class GSMClassTransformer : AbsClassTransformer() { methodName: String, access: Int ): InsnList { - val isStaticMethod = access and ACC_STATIC != 0 + val isStaticMethod = access and Opcodes.ACC_STATIC != 0 return with(InsnList()) { if (isStaticMethod) { add( FieldInsnNode( - GETSTATIC, + Opcodes.GETSTATIC, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "INSTANCE", "Lcom/didichuxing/doraemonkit/aop/MethodCostUtil;" ) ) - add(IntInsnNode(SIPUSH, thresholdTime)) + add(IntInsnNode(Opcodes.SIPUSH, thresholdTime)) add(LdcInsnNode("$className&$methodName")) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "recodeStaticMethodCostEnd", "(ILjava/lang/String;)V", @@ -189,18 +189,18 @@ class GSMClassTransformer : AbsClassTransformer() { } else { add( FieldInsnNode( - GETSTATIC, + Opcodes.GETSTATIC, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "INSTANCE", "Lcom/didichuxing/doraemonkit/aop/MethodCostUtil;" ) ) - add(IntInsnNode(SIPUSH, thresholdTime)) + add(IntInsnNode(Opcodes.SIPUSH, thresholdTime)) add(LdcInsnNode("$className&$methodName")) - add(VarInsnNode(ALOAD, 0)) + add(VarInsnNode(Opcodes.ALOAD, 0)) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "recodeObjectMethodCostEnd", "(ILjava/lang/String;Ljava/lang/Object;)V", @@ -214,4 +214,3 @@ class GSMClassTransformer : AbsClassTransformer() { } - diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/MSDClassTransformer.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/MSDClassTransformer.kt similarity index 79% rename from Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/MSDClassTransformer.kt rename to Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/MSDClassTransformer.kt index 07954979b..b4bdc2c6b 100644 --- a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/MSDClassTransformer.kt +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/MSDClassTransformer.kt @@ -1,14 +1,15 @@ -package com.didichuxing.doraemonkit.plugin.classtransformer +package com.didichuxing.doraemonkit.plugin.transform.classtransform import com.didichuxing.doraemonkit.plugin.* -import com.didichuxing.doraemonkit.plugin.extension.SlowMethodExt +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.extension.SlowMethodExtension import com.didichuxing.doraemonkit.plugin.stack_method.MethodStackNode import com.didichuxing.doraemonkit.plugin.stack_method.MethodStackNodeUtil import com.didiglobal.booster.transform.TransformContext -import com.didiglobal.booster.transform.asm.ClassTransformer import com.didiglobal.booster.transform.asm.asIterable import com.didiglobal.booster.transform.asm.className -import org.objectweb.asm.Opcodes.* +import org.gradle.api.Project +import org.objectweb.asm.Opcodes import org.objectweb.asm.tree.* /** @@ -18,23 +19,21 @@ import org.objectweb.asm.tree.* * 创建日期:2020/5/14-18:07 * 描 述:函数调用栈依赖 慢函数调用栈 wiki:https://juejin.im/post/5e8d87c4f265da47ad218e6b * 修订历史:不要指定自动注入 需要手动在DoKitAsmTransformer中通过配置创建 - * 原理:transform()方法的调用是无序的 原因:哪一个class会先被transformer执行是不确定的 但是每一个class被transformer执行顺序是遵循transformer的Priority规则的 + * + * 原理:transform()方法的调用是无序的 + * 原因:哪一个class会先被transformer执行是不确定的 但是每一个class被transformer执行顺序是遵循transformer的Priority规则的 * ================================================ */ class MSDClassTransformer(private val level: Int = 1) : AbsClassTransformer() { private val thresholdTime = DoKitExtUtil.slowMethodExt.stackMethod.thresholdTime - override fun transform(context: TransformContext, klass: ClassNode): ClassNode { - if (onCommInterceptor(context, klass)) { - return klass - } - + override fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode { if (!DoKitExtUtil.dokitSlowMethodSwitchOpen()) { return klass } - if (DoKitExtUtil.SLOW_METHOD_STRATEGY == SlowMethodExt.STRATEGY_NORMAL) { + if (DoKitExtUtil.SLOW_METHOD_STRATEGY == SlowMethodExtension.STRATEGY_NORMAL) { return klass } @@ -52,10 +51,10 @@ class MSDClassTransformer(private val level: Int = 1) : AbsClassTransformer() { klass.methods.filter { methodNode -> methodNode.name != "" && - !methodNode.isEmptyMethod() && - !methodNode.isSingleMethod() && - !methodNode.isGetSetMethod() && - !methodNode.isMainMethod(klass.className) + !methodNode.isEmptyMethod() && + !methodNode.isSingleMethod() && + !methodNode.isGetSetMethod() && + !methodNode.isMainMethod(klass.className) }.forEach { methodNode -> val key = "${klass.className}&${methodNode.name}&${methodNode.desc}" if (methodStackKeys.contains(key)) { @@ -123,26 +122,26 @@ class MSDClassTransformer(private val level: Int = 1) : AbsClassTransformer() { desc: String, access: Int ): InsnList { - val isStaticMethod = access and ACC_STATIC != 0 + val isStaticMethod = access and Opcodes.ACC_STATIC != 0 return with(InsnList()) { if (isStaticMethod) { add( FieldInsnNode( - GETSTATIC, + Opcodes.GETSTATIC, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "INSTANCE", "Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;" ) ) - add(IntInsnNode(BIPUSH, DoKitExtUtil.STACK_METHOD_LEVEL)) - add(IntInsnNode(BIPUSH, thresholdTime)) - add(IntInsnNode(BIPUSH, level)) + add(IntInsnNode(Opcodes.BIPUSH, DoKitExtUtil.STACK_METHOD_LEVEL)) + add(IntInsnNode(Opcodes.BIPUSH, thresholdTime)) + add(IntInsnNode(Opcodes.BIPUSH, level)) add(LdcInsnNode(className)) add(LdcInsnNode(methodName)) add(LdcInsnNode(desc)) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "recodeStaticMethodCostStart", "(IIILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", @@ -152,22 +151,22 @@ class MSDClassTransformer(private val level: Int = 1) : AbsClassTransformer() { } else { add( FieldInsnNode( - GETSTATIC, + Opcodes.GETSTATIC, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "INSTANCE", "Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;" ) ) - add(IntInsnNode(BIPUSH, DoKitExtUtil.STACK_METHOD_LEVEL)) - add(IntInsnNode(BIPUSH, thresholdTime)) - add(IntInsnNode(BIPUSH, level)) + add(IntInsnNode(Opcodes.BIPUSH, DoKitExtUtil.STACK_METHOD_LEVEL)) + add(IntInsnNode(Opcodes.BIPUSH, thresholdTime)) + add(IntInsnNode(Opcodes.BIPUSH, level)) add(LdcInsnNode(className)) add(LdcInsnNode(methodName)) add(LdcInsnNode(desc)) - add(VarInsnNode(ALOAD, 0)) + add(VarInsnNode(Opcodes.ALOAD, 0)) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "recodeObjectMethodCostStart", "(IIILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V", @@ -191,25 +190,25 @@ class MSDClassTransformer(private val level: Int = 1) : AbsClassTransformer() { desc: String, access: Int ): InsnList { - val isStaticMethod = access and ACC_STATIC != 0 + val isStaticMethod = access and Opcodes.ACC_STATIC != 0 return with(InsnList()) { if (isStaticMethod) { add( FieldInsnNode( - GETSTATIC, + Opcodes.GETSTATIC, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "INSTANCE", "Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;" ) ) - add(IntInsnNode(BIPUSH, thresholdTime)) - add(IntInsnNode(BIPUSH, level)) + add(IntInsnNode(Opcodes.BIPUSH, thresholdTime)) + add(IntInsnNode(Opcodes.BIPUSH, level)) add(LdcInsnNode(className)) add(LdcInsnNode(methodName)) add(LdcInsnNode(desc)) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "recodeStaticMethodCostEnd", "(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", @@ -219,21 +218,21 @@ class MSDClassTransformer(private val level: Int = 1) : AbsClassTransformer() { } else { add( FieldInsnNode( - GETSTATIC, + Opcodes.GETSTATIC, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "INSTANCE", "Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;" ) ) - add(IntInsnNode(BIPUSH, thresholdTime)) - add(IntInsnNode(BIPUSH, level)) + add(IntInsnNode(Opcodes.BIPUSH, thresholdTime)) + add(IntInsnNode(Opcodes.BIPUSH, level)) add(LdcInsnNode(className)) add(LdcInsnNode(methodName)) add(LdcInsnNode(desc)) - add(VarInsnNode(ALOAD, 0)) + add(VarInsnNode(Opcodes.ALOAD, 0)) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "recodeObjectMethodCostEnd", "(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V", @@ -257,4 +256,3 @@ class MSDClassTransformer(private val level: Int = 1) : AbsClassTransformer() { } } - diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/Okhttp3ClassTransformer.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/Okhttp3ClassTransformer.kt new file mode 100644 index 000000000..e8526ed46 --- /dev/null +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/Okhttp3ClassTransformer.kt @@ -0,0 +1,75 @@ +package com.didichuxing.doraemonkit.plugin.transform.classtransform + +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.lastPath +import com.didichuxing.doraemonkit.plugin.println +import com.didiglobal.booster.kotlinx.asIterable +import com.didiglobal.booster.transform.TransformContext +import com.didiglobal.booster.transform.asm.className +import org.gradle.api.Project +import org.objectweb.asm.Opcodes +import org.objectweb.asm.tree.* + + +/** + * didi Create on 2023/3/21 . + * + * Copyright (c) 2023/3/21 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/21 3:06 下午 + * @Description 用一句话说明文件功能 + */ + +class Okhttp3ClassTransformer : AbsClassTransformer() { + + override fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode { + val className = klass.className + + if (dokit.networkEnable && dokit.network.okHttp) { + //hook OkhttpClient + if (className == "okhttp3.OkHttpClient") { + klass.methods?.find { + it.name == "" && it.desc != "()V" + }.let { + "${context.projectDir.lastPath()}->hook OkhttpClient succeed: ${className}_${it?.name}_${it?.desc}".println() + it?.instructions + ?.iterator() + ?.asIterable() + ?.filterIsInstance(FieldInsnNode::class.java) + ?.filter { fieldInsnNode -> + fieldInsnNode.opcode == Opcodes.PUTFIELD + && fieldInsnNode.owner == "okhttp3/OkHttpClient" + && fieldInsnNode.name == "networkInterceptors" + && fieldInsnNode.desc == "Ljava/util/List;" + }?.forEach { fieldInsnNode -> + it.instructions.insert(fieldInsnNode, createOkHttpClientInsnList()) + } + } + } + } + return klass + } + + /** + * 创建OkhttpClient一个数构造函数指令 + */ + private fun createOkHttpClientInsnList(): InsnList { + return with(InsnList()) { + //插入application 拦截器 + add(VarInsnNode(Opcodes.ALOAD, 0)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/aop/OkHttpHook", + "addDoKitIntercept", + "(Lokhttp3/OkHttpClient;)V", + false + ) + ) + this + } + + } +} diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/ThirdLibsClassTransformer.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/ThirdLibsClassTransformer.kt new file mode 100644 index 000000000..b24603419 --- /dev/null +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/ThirdLibsClassTransformer.kt @@ -0,0 +1,89 @@ +package com.didichuxing.doraemonkit.plugin.transform.classtransform + +import com.didichuxing.doraemonkit.plugin.DoKitExtUtil +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.lastPath +import com.didichuxing.doraemonkit.plugin.println +import com.didiglobal.booster.transform.TransformContext +import com.didiglobal.booster.transform.asm.className +import org.gradle.api.Project +import org.objectweb.asm.Opcodes +import org.objectweb.asm.tree.* + + +/** + * didi Create on 2023/3/21 . + * + * Copyright (c) 2023/3/21 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/21 3:06 下午 + * @Description 用一句话说明文件功能 + */ + +class ThirdLibsClassTransformer : AbsClassTransformer() { + + override fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode { + val className = klass.className + + if (dokit.thirdLibEnable) { + //查找DoraemonKitReal&pluginConfig方法并插入指定字节码 + if (className == "com.didichuxing.doraemonkit.DoKitReal") { + //三方库信息注入 + klass.methods?.find { + it.name == "initThirdLibraryInfo" + }.let { methodNode -> + "${context.projectDir.lastPath()}->insert map to the DoKitReal initThirdLibraryInfo succeed".println() + methodNode?.instructions?.insert(createThirdLibInfoInsnList()) + } + } + } + + return klass + } + + /** + * 创建pluginConfig代码指令 + */ + private fun createThirdLibInfoInsnList(): InsnList { + //val insnList = InsnList() + return with(InsnList()) { + //new HashMap + add(TypeInsnNode(Opcodes.NEW, "java/util/HashMap")) + add(InsnNode(Opcodes.DUP)) + add(MethodInsnNode(Opcodes.INVOKESPECIAL, "java/util/HashMap", "", "()V", false)) + //保存变量 + add(VarInsnNode(Opcodes.ASTORE, 0)) + DoKitExtUtil.THIRD_LIB_INFOS.forEach { thirdLibInfo -> + add(VarInsnNode(Opcodes.ALOAD, 0)) + add(LdcInsnNode(thirdLibInfo.variant)) + add(LdcInsnNode(thirdLibInfo.fileSize.toString())) + add( + MethodInsnNode( + Opcodes.INVOKEINTERFACE, + "java/util/Map", + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + false + ) + ) + add(InsnNode(Opcodes.POP)) + } + //将HashMap注入到DokitPluginConfig中 + add(VarInsnNode(Opcodes.ALOAD, 0)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/aop/DokitThirdLibInfo", + "inject", + "(Ljava/util/Map;)V", + false + ) + ) + this + } + } + + +} diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/UrlConnectionTransformer.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/UrlConnectionTransformer.kt new file mode 100644 index 000000000..bf151ae66 --- /dev/null +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/UrlConnectionTransformer.kt @@ -0,0 +1,54 @@ +package com.didichuxing.doraemonkit.plugin.transform.classtransform + +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.lastPath +import com.didichuxing.doraemonkit.plugin.println +import com.didiglobal.booster.kotlinx.asIterable +import com.didiglobal.booster.transform.TransformContext +import com.didiglobal.booster.transform.asm.className +import org.gradle.api.Project +import org.objectweb.asm.Opcodes +import org.objectweb.asm.tree.ClassNode +import org.objectweb.asm.tree.MethodInsnNode + +/** + * ================================================ + * 作 者:jint(金台) + * 版 本:1.0 + * 创建日期:2020/5/14-18:07 + * 描 述:wiki:https://juejin.im/post/5e8d87c4f265da47ad218e6b + * 修订历史: + * ================================================ + */ +class UrlConnectionTransformer : AbsClassTransformer() { + + private val SHADOW_URL = "com/didichuxing/doraemonkit/aop/urlconnection/HttpUrlConnectionProxyUtil" + + private val DESC = "(Ljava/net/URLConnection;)Ljava/net/URLConnection;" + + override fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode { + val className = klass.className + + if (dokit.networkEnable && dokit.network.urlConnect) { + // url connection + klass.methods.forEach { method -> + method.instructions?.iterator()?.asIterable() + ?.filterIsInstance(MethodInsnNode::class.java)?.filter { + it.opcode == Opcodes.INVOKEVIRTUAL && + it.owner == "java/net/URL" && + it.name == "openConnection" && + it.desc == "()Ljava/net/URLConnection;" + }?.forEach { + "${context.projectDir.lastPath()}->hook URL#openConnection method succeed in : ${className}_${method.name}_${method.desc}".println() + method.instructions.insert( + it, + MethodInsnNode(Opcodes.INVOKESTATIC, SHADOW_URL, "proxy", DESC, false) + ) + } + } + } + return klass + } + + +} diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/WebViewClassTransformer.kt b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/WebViewClassTransformer.kt new file mode 100644 index 000000000..d2929f1d1 --- /dev/null +++ b/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/WebViewClassTransformer.kt @@ -0,0 +1,137 @@ +package com.didichuxing.doraemonkit.plugin.transform.classtransform + +import com.didichuxing.doraemonkit.plugin.DoKitExtUtil +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.formatSuperName +import com.didichuxing.doraemonkit.plugin.lastPath +import com.didichuxing.doraemonkit.plugin.println +import com.didiglobal.booster.kotlinx.asIterable +import com.didiglobal.booster.transform.TransformContext +import com.didiglobal.booster.transform.asm.className +import org.gradle.api.Project +import org.objectweb.asm.Opcodes +import org.objectweb.asm.tree.* + + +/** + * didi Create on 2023/3/21 . + * + * Copyright (c) 2023/3/21 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/21 3:06 下午 + * @Description WebView hooks + */ + +class WebViewClassTransformer : AbsClassTransformer() { + + override fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode { + + val className = klass.className + val superName = klass.formatSuperName + + //网络 OkHttp&didi platform aop + if (dokit.webViewEnable) { + //webView 字节码操作 + if (dokit.webView.network) { + //普通的webview + klass.methods.forEach { method -> + method.instructions?.iterator()?.asIterable() + ?.filterIsInstance(MethodInsnNode::class.java)?.filter { + if ("loadUrl".equals(it.name)) { + "hook loadUrl() all ${className} ^${superName}^${it.owner} :: ${it.name} , ${it.desc} ,${it.opcode}".println() + } + (it.opcode == Opcodes.INVOKEVIRTUAL || it.opcode == Opcodes.INVOKESPECIAL) + && it.name == "loadUrl" + && (it.desc == "(Ljava/lang/String;)V" || it.desc == "(Ljava/lang/String;Ljava/util/Map;)V") + && isWebViewOwnerNameMatched(it.owner) + }?.forEach { + "${context.projectDir.lastPath()}->hook WebView#loadurl method succeed in : ${className}_${method.name}_${method.desc} | ${it.owner}".println() + if (it.desc == "(Ljava/lang/String;)V") { + method.instructions.insertBefore(it, createWebViewInsnList()) + } else { + method.instructions.insertBefore(it, createWebViewInsnList(method)) + } + } + } + } + } + return klass + } + + + private fun isWebViewOwnerNameMatched(ownerName: String): Boolean { + return ownerName == "android/webkit/WebView" || + ownerName == "com/tencent/smtt/sdk/WebView" || + ownerName.contentEquals("WebView") || + ownerName == DoKitExtUtil.WEBVIEW_CLASS_NAME + } + + + /** + * 创建webView函数指令集 + * 参考:https://www.jianshu.com/p/7d623f441bed + */ + private fun createWebViewInsnList(): InsnList { + return with(InsnList()) { + //复制栈顶的2个指令 指令集变为 比如 aload 2 aload0 / aload 2 aload0 + add(InsnNode(Opcodes.DUP2)) + //抛出最上面的指令 指令集变为 aload 2 aload0 / aload 2 其中 aload 2即为我们所需要的对象 + add(InsnNode(Opcodes.POP)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/aop/WebViewHook", + "inject", + "(Ljava/lang/Object;)V", + false + ) + ) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/aop/WebViewHook", + "getSafeUrl", + "(Ljava/lang/String;)Ljava/lang/String;", + false + ) + ) + this + } + } + + /** + * 创建webView函数指令集 (多参数,先存参数然后取出) + * 参考:https://www.jianshu.com/p/7d623f441bed + */ + private fun createWebViewInsnList(method: MethodNode): InsnList { + val size = method.localVariables.size + return with(InsnList()) { + add(VarInsnNode(Opcodes.ASTORE, size + 1)) + add(VarInsnNode(Opcodes.ASTORE, size)) + add(InsnNode(Opcodes.DUP)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/aop/WebViewHook", + "inject", + "(Ljava/lang/Object;)V", + false + ) + ) + add(VarInsnNode(Opcodes.ALOAD, size)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/aop/WebViewHook", + "getSafeUrl", + "(Ljava/lang/String;)Ljava/lang/String;", + false + ) + ) + add(VarInsnNode(Opcodes.ALOAD, size + 1)) + this + } + } +} diff --git a/Android/config.gradle b/Android/config.gradle index 91e94d132..597049277 100755 --- a/Android/config.gradle +++ b/Android/config.gradle @@ -14,10 +14,10 @@ ext { use_local : true, // group_id : 'io.github.didi.dokit', group_id : 'com.didichuxing.doraemonkit', - version : '3.7.0.6' + version : '3.7.14.9-kotlin-13' ] - android = [compileSdkVersion : 29, + android = [compileSdkVersion : 31, applicationId : "com.didichuxing.doraemondemo", minSdkVersion_16 : 16, minSdkVersion_21 : 21, @@ -31,7 +31,7 @@ ext { kotlin_version_v15 : "1.5.31", kotlinx_coroutines_version_v13: "1.3.7", kotlinx_coroutines_version_v14: "1.4.3", - booster_version : "4.0.0", + booster_version : "4.13.0", agp_module_verson : "7.0.0", agp_plugin_verson : "4.2.2", ktor : "1.5.4", @@ -162,9 +162,7 @@ ext { //定义全局方法 needKotlinV14 = { String version = publish_config["version"] - //分割字符串 - String[] vs = version.split("\\.") - return vs.length == 3 + return !version.contains("kotlin-13") } usePrivateEnv = { diff --git a/Android/dokit-gps-mock/build.gradle b/Android/dokit-gps-mock/build.gradle index e3f68b742..f89d17945 100644 --- a/Android/dokit-gps-mock/build.gradle +++ b/Android/dokit-gps-mock/build.gradle @@ -80,9 +80,9 @@ dependencies { api files('libs/BaiduLBS_Android.jar') - compileOnly rootProject.ext.dependencies["amap_location"] //高德导航 compileOnly rootProject.ext.dependencies["amap_navi"] + compileOnly rootProject.ext.dependencies["amap_location"] //腾讯地图定位 compileOnly rootProject.ext.dependencies["tencent_location"] } diff --git a/Android/dokit-gps-mock/src/main/java/com/didichuxing/doraemonkit/gps_mock/map/AMapLocationListenerProxy.java b/Android/dokit-gps-mock/src/main/java/com/didichuxing/doraemonkit/gps_mock/map/AMapLocationListenerProxy.java index e365c0288..23a5a0c83 100644 --- a/Android/dokit-gps-mock/src/main/java/com/didichuxing/doraemonkit/gps_mock/map/AMapLocationListenerProxy.java +++ b/Android/dokit-gps-mock/src/main/java/com/didichuxing/doraemonkit/gps_mock/map/AMapLocationListenerProxy.java @@ -4,6 +4,7 @@ import com.amap.api.location.AMapLocation; import com.amap.api.location.AMapLocationListener; +import com.didichuxing.doraemonkit.config.GpsMockConfig; import com.didichuxing.doraemonkit.gps_mock.gpsmock.GpsMockManager; import com.didichuxing.doraemonkit.gps_mock.gpsmock.GpsMockProxyManager; import com.didichuxing.doraemonkit.util.CoordinateUtils; @@ -40,6 +41,9 @@ public void onLocationChanged(AMapLocation mapLocation) { + "\n after_trans_loc==>" + Arrays.toString(res)); mapLocation.setLatitude(res[1]); mapLocation.setLongitude(res[0]); + if (GpsMockManager.getInstance().isMockingRoute()) { + mapLocation.setSpeed(GpsMockConfig.getRouteMockSpeed()); + } mapLocation.setProvider(LocationManager.GPS_PROVIDER); //通过反射强制改变p的值 原因:看mapLocation.setErrorCode ReflectUtils.reflect(mapLocation).field("p", 0); diff --git a/Android/dokit-gps-mock/src/main/java/com/didichuxing/doraemonkit/gps_mock/map/AMapNaviListenerProxy.java b/Android/dokit-gps-mock/src/main/java/com/didichuxing/doraemonkit/gps_mock/map/AMapNaviListenerProxy.java index 038f38e72..926a2de20 100644 --- a/Android/dokit-gps-mock/src/main/java/com/didichuxing/doraemonkit/gps_mock/map/AMapNaviListenerProxy.java +++ b/Android/dokit-gps-mock/src/main/java/com/didichuxing/doraemonkit/gps_mock/map/AMapNaviListenerProxy.java @@ -1,383 +1,44 @@ package com.didichuxing.doraemonkit.gps_mock.map; -import com.amap.api.navi.AMapNavi; +import androidx.annotation.NonNull; + import com.amap.api.navi.AMapNaviListener; import com.amap.api.navi.model.AMapCalcRouteResult; -import com.amap.api.navi.model.AMapLaneInfo; -import com.amap.api.navi.model.AMapModelCross; -import com.amap.api.navi.model.AMapNaviCameraInfo; -import com.amap.api.navi.model.AMapNaviCross; -import com.amap.api.navi.model.AMapNaviLink; import com.amap.api.navi.model.AMapNaviLocation; -import com.amap.api.navi.model.AMapNaviPath; -import com.amap.api.navi.model.AMapNaviRouteNotifyData; -import com.amap.api.navi.model.AMapNaviStep; -import com.amap.api.navi.model.AMapNaviTrafficFacilityInfo; -import com.amap.api.navi.model.AMapServiceAreaInfo; -import com.amap.api.navi.model.AimLessModeCongestionInfo; -import com.amap.api.navi.model.AimLessModeStat; -import com.amap.api.navi.model.NaviInfo; -import com.amap.api.navi.model.NaviLatLng; -import com.baidu.mapapi.search.core.RouteNode; -import com.baidu.mapapi.utils.CoordinateConverter; -import com.didichuxing.doraemonkit.DoKit; -import com.didichuxing.doraemonkit.config.GpsMockConfig; -import com.didichuxing.doraemonkit.gps_mock.common.BdMapRouteData; -import com.didichuxing.doraemonkit.gps_mock.gpsmock.GpsMockManager; import com.didichuxing.doraemonkit.gps_mock.gpsmock.GpsMockProxyManager; -import com.didichuxing.doraemonkit.util.CoordinateUtils; -import com.didichuxing.doraemonkit.util.LogHelper; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; /** - * ================================================ - * 作 者:jint(金台) - * 版 本:1.0 - * 创建日期:2019-12-15-16:18 - * 描 述:高德AMapLocationListenerProxy 通过ASM代码动态插入 高德不会跟随系统hook 腾讯和百度会跟随系统的hook - * 修订历史: - * ================================================ + * didi Create on 2023/3/28 . + *

+ * Copyright (c) 2023/3/28 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/28 8:13 下午 + * @Description 用一句话说明文件功能 */ -public class AMapNaviListenerProxy implements AMapNaviListener { - private static final String TAG = "AMapNaviListenerProxy"; - public AMapNaviListener aMapNaviListener; - - public AMapNaviListenerProxy(AMapNaviListener aMapNaviListener) { - this.aMapNaviListener = aMapNaviListener; - GpsMockProxyManager.INSTANCE.addAMapNaviListenerProxy(this); - } +public class AMapNaviListenerProxy extends AMapNaviListenerProxyNoOp { - @Override - public void onInitNaviFailure() { - if (aMapNaviListener != null) { - aMapNaviListener.onInitNaviFailure(); - } - - } - - @Override - public void onInitNaviSuccess() { - if (aMapNaviListener != null) { - aMapNaviListener.onInitNaviSuccess(); - } - } - - @Override - public void onStartNavi(int i) { - if (aMapNaviListener != null) { - aMapNaviListener.onStartNavi(i); - } - } + public AMapNaviListener aMapNaviListener; + private AMapNaviListenerProxyDelegate delegate; - @Override - public void onTrafficStatusUpdate() { - if (aMapNaviListener != null) { - aMapNaviListener.onTrafficStatusUpdate(); - } + public AMapNaviListenerProxy(@NonNull AMapNaviListener naviListener) { + super(naviListener); + this.aMapNaviListener = naviListener; + delegate = new AMapNaviListenerProxyDelegate(); + GpsMockProxyManager.INSTANCE.addAMapNaviListenerProxy(this); } @Override public void onLocationChange(AMapNaviLocation aMapNaviLocation) { - if (GpsMockManager.getInstance().isMocking()) { - double[] res = CoordinateUtils.bd09ToGcj02(GpsMockManager.getInstance().getLongitude(), GpsMockManager.getInstance().getLatitude()); - aMapNaviLocation.setCoord(new NaviLatLng(res[1], res[0])); - aMapNaviLocation.setSpeed(GpsMockConfig.getRouteMockSpeed()); - } - LogHelper.d(TAG, "===amap===onLocationChange" + aMapNaviLocation.getCoord().toString()); - if (aMapNaviListener != null) { - aMapNaviListener.onLocationChange(aMapNaviLocation); - } - } - - @Override - public void onGetNavigationText(int i, String s) { - if (aMapNaviListener != null) { - aMapNaviListener.onGetNavigationText(i, s); - } - } - - @Override - public void onGetNavigationText(String s) { - if (aMapNaviListener != null) { - aMapNaviListener.onGetNavigationText(s); - } - } - - @Override - public void onEndEmulatorNavi() { - if (aMapNaviListener != null) { - aMapNaviListener.onEndEmulatorNavi(); - } - } - - @Override - public void onArriveDestination() { - if (aMapNaviListener != null) { - aMapNaviListener.onArriveDestination(); - } - } - - @Override - public void onCalculateRouteFailure(int i) { - if (aMapNaviListener != null) { - aMapNaviListener.onCalculateRouteFailure(i); - } - } - - @Override - public void onReCalculateRouteForYaw() { - if (aMapNaviListener != null) { - aMapNaviListener.onReCalculateRouteForYaw(); - } - } - - @Override - public void onReCalculateRouteForTrafficJam() { - if (aMapNaviListener != null) { - aMapNaviListener.onReCalculateRouteForTrafficJam(); - } - } - - @Override - public void onArrivedWayPoint(int i) { - if (aMapNaviListener != null) { - aMapNaviListener.onArrivedWayPoint(i); - } - } - - @Override - public void onGpsOpenStatus(boolean b) { - if (aMapNaviListener != null) { - aMapNaviListener.onGpsOpenStatus(b); - } - } - - @Override - public void onNaviInfoUpdate(NaviInfo naviInfo) { - LogHelper.d(TAG, "====onNaviInfoUpdate====" + naviInfo.getPathRetainDistance()); - if (aMapNaviListener != null) { - aMapNaviListener.onNaviInfoUpdate(naviInfo); - } - } - - @Override - public void updateCameraInfo(AMapNaviCameraInfo[] aMapNaviCameraInfos) { - if (aMapNaviListener != null) { - aMapNaviListener.updateCameraInfo(aMapNaviCameraInfos); - } - } - - @Override - public void updateIntervalCameraInfo(AMapNaviCameraInfo aMapNaviCameraInfo, AMapNaviCameraInfo aMapNaviCameraInfo1, int i) { - if (aMapNaviListener != null) { - aMapNaviListener.updateIntervalCameraInfo(aMapNaviCameraInfo, aMapNaviCameraInfo1, i); - } - } - - @Override - public void onServiceAreaUpdate(AMapServiceAreaInfo[] aMapServiceAreaInfos) { - if (aMapNaviListener != null) { - aMapNaviListener.onServiceAreaUpdate(aMapServiceAreaInfos); - } - } - - @Override - public void showCross(AMapNaviCross aMapNaviCross) { - if (aMapNaviListener != null) { - aMapNaviListener.showCross(aMapNaviCross); - } - } - - @Override - public void hideCross() { - if (aMapNaviListener != null) { - aMapNaviListener.hideCross(); - } - } - - @Override - public void showModeCross(AMapModelCross aMapModelCross) { - if (aMapNaviListener != null) { - aMapNaviListener.showModeCross(aMapModelCross); - } - } - - @Override - public void hideModeCross() { - if (aMapNaviListener != null) { - aMapNaviListener.hideModeCross(); - } - } - - @Override - public void showLaneInfo(AMapLaneInfo[] aMapLaneInfos, byte[] bytes, byte[] bytes1) { - if (aMapNaviListener != null) { - aMapNaviListener.showLaneInfo(aMapLaneInfos, bytes, bytes1); - } - } - - @Override - public void showLaneInfo(AMapLaneInfo aMapLaneInfo) { - if (aMapNaviListener != null) { - aMapNaviListener.showLaneInfo(aMapLaneInfo); - } - } - - @Override - public void hideLaneInfo() { - if (aMapNaviListener != null) { - aMapNaviListener.hideLaneInfo(); - } - } - - @Override - public void onCalculateRouteSuccess(int[] ints) { - if (aMapNaviListener != null) { - aMapNaviListener.onCalculateRouteSuccess(ints); - } - } - - @Override - public void notifyParallelRoad(int i) { - if (aMapNaviListener != null) { - aMapNaviListener.notifyParallelRoad(i); - } - } - - @Override - public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo[] aMapNaviTrafficFacilityInfos) { - if (aMapNaviListener != null) { - aMapNaviListener.OnUpdateTrafficFacility(aMapNaviTrafficFacilityInfos); - } - } - - @Override - public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo aMapNaviTrafficFacilityInfo) { - if (aMapNaviListener != null) { - aMapNaviListener.OnUpdateTrafficFacility(aMapNaviTrafficFacilityInfo); - } - } - - @Override - public void updateAimlessModeStatistics(AimLessModeStat aimLessModeStat) { - if (aMapNaviListener != null) { - aMapNaviListener.updateAimlessModeStatistics(aimLessModeStat); - } - } - - @Override - public void updateAimlessModeCongestionInfo(AimLessModeCongestionInfo aimLessModeCongestionInfo) { - if (aMapNaviListener != null) { - aMapNaviListener.updateAimlessModeCongestionInfo(aimLessModeCongestionInfo); - } - } - - @Override - public void onPlayRing(int i) { - if (aMapNaviListener != null) { - aMapNaviListener.onPlayRing(i); - } + delegate.onLocationChange(aMapNaviLocation); + super.onLocationChange(aMapNaviLocation); } @Override public void onCalculateRouteSuccess(AMapCalcRouteResult aMapCalcRouteResult) { - try { - // 重新做了路径规划,则尝试打断当前模拟. - GpsMockManager.getInstance().interruptRouteMockThread(); - int[] routIds = aMapCalcRouteResult.getRouteid(); - // 获取路线数据对象 - HashMap naviPaths = AMapNavi.getInstance(DoKit.INSTANCE.getAPPLICATION()).getNaviPaths(); - LogHelper.d(TAG, "===amap===onCalculateRouteSuccess $naviPaths " + naviPaths.size() + " routeId " + Arrays.toString(routIds)); - - CoordinateConverter converter = new CoordinateConverter().from(CoordinateConverter.CoordType.COMMON); - // 将所有点转换成百度坐标点 - List bdPoints = new ArrayList<>(); - AMapNaviPath naviPath = naviPaths.get(routIds[0]); - List steps = naviPath.getSteps(); - int linkSize = 0; - int stepSize = 0; - for (AMapNaviStep step : steps) { - stepSize += step.getCoords().size(); - List links = step.getLinks(); - boolean notNavi = false; - if (links != null && links.size() > 0){ - for (AMapNaviLink link : links){ - if (link == null) continue; - int linkType = link.getLinkType(); // 获取道路类型 0-普通道路 1-航道 2-隧道 3-桥梁 4-高架桥 注意:该接口仅驾车模式有效 - int roadClass = link.getRoadClass(); //获取该Link道路等级 * 0 高速公路 * 1 国道 * 2 省道 * 3 县道 * 4 乡公路 * 5 县乡村内部道路 * 6 主要大街、城市快速道 * 7 主要道路 * 8 次要道路 * 9 普通道路 * 10 非导航道路 - List coords = link.getCoords(); - if (coords == null) continue; - linkSize += coords.size(); - // 过滤非开车导航坐标点(下车后) - if (roadClass == 10){ - notNavi = true; - break; - } - } - } - - if (notNavi) continue; - for (NaviLatLng latLng : step.getCoords()){ - com.baidu.mapapi.model.LatLng sourceLatLng = new com.baidu.mapapi.model.LatLng(latLng.getLatitude(), latLng.getLongitude()); - //转换坐标 - converter.coord(sourceLatLng); - com.baidu.mapapi.model.LatLng desLatLng = converter.convert(); - bdPoints.add(desLatLng); - } - } - - LogHelper.d(TAG, "===amap===total points==>" + naviPath.getCoordList().size() + " " + naviPath.getCoordList().get(naviPath.getCoordList().size() - 1) - + " \n" + bdPoints.size() + " " + bdPoints.get(bdPoints.size() - 1) - + "\nlinkSize=" + linkSize + " stepSize=" + stepSize); - BdMapRouteData bdMapRouteData = new BdMapRouteData(); - bdMapRouteData.setAllPoints(bdPoints); - bdMapRouteData.setTotalDistance(naviPath.getAllLength()); - - RouteNode startNode = new RouteNode(); - com.baidu.mapapi.model.LatLng sourceStartLatLng = new com.baidu.mapapi.model.LatLng(naviPath.getStartPoint().getLatitude(), naviPath.getStartPoint().getLongitude()); - com.baidu.mapapi.model.LatLng desStartLatLng = converter.coord(sourceStartLatLng).convert(); - startNode.setLocation(desStartLatLng); - RouteNode terminalNode = new RouteNode(); - com.baidu.mapapi.model.LatLng sourceTerminalLatLng = new com.baidu.mapapi.model.LatLng(naviPath.getEndPoint().getLatitude(), naviPath.getEndPoint().getLongitude()); - com.baidu.mapapi.model.LatLng desTerminalLatLng = converter.coord(sourceTerminalLatLng).convert(); - terminalNode.setLocation(desTerminalLatLng); - bdMapRouteData.setStartNode(startNode); - bdMapRouteData.setTerminalNode(terminalNode); - bdMapRouteData.setRouteDataFromBiz(true); - - GpsMockManager.getInstance().setBdMockDrivingRouteLine(bdMapRouteData); - - if (aMapNaviListener != null) { - aMapNaviListener.onCalculateRouteSuccess(aMapCalcRouteResult); - } - } catch (Exception e) { - LogHelper.e(TAG, "===amap===onCalculateRouteSuccess error " + e.getMessage()); - } - } - - @Override - public void onCalculateRouteFailure(AMapCalcRouteResult aMapCalcRouteResult) { - if (aMapNaviListener != null) { - aMapNaviListener.onCalculateRouteFailure(aMapCalcRouteResult); - } - } - - @Override - public void onNaviRouteNotify(AMapNaviRouteNotifyData aMapNaviRouteNotifyData) { - if (aMapNaviListener != null) { - aMapNaviListener.onNaviRouteNotify(aMapNaviRouteNotifyData); - } - } - - @Override - public void onGpsSignalWeak(boolean b) { - if (aMapNaviListener != null) { - aMapNaviListener.onGpsSignalWeak(b); - } + delegate.onCalculateRouteSuccess(aMapCalcRouteResult); + super.onCalculateRouteSuccess(aMapCalcRouteResult); } } diff --git a/Android/dokit-gps-mock/src/main/java/com/didichuxing/doraemonkit/gps_mock/map/AMapNaviListenerProxyDelegate.java b/Android/dokit-gps-mock/src/main/java/com/didichuxing/doraemonkit/gps_mock/map/AMapNaviListenerProxyDelegate.java new file mode 100644 index 000000000..6cb58b4fe --- /dev/null +++ b/Android/dokit-gps-mock/src/main/java/com/didichuxing/doraemonkit/gps_mock/map/AMapNaviListenerProxyDelegate.java @@ -0,0 +1,124 @@ +package com.didichuxing.doraemonkit.gps_mock.map; + +import com.amap.api.navi.AMapNavi; +import com.amap.api.navi.model.AMapCalcRouteResult; +import com.amap.api.navi.model.AMapNaviLink; +import com.amap.api.navi.model.AMapNaviLocation; +import com.amap.api.navi.model.AMapNaviPath; +import com.amap.api.navi.model.AMapNaviStep; +import com.amap.api.navi.model.NaviLatLng; +import com.baidu.mapapi.search.core.RouteNode; +import com.baidu.mapapi.utils.CoordinateConverter; +import com.didichuxing.doraemonkit.DoKit; +import com.didichuxing.doraemonkit.config.GpsMockConfig; +import com.didichuxing.doraemonkit.gps_mock.common.BdMapRouteData; +import com.didichuxing.doraemonkit.gps_mock.gpsmock.GpsMockManager; +import com.didichuxing.doraemonkit.util.CoordinateUtils; +import com.didichuxing.doraemonkit.util.LogHelper; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +/** + * ================================================ + * 作 者:jint(金台) + * 版 本:1.0 + * 创建日期:2019-12-15-16:18 + * 描 述:高德AMapLocationListenerProxy 通过ASM代码动态插入 高德不会跟随系统hook 腾讯和百度会跟随系统的hook + * 修订历史: + * ================================================ + */ +public class AMapNaviListenerProxyDelegate { + private static final String TAG = "AMapNaviListenerProxy"; + + public AMapNaviListenerProxyDelegate() { + + } + + public void onLocationChange(AMapNaviLocation aMapNaviLocation) { + if (GpsMockManager.getInstance().isMocking()) { + double[] res = CoordinateUtils.bd09ToGcj02(GpsMockManager.getInstance().getLongitude(), GpsMockManager.getInstance().getLatitude()); + aMapNaviLocation.setCoord(new NaviLatLng(res[1], res[0])); + aMapNaviLocation.setSpeed(GpsMockConfig.getRouteMockSpeed()); + } + LogHelper.d(TAG, "===amap===onLocationChange" + aMapNaviLocation.getCoord().toString()); + } + + + public void onCalculateRouteSuccess(AMapCalcRouteResult aMapCalcRouteResult) { + if (GpsMockManager.getInstance().isMocking()) { + try { + // 重新做了路径规划,则尝试打断当前模拟. + GpsMockManager.getInstance().interruptRouteMockThread(); + int[] routIds = aMapCalcRouteResult.getRouteid(); + // 获取路线数据对象 + HashMap naviPaths = AMapNavi.getInstance(DoKit.INSTANCE.getAPPLICATION()).getNaviPaths(); + LogHelper.d(TAG, "===amap===onCalculateRouteSuccess $naviPaths " + naviPaths.size() + " routeId " + Arrays.toString(routIds)); + + CoordinateConverter converter = new CoordinateConverter().from(CoordinateConverter.CoordType.COMMON); + // 将所有点转换成百度坐标点 + List bdPoints = new ArrayList<>(); + AMapNaviPath naviPath = naviPaths.get(routIds[0]); + List steps = naviPath.getSteps(); + int linkSize = 0; + int stepSize = 0; + for (AMapNaviStep step : steps) { + stepSize += step.getCoords().size(); + List links = step.getLinks(); + boolean notNavi = false; + if (links != null && links.size() > 0) { + for (AMapNaviLink link : links) { + if (link == null) continue; + int linkType = link.getLinkType(); // 获取道路类型 0-普通道路 1-航道 2-隧道 3-桥梁 4-高架桥 注意:该接口仅驾车模式有效 + int roadClass = link.getRoadClass(); //获取该Link道路等级 * 0 高速公路 * 1 国道 * 2 省道 * 3 县道 * 4 乡公路 * 5 县乡村内部道路 * 6 主要大街、城市快速道 * 7 主要道路 * 8 次要道路 * 9 普通道路 * 10 非导航道路 + List coords = link.getCoords(); + if (coords == null) continue; + linkSize += coords.size(); + // 过滤非开车导航坐标点(下车后) + if (roadClass == 10) { + notNavi = true; + break; + } + } + } + + if (notNavi) continue; + for (NaviLatLng latLng : step.getCoords()) { + com.baidu.mapapi.model.LatLng sourceLatLng = new com.baidu.mapapi.model.LatLng(latLng.getLatitude(), latLng.getLongitude()); + //转换坐标 + converter.coord(sourceLatLng); + com.baidu.mapapi.model.LatLng desLatLng = converter.convert(); + bdPoints.add(desLatLng); + } + } + + LogHelper.d(TAG, "===amap===total points==>" + naviPath.getCoordList().size() + " " + naviPath.getCoordList().get(naviPath.getCoordList().size() - 1) + + " \n" + bdPoints.size() + " " + bdPoints.get(bdPoints.size() - 1) + + "\nlinkSize=" + linkSize + " stepSize=" + stepSize); + BdMapRouteData bdMapRouteData = new BdMapRouteData(); + bdMapRouteData.setAllPoints(bdPoints); + bdMapRouteData.setTotalDistance(naviPath.getAllLength()); + + RouteNode startNode = new RouteNode(); + com.baidu.mapapi.model.LatLng sourceStartLatLng = new com.baidu.mapapi.model.LatLng(naviPath.getStartPoint().getLatitude(), naviPath.getStartPoint().getLongitude()); + com.baidu.mapapi.model.LatLng desStartLatLng = converter.coord(sourceStartLatLng).convert(); + startNode.setLocation(desStartLatLng); + RouteNode terminalNode = new RouteNode(); + com.baidu.mapapi.model.LatLng sourceTerminalLatLng = new com.baidu.mapapi.model.LatLng(naviPath.getEndPoint().getLatitude(), naviPath.getEndPoint().getLongitude()); + com.baidu.mapapi.model.LatLng desTerminalLatLng = converter.coord(sourceTerminalLatLng).convert(); + terminalNode.setLocation(desTerminalLatLng); + bdMapRouteData.setStartNode(startNode); + bdMapRouteData.setTerminalNode(terminalNode); + bdMapRouteData.setRouteDataFromBiz(true); + + GpsMockManager.getInstance().setBdMockDrivingRouteLine(bdMapRouteData); + + } catch (Exception e) { + LogHelper.e(TAG, "===amap===onCalculateRouteSuccess error " + e.getMessage()); + } + } + } + +} diff --git a/Android/dokit-gps-mock/src/main/java/com/didichuxing/doraemonkit/gps_mock/map/AMapNaviListenerProxyNoOp.java b/Android/dokit-gps-mock/src/main/java/com/didichuxing/doraemonkit/gps_mock/map/AMapNaviListenerProxyNoOp.java new file mode 100644 index 000000000..81780a9f9 --- /dev/null +++ b/Android/dokit-gps-mock/src/main/java/com/didichuxing/doraemonkit/gps_mock/map/AMapNaviListenerProxyNoOp.java @@ -0,0 +1,294 @@ +package com.didichuxing.doraemonkit.gps_mock.map; + +import androidx.annotation.NonNull; + +import com.amap.api.navi.AMapNaviListener; +import com.amap.api.navi.MyNaviListener; +import com.amap.api.navi.model.AMapCalcRouteResult; +import com.amap.api.navi.model.AMapLaneInfo; +import com.amap.api.navi.model.AMapModelCross; +import com.amap.api.navi.model.AMapNaviCameraInfo; +import com.amap.api.navi.model.AMapNaviCross; +import com.amap.api.navi.model.AMapNaviLocation; +import com.amap.api.navi.model.AMapNaviRouteNotifyData; +import com.amap.api.navi.model.AMapNaviTrafficFacilityInfo; +import com.amap.api.navi.model.AMapServiceAreaInfo; +import com.amap.api.navi.model.AimLessModeCongestionInfo; +import com.amap.api.navi.model.AimLessModeStat; +import com.amap.api.navi.model.InnerNaviInfo; +import com.amap.api.navi.model.NaviCongestionInfo; +import com.amap.api.navi.model.NaviInfo; +import com.amap.api.navi.model.NaviPath; + +/** + * didi Create on 2023/3/28 . + *

+ * Copyright (c) 2023/3/28 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/28 8:06 下午 + * @Description 用一句话说明文件功能 + */ + +public class AMapNaviListenerProxyNoOp implements MyNaviListener { + + + @NonNull + private AMapNaviListener naviListener; + + public AMapNaviListenerProxyNoOp(@NonNull AMapNaviListener naviListener) { + this.naviListener = naviListener; + } + + public AMapNaviListener getNaviListener() { + return naviListener; + } + + + @Override + public void onInitNaviFailure() { + naviListener.onInitNaviFailure(); + } + + @Override + public void onInitNaviSuccess() { + naviListener.onInitNaviSuccess(); + } + + @Override + public void onStartNavi(int i) { + naviListener.onStartNavi(i); + } + + @Override + public void onTrafficStatusUpdate() { + naviListener.onTrafficStatusUpdate(); + } + + @Override + public void onLocationChange(AMapNaviLocation aMapNaviLocation) { + naviListener.onLocationChange(aMapNaviLocation); + } + + @Override + public void onGetNavigationText(int i, String s) { + naviListener.onGetNavigationText(i, s); + } + + @Override + public void onGetNavigationText(String s) { + naviListener.onGetNavigationText(s); + } + + @Override + public void onEndEmulatorNavi() { + naviListener.onEndEmulatorNavi(); + } + + @Override + public void onArriveDestination() { + naviListener.onArriveDestination(); + } + + @Override + public void onCalculateRouteFailure(int i) { + naviListener.onCalculateRouteFailure(i); + } + + @Override + public void onReCalculateRouteForYaw() { + naviListener.onReCalculateRouteForYaw(); + } + + @Override + public void onReCalculateRouteForTrafficJam() { + naviListener.onReCalculateRouteForTrafficJam(); + } + + @Override + public void onArrivedWayPoint(int i) { + naviListener.onArrivedWayPoint(i); + } + + @Override + public void onGpsOpenStatus(boolean b) { + naviListener.onGpsOpenStatus(b); + } + + @Override + public void onNaviInfoUpdate(NaviInfo naviInfo) { + naviListener.onNaviInfoUpdate(naviInfo); + } + + @Override + public void updateCameraInfo(AMapNaviCameraInfo[] aMapNaviCameraInfos) { + naviListener.updateCameraInfo(aMapNaviCameraInfos); + } + + @Override + public void updateIntervalCameraInfo(AMapNaviCameraInfo aMapNaviCameraInfo, AMapNaviCameraInfo aMapNaviCameraInfo1, int i) { + naviListener.updateIntervalCameraInfo(aMapNaviCameraInfo, aMapNaviCameraInfo1, i); + } + + @Override + public void onServiceAreaUpdate(AMapServiceAreaInfo[] aMapServiceAreaInfos) { + naviListener.onServiceAreaUpdate(aMapServiceAreaInfos); + } + + @Override + public void showCross(AMapNaviCross aMapNaviCross) { + naviListener.showCross(aMapNaviCross); + } + + @Override + public void hideCross() { + naviListener.hideCross(); + } + + @Override + public void showModeCross(AMapModelCross aMapModelCross) { + naviListener.showModeCross(aMapModelCross); + } + + @Override + public void hideModeCross() { + naviListener.hideModeCross(); + } + + @Override + public void showLaneInfo(AMapLaneInfo[] aMapLaneInfos, byte[] bytes, byte[] bytes1) { + naviListener.showLaneInfo(aMapLaneInfos, bytes, bytes1); + } + + @Override + public void showLaneInfo(AMapLaneInfo aMapLaneInfo) { + naviListener.showLaneInfo(aMapLaneInfo); + } + + @Override + public void hideLaneInfo() { + naviListener.hideLaneInfo(); + } + + @Override + public void onCalculateRouteSuccess(int[] ints) { + naviListener.onCalculateRouteSuccess(ints); + } + + @Override + public void notifyParallelRoad(int i) { + naviListener.notifyParallelRoad(i); + } + + @Override + public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo[] aMapNaviTrafficFacilityInfos) { + naviListener.OnUpdateTrafficFacility(aMapNaviTrafficFacilityInfos); + } + + @Override + public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo aMapNaviTrafficFacilityInfo) { + naviListener.OnUpdateTrafficFacility(aMapNaviTrafficFacilityInfo); + } + + @Override + public void updateAimlessModeStatistics(AimLessModeStat aimLessModeStat) { + naviListener.updateAimlessModeStatistics(aimLessModeStat); + } + + @Override + public void updateAimlessModeCongestionInfo(AimLessModeCongestionInfo aimLessModeCongestionInfo) { + naviListener.updateAimlessModeCongestionInfo(aimLessModeCongestionInfo); + } + + @Override + public void onPlayRing(int i) { + naviListener.onPlayRing(i); + } + + @Override + public void onCalculateRouteSuccess(AMapCalcRouteResult aMapCalcRouteResult) { + naviListener.onCalculateRouteSuccess(aMapCalcRouteResult); + } + + @Override + public void onCalculateRouteFailure(AMapCalcRouteResult aMapCalcRouteResult) { + naviListener.onCalculateRouteFailure(aMapCalcRouteResult); + } + + @Override + public void onNaviRouteNotify(AMapNaviRouteNotifyData aMapNaviRouteNotifyData) { + naviListener.onNaviRouteNotify(aMapNaviRouteNotifyData); + } + + @Override + public void onGpsSignalWeak(boolean b) { + naviListener.onGpsSignalWeak(b); + } + + //----------MyNaviListener---------- + + + @Override + public void onInnerNaviInfoUpdate(InnerNaviInfo innerNaviInfo) { + if (naviListener instanceof MyNaviListener) { + ((MyNaviListener) naviListener).onInnerNaviInfoUpdate(innerNaviInfo); + } + } + + @Override + public void onInnerNaviInfoUpdate(InnerNaviInfo[] innerNaviInfos) { + if (naviListener instanceof MyNaviListener) { + ((MyNaviListener) naviListener).onInnerNaviInfoUpdate(innerNaviInfos); + } + } + + @Override + public void onUpdateTmcStatus(NaviCongestionInfo naviCongestionInfo) { + if (naviListener instanceof MyNaviListener) { + ((MyNaviListener) naviListener).onUpdateTmcStatus(naviCongestionInfo); + } + } + + @Override + public void onStopNavi() { + if (naviListener instanceof MyNaviListener) { + ((MyNaviListener) naviListener).onStopNavi(); + } + } + + @Override + public void onSelectRouteId(int i) { + if (naviListener instanceof MyNaviListener) { + ((MyNaviListener) naviListener).onSelectRouteId(i); + } + } + + @Override + public void updateBackupPath(NaviPath[] naviPaths) { + if (naviListener instanceof MyNaviListener) { + ((MyNaviListener) naviListener).updateBackupPath(naviPaths); + } + } + + @Override + public void onSuggestChangePath(long l, long l1, int i, String s) { + if (naviListener instanceof MyNaviListener) { + ((MyNaviListener) naviListener).onSuggestChangePath(l, l1, i, s); + } + } + + @Override + public void onUpdateNaviPath() { + if (naviListener instanceof MyNaviListener) { + ((MyNaviListener) naviListener).onUpdateNaviPath(); + } + } + + @Override + public void onUpdateGpsSignalStrength(int i) { + if (naviListener instanceof MyNaviListener) { + ((MyNaviListener) naviListener).onUpdateGpsSignalStrength(i); + } + } +} diff --git a/Android/dokit-mc/src/main/java/com/didichuxing/doraemonkit/kit/mc/ui/connect/MultiControlAllFragment.kt b/Android/dokit-mc/src/main/java/com/didichuxing/doraemonkit/kit/mc/ui/connect/MultiControlAllFragment.kt index 038962c63..0a8c38458 100644 --- a/Android/dokit-mc/src/main/java/com/didichuxing/doraemonkit/kit/mc/ui/connect/MultiControlAllFragment.kt +++ b/Android/dokit-mc/src/main/java/com/didichuxing/doraemonkit/kit/mc/ui/connect/MultiControlAllFragment.kt @@ -223,7 +223,7 @@ class MultiControlAllFragment : BaseFragment() { val name = uri.host.toString() val time = TimeUtils.date2String(Date()) val url = code - val history = McClientHistory(uri.host!!, uri.port, uri.path!!, name, time, url) + val history = McClientHistory(uri.host!!, uri.port, uri.path!!, name, time, url!!) ConnectHistoryUtils.saveClientHistory(history) handleConnect(history) } diff --git a/Android/dokit-no-op/src/main/java/com/didichuxing/doraemonkit/tcp/ability/MessageReceiverHook.java b/Android/dokit-no-op/src/main/java/com/didichuxing/doraemonkit/tcp/ability/MessageReceiverHook.java new file mode 100644 index 000000000..167250aa0 --- /dev/null +++ b/Android/dokit-no-op/src/main/java/com/didichuxing/doraemonkit/tcp/ability/MessageReceiverHook.java @@ -0,0 +1,19 @@ +package com.didichuxing.doraemonkit.tcp.ability; + +/** + * didi Create on 2022/9/20 . + *

+ * Copyright (c) 2022/9/20 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2022/9/20 11:19 上午 + * @Description 用一句话说明文件功能 + */ + +public class MessageReceiverHook { + + public static void dispatchMessage(Object message) { + + } +} diff --git a/Android/dokit-no-op/src/main/java/com/didichuxing/doraemonkit/tcp/ability/MessageSenderHook.java b/Android/dokit-no-op/src/main/java/com/didichuxing/doraemonkit/tcp/ability/MessageSenderHook.java new file mode 100644 index 000000000..8b54e2622 --- /dev/null +++ b/Android/dokit-no-op/src/main/java/com/didichuxing/doraemonkit/tcp/ability/MessageSenderHook.java @@ -0,0 +1,18 @@ +package com.didichuxing.doraemonkit.tcp.ability; + +/** + * didi Create on 2022/9/20 . + *

+ * Copyright (c) 2022/9/20 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2022/9/20 11:18 上午 + * @Description 用一句话说明文件功能 + */ + +public class MessageSenderHook { + + public static void sendMessage(String message) { + } +} diff --git a/Android/dokit-no-op/src/main/java/com/didichuxing/doraemonkit/tcp/ability/TcpMessageHook.java b/Android/dokit-no-op/src/main/java/com/didichuxing/doraemonkit/tcp/ability/TcpMessageHook.java new file mode 100644 index 000000000..04f8ce93c --- /dev/null +++ b/Android/dokit-no-op/src/main/java/com/didichuxing/doraemonkit/tcp/ability/TcpMessageHook.java @@ -0,0 +1,19 @@ +package com.didichuxing.doraemonkit.tcp.ability; + +/** + * didi Create on 2022/9/20 . + *

+ * Copyright (c) 2022/9/20 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2022/9/20 11:18 上午 + * @Description 用一句话说明文件功能 + */ + +public class TcpMessageHook { + + public static void init() { + + } +} diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitExt.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitExt.kt index 741731104..69f58f014 100644 --- a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitExt.kt +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitExt.kt @@ -87,7 +87,7 @@ fun MethodNode.isEmptyMethod(): Boolean { fun MethodNode.isMainMethod(className: String): Boolean { if (this.name == "main" && this.desc == "([Ljava/lang/String;)V") { -// "====isMainMethod====$className ${this.name} ${this.desc} ${this.access}".println() + "====isMainMethod====$className ${this.name} ${this.desc} ${this.access}".println() return true } diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitExtUtil.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitExtUtil.kt index 97dbec8a0..2fea747c6 100644 --- a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitExtUtil.kt +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitExtUtil.kt @@ -1,9 +1,8 @@ package com.didichuxing.doraemonkit.plugin -import com.didichuxing.doraemonkit.plugin.extension.CommExt -import com.didichuxing.doraemonkit.plugin.extension.DoKitExt -import com.didichuxing.doraemonkit.plugin.extension.SlowMethodExt -import org.gradle.api.Project +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.extension.SlowMethodExtension +import com.didichuxing.doraemonkit.plugin.thirdlib.ThirdLibInfo /** * ================================================ @@ -16,20 +15,11 @@ import org.gradle.api.Project */ object DoKitExtUtil { - /** - * 是否包含dokitx-rpc模块 - */ - var HAS_DOKIT_RPC_MODULE = false - //private var mApplicationId: String = "" - - var HAS_DOKIT_TCP_HOOK_DJ = false - var DOKIT_GPS_MOCK_INCLUDE = false /** * 三方库版本信息 */ -// val THIRD_LIB_INFOS = mutableMapOf() val THIRD_LIB_INFOS = mutableListOf() @@ -64,7 +54,7 @@ object DoKitExtUtil { /** * 慢函数策略 默认为函数调用栈策略 */ - var SLOW_METHOD_STRATEGY = SlowMethodExt.STRATEGY_STACK + var SLOW_METHOD_STRATEGY = SlowMethodExtension.STRATEGY_STACK private val applications: MutableSet = mutableSetOf() @@ -73,9 +63,8 @@ object DoKitExtUtil { */ private var appPackageName: String = "" - var commExt = CommExt() - private set - val slowMethodExt = SlowMethodExt() + + val slowMethodExt = SlowMethodExtension() fun dokitPluginSwitchOpen(): Boolean { @@ -97,9 +86,8 @@ object DoKitExtUtil { * @param dokitEx dokitExtension * @param appExtension appExtension */ - fun init(dokitEx: DoKitExt) { + fun init(dokitEx: DoKitExtension) { //设置普通的配置 - commExt = dokitEx.comm //slowMethodExt.strategy = dokitEx.slowMethod.strategy //slowMethodExt.methodSwitch = dokitEx.slowMethod.methodSwitch /** diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitPlugin.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitPlugin.kt index cb32f8619..255355f63 100644 --- a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitPlugin.kt +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitPlugin.kt @@ -2,18 +2,56 @@ package com.didichuxing.doraemonkit.plugin import com.android.build.gradle.AppExtension import com.android.build.gradle.LibraryExtension -import com.didichuxing.doraemonkit.plugin.extension.DoKitExt -import com.didichuxing.doraemonkit.plugin.extension.SlowMethodExt +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.extension.SlowMethodExtension import com.didichuxing.doraemonkit.plugin.processor.DoKitPluginConfigProcessor import com.didichuxing.doraemonkit.plugin.stack_method.MethodStackNodeUtil +import com.didichuxing.doraemonkit.plugin.thirdlib.ThirdLibVariantProcessor import com.didichuxing.doraemonkit.plugin.transform.* import com.didiglobal.booster.gradle.GTE_V3_4 -import com.didiglobal.booster.gradle.dependencies import com.didiglobal.booster.gradle.getAndroid import com.didiglobal.booster.gradle.getProperty import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.api.artifacts.result.ResolvedArtifactResult + + +/** + * when 也可以用来取代 if-else if链。 + * 如果不提供参数,所有的分支条件都是简单的布尔表达式,而当一个分支的条件为真时则执行该分支: + */ + +/** + * 作用域函数:let、run、with、apply 以及 also + * 它们的唯一目的是在对象的上下文中执行代码块 + * 由于作用域函数本质上都非常相似,因此了解它们之间的区别很重要。每个作用域函数之间有两个主要区别: + * 引用上下文对象的方式: + * 作为 lambda 表达式的接收者(this)或者作为 lambda 表达式的参数(it) + * run、with 以及 apply 通过关键字 this 引用上下文对象 + * let 及 also 将上下文对象作为 lambda 表达式参数 + * + * 返回值: + * apply 及 also 返回上下文对象。 + * let、run 及 with 返回 lambda 表达式结果. + */ +/** + * 函数 对象引用 返回值 是否是扩展函数 + * let it Lambda 表达式结果 是 + * run this Lambda 表达式结果 是 + * run - Lambda 表达式结果 不是:调用无需上下文对象 + * with this Lambda 表达式结果 不是:把上下文对象当做参数 + * apply this 上下文对象 是 + * also it 上下文对象 是 + */ + +/** + *对一个非空(non-null)对象执行 lambda 表达式:let + *将表达式作为变量引入为局部作用域中:let + *对象配置:apply + *对象配置并且计算结果:run + *在需要表达式的地方运行语句:非扩展的 run + *附加效果:also + *一个对象的一组函数调用:with + */ /** * ================================================ @@ -23,58 +61,26 @@ import org.gradle.api.artifacts.result.ResolvedArtifactResult * 描 述: * 修订历史: * ================================================ + * + * DoKit 插件入口 */ + class DoKitPlugin : Plugin { override fun apply(project: Project) { //创建指定扩展 并将project 传入构造函数 - val doKitExt = project.extensions.create("dokitExt", DoKitExt::class.java) + val doKit = project.extensions.create("dokit", DoKitExtension::class.java) + "dokit plugin apply ${doKit}".println() project.gradle.addListener(DoKitTransformTaskExecutionListener(project)) - //println("project.plugins===>${project.plugins}") - /** - * when 也可以用来取代 if-else if链。 - * 如果不提供参数,所有的分支条件都是简单的布尔表达式,而当一个分支的条件为真时则执行该分支: - */ - - /** - * 作用域函数:let、run、with、apply 以及 also - * 它们的唯一目的是在对象的上下文中执行代码块 - * 由于作用域函数本质上都非常相似,因此了解它们之间的区别很重要。每个作用域函数之间有两个主要区别: - * 引用上下文对象的方式: - * 作为 lambda 表达式的接收者(this)或者作为 lambda 表达式的参数(it) - * run、with 以及 apply 通过关键字 this 引用上下文对象 - * let 及 also 将上下文对象作为 lambda 表达式参数 - * - * 返回值: - * apply 及 also 返回上下文对象。 - * let、run 及 with 返回 lambda 表达式结果. - */ - /** - * 函数 对象引用 返回值 是否是扩展函数 - * let it Lambda 表达式结果 是 - * run this Lambda 表达式结果 是 - * run - Lambda 表达式结果 不是:调用无需上下文对象 - * with this Lambda 表达式结果 不是:把上下文对象当做参数 - * apply this 上下文对象 是 - * also it 上下文对象 是 - */ - - /** - *对一个非空(non-null)对象执行 lambda 表达式:let - *将表达式作为变量引入为局部作用域中:let - *对象配置:apply - *对象配置并且计算结果:run - *在需要表达式的地方运行语句:非扩展的 run - *附加效果:also - *一个对象的一组函数调用:with - */ + when { project.plugins.hasPlugin("com.android.application") || project.plugins.hasPlugin("com.android.dynamic-feature") -> { if (!isReleaseTask(project)) { project.getAndroid().let { androidExt -> val pluginSwitch = project.getProperty("DOKIT_PLUGIN_SWITCH", true) val logSwitch = project.getProperty("DOKIT_LOG_SWITCH", false) + val slowMethodSwitch = project.getProperty("DOKIT_METHOD_SWITCH", false) val slowMethodStrategy = project.getProperty("DOKIT_METHOD_STRATEGY", 0) val methodStackLevel = project.getProperty("DOKIT_METHOD_STACK_LEVEL", 5) @@ -94,7 +100,7 @@ class DoKitPlugin : Plugin { if (DoKitExtUtil.DOKIT_PLUGIN_SWITCH) { //注册transform androidExt.registerTransform(commNewInstance(project)) - if (slowMethodSwitch && slowMethodStrategy == SlowMethodExt.STRATEGY_STACK) { + if (slowMethodSwitch && slowMethodStrategy == SlowMethodExtension.STRATEGY_STACK) { MethodStackNodeUtil.METHOD_STACK_KEYS.add(0, mutableSetOf()) val methodStackRange = 1 until methodStackLevel if (methodStackLevel > 1) { @@ -111,14 +117,6 @@ class DoKitPlugin : Plugin { } } - //项目评估完毕回调 -// project.afterEvaluate { project -> -// "===afterEvaluate===".println() -// androidExt.applicationVariants.forEach { variant -> -// DoKitPluginConfigProcessor(project).process(variant) -// } -// } - /** * 所有项目的build.gradle执行完毕 * wiki:https://juejin.im/post/6844903607679057934 @@ -127,6 +125,7 @@ class DoKitPlugin : Plugin { project.gradle.projectsEvaluated { "===projectsEvaluated===".println() androidExt.applicationVariants.forEach { variant -> + ThirdLibVariantProcessor(project).process(variant) DoKitPluginConfigProcessor(project).process(variant) } @@ -136,6 +135,7 @@ class DoKitPlugin : Plugin { //task依赖关系图建立完毕 project.gradle.taskGraph.whenReady { "===taskGraph.whenReady===".println() + "dokit config :: ${doKit}".println() } } @@ -152,6 +152,7 @@ class DoKitPlugin : Plugin { } project.afterEvaluate { libraryExt.libraryVariants.forEach { variant -> + ThirdLibVariantProcessor(project).process(variant) DoKitPluginConfigProcessor(project).process(variant) } } @@ -168,8 +169,8 @@ class DoKitPlugin : Plugin { } private fun commNewInstance(project: Project): DoKitBaseTransform = when { - GTE_V3_4 -> DoKitCommTransformV34(project) - else -> DoKitCommTransform(project) + GTE_V3_4 -> DoKitCommonTransformV34(project) + else -> DoKitCommonTransform(project) } private fun dependNewInstance(project: Project, index: Int): DoKitBaseTransform = when { @@ -178,4 +179,4 @@ class DoKitPlugin : Plugin { } -} \ No newline at end of file +} diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/ServiceLoader.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/ServiceLoader.kt deleted file mode 100644 index aeff63e8f..000000000 --- a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/ServiceLoader.kt +++ /dev/null @@ -1,76 +0,0 @@ -package com.didichuxing.doraemonkit.plugin - -import com.didiglobal.booster.task.spi.VariantProcessor -import com.didiglobal.booster.transform.Transformer -import org.gradle.api.Project -import java.net.URL -import java.nio.charset.StandardCharsets -import java.util.ServiceConfigurationError - -//internal interface ServiceLoader { -// fun load(vararg args: Any): List -//} - -//internal class ServiceLoaderFactory(private val classLoader: ClassLoader, private val service: Class) { -// -// fun newServiceLoader(vararg types: Class<*>) = object : ServiceLoader { -// -// @Suppress("UNCHECKED_CAST") -// override fun load(vararg args: Any) = classLoader.getResources("META-INF/services/${service.name}")?.asSequence()?.map(::parse)?.flatten()?.toSet()?.map { provider -> -// try { -// val providerClass = Class.forName(provider, false, classLoader) -// if (!service.isAssignableFrom(providerClass)) { -// throw ServiceConfigurationError("Provider $provider not a subtype") -// } -// -// try { -// providerClass.getConstructor(*types).newInstance(*args) as T -// } catch (e: NoSuchMethodException) { -// providerClass.newInstance() as T -// } -// } catch (e: ClassNotFoundException) { -// throw ServiceConfigurationError("Provider $provider not found") -// } -// } ?: emptyList() -// -// } -// -//} -// -//internal inline fun newServiceLoader(classLoader: ClassLoader, vararg types: Class<*>) = ServiceLoaderFactory(classLoader, T::class.java).newServiceLoader(*types) - -/** - * Load [Transformer]s with the specified [classLoader] - */ -//@Throws(ServiceConfigurationError::class) -//internal fun loadTransformers(classLoader: ClassLoader) = newServiceLoader(classLoader, ClassLoader::class.java).load(classLoader) - -/** - * Load [VariantProcessor]s with the specified [classLoader] - */ -//@Throws(ServiceConfigurationError::class) -//internal fun loadVariantProcessors(project: Project) = newServiceLoader(project.buildscript.classLoader, Project::class.java).load(project) - -@Throws(ServiceConfigurationError::class) -private fun parse(u: URL) = try { - u.openStream().bufferedReader(StandardCharsets.UTF_8).readLines().filter { - it.isNotEmpty() && it.isNotBlank() && !it.startsWith('#') - }.map(String::trim).filter(::isJavaClassName) -} catch (e: Throwable) { - emptyList() -} - -private fun isJavaClassName(text: String): Boolean { - if (!Character.isJavaIdentifierStart(text[0])) { - throw ServiceConfigurationError("Illegal provider-class name: $text") - } - - for (i in 1 until text.length) { - val cp = text.codePointAt(i) - if (!Character.isJavaIdentifierPart(cp) && cp != '.'.toInt()) { - throw ServiceConfigurationError("Illegal provider-class name: $text") - } - } - - return true -} \ No newline at end of file diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/AbsClassTransformer.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/AbsClassTransformer.kt deleted file mode 100644 index 5c909b387..000000000 --- a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/AbsClassTransformer.kt +++ /dev/null @@ -1,40 +0,0 @@ -package com.didichuxing.doraemonkit.plugin.classtransformer - -import com.didichuxing.doraemonkit.plugin.DoKitExtUtil -import com.didichuxing.doraemonkit.plugin.isRelease -import com.didichuxing.doraemonkit.plugin.println -import com.didiglobal.booster.transform.TransformContext -import com.didiglobal.booster.transform.asm.ClassTransformer -import com.didiglobal.booster.transform.asm.className -import org.objectweb.asm.tree.ClassNode - -/** - * ================================================ - * 作 者:jint(金台) - * 版 本:1.0 - * 创建日期:2021/5/12-18:06 - * 描 述: - * 修订历史: - * ================================================ - */ - -open class AbsClassTransformer : ClassTransformer { - - - fun onCommInterceptor(context: TransformContext, klass: ClassNode): Boolean { -// "===onCommInterceptor--->$this====${klass.className}===".println() - if (context.isRelease()) { - return true - } - - if (!DoKitExtUtil.dokitPluginSwitchOpen()) { - return true - } - //过滤kotlin module-info - if (klass.className == "module-info") { - return true - } - - return false - } -} \ No newline at end of file diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/CommClassTransformer.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/CommClassTransformer.kt deleted file mode 100644 index 75dcfbecb..000000000 --- a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/CommClassTransformer.kt +++ /dev/null @@ -1,1230 +0,0 @@ -package com.didichuxing.doraemonkit.plugin.classtransformer - -import com.didichuxing.doraemonkit.plugin.* -import com.didichuxing.doraemonkit.plugin.extension.SlowMethodExt -import com.didiglobal.booster.annotations.Priority -import com.didiglobal.booster.kotlinx.asIterable -import com.didiglobal.booster.transform.TransformContext -import com.didiglobal.booster.transform.asm.ClassTransformer -import com.didiglobal.booster.transform.asm.className -import com.google.auto.service.AutoService -import org.objectweb.asm.Label -import org.objectweb.asm.Opcodes.* -import org.objectweb.asm.tree.* - -/** - * ================================================ - * 作 者:jint(金台) - * 版 本:1.0 - * 创建日期:2020/5/14-18:07 - * 描 述:wiki:https://juejin.im/post/5e8d87c4f265da47ad218e6b - * 修订历史: - * ================================================ - */ -//@Priority(0) -//@AutoService(ClassTransformer::class) -class CommClassTransformer : AbsClassTransformer() { - - - private val SHADOW_URL = - "com/didichuxing/doraemonkit/aop/urlconnection/HttpUrlConnectionProxyUtil" - private val DESC = "(Ljava/net/URLConnection;)Ljava/net/URLConnection;" - - - /** - * 转化 - */ - override fun transform(context: TransformContext, klass: ClassNode): ClassNode { - - if (onCommInterceptor(context, klass)) { - return klass - } - - - val className = klass.className - val superName = klass.formatSuperName - -// if (className.contains("didihttp")) { -// "${context.projectDir.lastPath()}==className===>$className".println() -// } - - //查找DoraemonKitReal&pluginConfig方法并插入指定字节码 - if (className == "com.didichuxing.doraemonkit.DoKitReal") { - //插件配置 - klass.methods?.find { - it.name == "pluginConfig" - }.let { methodNode -> - "${context.projectDir.lastPath()}->insert map to the DoKitReal pluginConfig succeed".println() - methodNode?.instructions?.insert(createPluginConfigInsnList()) - } - //三方库信息注入 - klass.methods?.find { - it.name == "initThirdLibraryInfo" - }.let { methodNode -> - "${context.projectDir.lastPath()}->insert map to the DoKitReal initThirdLibraryInfo succeed".println() - methodNode?.instructions?.insert(createThirdLibInfoInsnList()) - } - } - - //gps字节码操作 - if (DoKitExtUtil.commExt.gpsSwitch && DoKitExtUtil.DOKIT_GPS_MOCK_INCLUDE) { - //系统 gpsStatus hook - klass.methods.forEach { method -> - method.instructions?.iterator()?.asIterable() - ?.filterIsInstance(MethodInsnNode::class.java)?.filter { - it.opcode == INVOKEVIRTUAL && - it.owner == "android/location/LocationManager" && - it.name == "getGpsStatus" && - it.desc == "(Landroid/location/GpsStatus;)Landroid/location/GpsStatus;" - }?.forEach { - "${context.projectDir.lastPath()}->hook LocationManager#getGpsStatus method succeed in : ${className}_${method.name}_${method.desc}".println() - method.instructions.insert( - it, - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/gps_mock/location/GpsStatusUtil", - "wrap", - "(Landroid/location/GpsStatus;)Landroid/location/GpsStatus;", - false - ) - ) - } - } - - //插入高德地图定位相关字节码 - if (className == "com.amap.api.location.AMapLocationClient") { - //设置监听器 - klass.methods?.find { - it.name == "setLocationListener" - }.let { methodNode -> - "${context.projectDir.lastPath()}->hook amap map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() - methodNode?.instructions?.insert(createAmapLocationInsnList()) - } - - //反注册监听器 - klass.methods?.find { - it.name == "unRegisterLocationListener" - }.let { methodNode -> - "${context.projectDir.lastPath()}->hook amap map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() - methodNode?.instructions?.insert( - createAmapLocationUnRegisterInsnList() - ) - } - - //代理getLastKnownLocation - klass.methods?.find { - it.name == "getLastKnownLocation" - }.let { methodNode -> - "${context.projectDir.lastPath()}->hook AMapLocationClient getLastKnownLocation succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() - methodNode?.instructions?.insert(createAMapClientLastKnownLocation()) - } - - } - //插入高德 地图定位相关字节码 -// if (className == "com.amap.api.maps.AMap") { -// //设置LocationSource代理 -// klass.methods?.find { -// it.name == "setLocationSource" -// }.let { methodNode -> -// "${context.projectDir.lastPath()}->hook amap map LocationSource succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() -// methodNode?.instructions?.insert(createAmapLocationSourceInsnList()) -// } -// } - - //插入高德地图导航相关字节码 - if (className == "com.amap.api.navi.AMapNavi") { - //设置监听器 - klass.methods?.find { - it.name == "addAMapNaviListener" - }.let { methodNode -> - "${context.projectDir.lastPath()}->hook amap map navi succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() - methodNode?.instructions?.insert(createAmapNaviInsnList()) - } -// -// //反注册监听器 - klass.methods?.find { - it.name == "removeAMapNaviListener" - }.let { methodNode -> - "${context.projectDir.lastPath()}->hook amap map navi succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() - methodNode?.instructions?.insert( - createAmapNaviUnRegisterInsnList() - ) - } - } - - - //插入腾讯地图相关字节码 - if (className == "com.tencent.map.geolocation.TencentLocationManager") { - //持续定位和单次定位 - klass.methods?.filter { - it.name == "requestSingleFreshLocation" || it.name == "requestLocationUpdates" - }?.forEach { methodNode -> - "${context.projectDir.lastPath()}->hook tencent map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() - methodNode?.instructions?.insert(createTencentLocationInsnList()) - } - - - //反注册监听器 - klass.methods?.find { - it.name == "removeUpdates" - }.let { methodNode -> - "${context.projectDir.lastPath()}->hook tencent map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() - methodNode?.instructions?.insert( - createTencentLocationUnRegisterInsnList() - ) - } - } - - //插入百度地图相关字节码 - if (className == "com.baidu.location.LocationClient") { - //拦截注册监听器 - klass.methods?.filter { - it.name == "registerLocationListener" - && (it.desc == "(Lcom/baidu/location/BDLocationListener;)V" || it.desc == "(Lcom/baidu/location/BDAbstractLocationListener;)V") - }?.forEach { methodNode -> - "${context.projectDir.lastPath()}->hook baidu map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() - if (methodNode.desc == "(Lcom/baidu/location/BDLocationListener;)V") { - methodNode?.instructions?.insert(createBDLocationListenerInsnList()) - } else if (methodNode.desc == "(Lcom/baidu/location/BDAbstractLocationListener;)V") { - methodNode?.instructions?.insert(createBDLocationAbsListenerInsnList()) - } - } - - - //反注册监听器 - klass.methods?.find { - it.name == "unRegisterLocationListener" && it.desc == "(Lcom/baidu/location/BDLocationListener;)V" - }.let { methodNode -> - "${context.projectDir.lastPath()}->hook baidu map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() - methodNode?.instructions?.insert( - createBDLocationUnRegisterInsnList() - ) - } - - - //反注册监听器 - klass.methods?.find { - it.name == "unRegisterLocationListener" && it.desc == "(Lcom/baidu/location/BDAbstractLocationListener;)V" - }.let { methodNode -> - "${context.projectDir.lastPath()}->hook baidu map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() - methodNode?.instructions?.insert( - createBDAbsLocationUnRegisterInsnList() - ) - } - } - } - - - //网络 OkHttp&didi platform aop - if (DoKitExtUtil.commExt.networkSwitch) { - //hook OkhttpClient - if (className == "okhttp3.OkHttpClient") { - klass.methods?.find { - it.name == "" && it.desc != "()V" - }.let { - "${context.projectDir.lastPath()}->hook OkhttpClient succeed: ${className}_${it?.name}_${it?.desc}".println() - it?.instructions - ?.iterator() - ?.asIterable() - ?.filterIsInstance(FieldInsnNode::class.java) - ?.filter { fieldInsnNode -> - fieldInsnNode.opcode == PUTFIELD - && fieldInsnNode.owner == "okhttp3/OkHttpClient" - && fieldInsnNode.name == "networkInterceptors" - && fieldInsnNode.desc == "Ljava/util/List;" - }?.forEach { fieldInsnNode -> - it.instructions.insert(fieldInsnNode, createOkHttpClientInsnList()) - } - } - } - - //didi platform 判断是否引入了dokit-rpc模块 - if (className == "didihttp.DidiHttpClient" && DoKitExtUtil.commExt.didinetSwitch && DoKitExtUtil.HAS_DOKIT_RPC_MODULE) { - klass.methods?.find { - it.name == "" && it.desc != "()V" - }.let { - "${context.projectDir.lastPath()}->hook DidiHttpClient succeed: ${className}_${it?.name}_${it?.desc}".println() - it?.instructions - ?.iterator() - ?.asIterable() - ?.filterIsInstance(FieldInsnNode::class.java) - ?.filter { fieldInsnNode -> - fieldInsnNode.opcode == PUTFIELD - && fieldInsnNode.owner == "didihttp/DidiHttpClient" - && fieldInsnNode.name == "networkInterceptors" - && fieldInsnNode.desc == "Ljava/util/List;" - } - ?.forEach { fieldInsnNode -> - it.instructions.insert( - fieldInsnNode, - createDidiHttpClientInsnList() - ) - } - } - } - - - //hook tcp 支持tcp消息hook - if (className == "com.didi.daijia.tcp.message.MessageSender") { - klass.methods?.find { - it.name == "sendMessage" && it.desc == "(Ljava/lang/String;)Z" - }.let { - "${context.projectDir.lastPath()}->hook tcp MessageSender succeed: ${className}_${it?.name}_${it?.desc}".println() - val first = it?.instructions?.first - if (first != null) { - it.instructions.insert(first, createMessageSenderHookInsnList()) - } - } - } - if (className == "com.didi.daijia.tcp.message.MessageReceiver") { - klass.methods?.find { - it.name == "channelRead" && it.desc == "(Ljava/lang/Object;)V" - }.let { - "${context.projectDir.lastPath()}->hook tcp MessageReceiver succeed: ${className}_${it?.name}_${it?.desc}".println() - val first = it?.instructions?.first - if (first != null) { - it.instructions.insert(first, createMessageReceiverHookInsnList()) - } - } - } - - - //webView 字节码操作 - if (DoKitExtUtil.commExt.webViewSwitch) { - //普通的webview - klass.methods.forEach { method -> - method.instructions?.iterator()?.asIterable() - ?.filterIsInstance(MethodInsnNode::class.java)?.filter { - if ("loadUrl".equals(it.name)) { - "hook loadUrl() all ${className} ^${superName}^${it.owner} :: ${it.name} , ${it.desc} ,${it.opcode}".println() - } - (it.opcode == INVOKEVIRTUAL || it.opcode == INVOKESPECIAL) && - it.name == "loadUrl" && - (it.desc == "(Ljava/lang/String;)V" || it.desc == "(Ljava/lang/String;Ljava/util/Map;)V") && - isWebViewOwnerNameMatched(it.owner) - }?.forEach { - "${context.projectDir.lastPath()}->hook WebView#loadurl method succeed in : ${className}_${method.name}_${method.desc} | ${it.owner}".println() - if (it.desc == "(Ljava/lang/String;)V") { - method.instructions.insertBefore( - it, - createWebViewInsnList() - ) - } else { - val size = method.localVariables.size - val insn = with(InsnList()) { - add(VarInsnNode(ASTORE, size + 1)) - add(VarInsnNode(ASTORE, size)) - add(InsnNode(DUP)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/aop/WebViewHook", - "inject", - "(Ljava/lang/Object;)V", - false - ) - ) - add(VarInsnNode(ALOAD, size)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/aop/WebViewHook", - "getSafeUrl", - "(Ljava/lang/String;)Ljava/lang/String;", - false - ) - ) - add(VarInsnNode(ALOAD, size + 1)) - this - } - method.instructions.insertBefore(it, insn) - } - - } - } - } - - // url connection - klass.methods.forEach { method -> - method.instructions?.iterator()?.asIterable() - ?.filterIsInstance(MethodInsnNode::class.java)?.filter { - it.opcode == INVOKEVIRTUAL && - it.owner == "java/net/URL" && - it.name == "openConnection" && - it.desc == "()Ljava/net/URLConnection;" - }?.forEach { - "${context.projectDir.lastPath()}->hook URL#openConnection method succeed in : ${className}_${method.name}_${method.desc}".println() - method.instructions.insert( - it, - MethodInsnNode(INVOKESTATIC, SHADOW_URL, "proxy", DESC, false) - ) - } - } - - } - - - //hook Androidx的ComponentActivity - if (className != "com.didichuxing.doraemonkit.aop.mc.DoKitProxyActivity" && superName == "android.app.Activity") { - createComponentActivitySuperActivityImpl(klass) - } - - - //hook androidx的AppCompatDelegateImpl -// if (className == "androidx.appcompat.app.AppCompatDelegate") { -// klass.methods?.filter { -// it.name == "create" -// && (it.desc == "(Landroid/app/Activity;Landroidx/appcompat/app/AppCompatCallback;)Landroidx/appcompat/app/AppCompatDelegate;" -// || it.desc == "(Landroid/app/Dialog;Landroidx/appcompat/app/AppCompatCallback;)Landroidx/appcompat/app/AppCompatDelegate;" -// || it.desc == "(Landroid/content/Context;Landroid/view/Window;Landroidx/appcompat/app/AppCompatCallback;)Landroidx/appcompat/app/AppCompatDelegate;" -// || it.desc == "(Landroid/content/Context;Landroid/app/Activity;Landroidx/appcompat/app/AppCompatCallback;)Landroidx/appcompat/app/AppCompatDelegate;") -// }?.asIterable() -// ?.forEach { methodNode -> -// //操作方法 -// val typeInsnNodes = methodNode.instructions -// ?.iterator() -// ?.asIterable() -// ?.filterIsInstance(TypeInsnNode::class.java) -// //操作New指令 -// typeInsnNodes?.filter { -// it.opcode == NEW && it.desc == "androidx/appcompat/app/AppCompatDelegateImpl" -// }?.forEach { -// "${context.projectDir.lastPath()}->hook ${klass.name}-${methodNode.name}-${it.opcode}-${it.desc} succeed".println() -// methodNode.instructions.insertBefore( -// it, -// createNewDoKitAppCompatDelegateImplInsnList() -// ) -// } -// -// //操作方法 -// val methodInsnNodes = methodNode.instructions -// ?.iterator() -// ?.asIterable() -// ?.filterIsInstance(MethodInsnNode::class.java) -// -// methodInsnNodes?.filter { -// //"${context.projectDir.lastPath()}->hook AppCompatDelegate create matched ${it.opcode} ${it.ownerClassName} ${it.name}".println() -// it.opcode == INVOKESPECIAL -// && it.ownerClassName == "androidx.appcompat.app.AppCompatDelegateImpl" -// && it.name == "" -// }?.forEach { -// //"${context.projectDir.lastPath()}->hook AppCompatDelegate create method succeed".println() -// "${context.projectDir.lastPath()}->hook ${klass.name}-${methodNode.name}-${it.owner}-${it.name}-${it.desc} succeed".println() -// methodNode.instructions.insert( -// it, -// MethodInsnNode( -// INVOKESPECIAL, -// "androidx/appcompat/app/DoKitAppCompatDelegateImpl", -// "", -// "(Landroidx/appcompat/app/AppCompatDelegate;)V", -// false -// ) -// ) -// } -// } -// } - - //hook 所有的view的事件 -// klass.methods?.forEach { methodNode -> -// if (methodNode.name == "onClick" && methodNode.desc == "(Landroid/view/View;)V") { -// val insnList = with(InsnList()) { -// add(VarInsnNode(ALOAD, 1)) -// add( -// MethodInsnNode( -// INVOKESTATIC, -// "com/didichuxing/doraemonkit/aop/mc/DoKitListenerHelper", -// "hookViewClickListener", -// "(Landroid/view/View;)V", -// false -// ) -// ) -// this -// } -// methodNode.instructions.insert(insnList) -// } -// } - - - // hook 所有的View -// if (className != "com.didichuxing.doraemonkit.aop.mc.DoKitProxyView" && superName == "android.view.View") { -// createViewImpl(klass) -// } - - // hook 所有的ViewGroup -// if (className != "com.didichuxing.doraemonkit.aop.mc.DoKitProxyViewGroup" && superName == "android.view.ViewGroup") { -// createViewGroupImpl(klass) -// } - -// if (className == "androidx.appcompat.app.AppCompatDelegateImpl") { -// //插件配置 -// klass.methods?.find { -// it.name == "onCreateView" && it.desc == "(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;" -// }.let { method -> -// method?.instructions?.iterator()?.asIterable() -// ?.filterIsInstance(MethodInsnNode::class.java)?.filter { -// it.opcode == INVOKEVIRTUAL && -// it.owner == "androidx/appcompat/app/AppCompatDelegateImpl" && -// it.name == "createView" && -// it.desc == "(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;" -// }?.forEach { -// "${context.projectDir.lastPath()}->hook AppCompatDelegateImpl onCreateView method succeed".println() -// method.instructions.insert( -// it, -// MethodInsnNode( -// INVOKESTATIC, -// "com/didichuxing/doraemonkit/aop/mc/AppCompatDelegateImplProxy", -// "onCreateView", -// "(Landroid/view/View;)Landroid/view/View;", -// false -// ) -// ) -// } -// } -// } - - return klass - } - - private fun isWebViewOwnerNameMatched(ownerName: String): Boolean { - return ownerName == "android/webkit/WebView" || - ownerName == "com/tencent/smtt/sdk/WebView" || - ownerName.contentEquals("WebView") || - ownerName == DoKitExtUtil.WEBVIEW_CLASS_NAME - } - - - /** - * 创建pluginConfig代码指令 - */ - private fun createPluginConfigInsnList(): InsnList { - //val insnList = InsnList() - return with(InsnList()) { - //new HashMap - add(TypeInsnNode(NEW, "java/util/HashMap")) - add(InsnNode(DUP)) - add(MethodInsnNode(INVOKESPECIAL, "java/util/HashMap", "", "()V", false)) - //保存变量 - add(VarInsnNode(ASTORE, 0)) - //获取第一个变量 - //put("dokitPluginSwitch",true) - add(VarInsnNode(ALOAD, 0)) - add(LdcInsnNode("dokitPluginSwitch")) - add(InsnNode(if (DoKitExtUtil.dokitPluginSwitchOpen()) ICONST_1 else ICONST_0)) - add( - MethodInsnNode( - INVOKESTATIC, - "java/lang/Boolean", - "valueOf", - "(Z)Ljava/lang/Boolean;", - false - ) - ) - add( - MethodInsnNode( - INVOKEINTERFACE, - "java/util/Map", - "put", - "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", - true - ) - ) - add(InsnNode(POP)) - - //put("gpsSwitch",true) - add(VarInsnNode(ALOAD, 0)) - add(LdcInsnNode("gpsSwitch")) - add(InsnNode(if (DoKitExtUtil.commExt.gpsSwitch) ICONST_1 else ICONST_0)) - add( - MethodInsnNode( - INVOKESTATIC, - "java/lang/Boolean", - "valueOf", - "(Z)Ljava/lang/Boolean;", - false - ) - ) - add( - MethodInsnNode( - INVOKEINTERFACE, - "java/util/Map", - "put", - "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", - true - ) - ) - add(InsnNode(POP)) - - //put("networkSwitch",true) - add(VarInsnNode(ALOAD, 0)) - add(LdcInsnNode("networkSwitch")) - add(InsnNode(if (DoKitExtUtil.commExt.networkSwitch) ICONST_1 else ICONST_0)) - add( - MethodInsnNode( - INVOKESTATIC, - "java/lang/Boolean", - "valueOf", - "(Z)Ljava/lang/Boolean;", - false - ) - ) - add( - MethodInsnNode( - INVOKEINTERFACE, - "java/util/Map", - "put", - "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", - true - ) - ) - add(InsnNode(POP)) - - //put("bigImgSwitch",true) - add(VarInsnNode(ALOAD, 0)) - add(LdcInsnNode("bigImgSwitch")) - add(InsnNode(if (DoKitExtUtil.commExt.bigImgSwitch) ICONST_1 else ICONST_0)) - add( - MethodInsnNode( - INVOKESTATIC, - "java/lang/Boolean", - "valueOf", - "(Z)Ljava/lang/Boolean;", - false - ) - ) - add( - MethodInsnNode( - INVOKEINTERFACE, - "java/util/Map", - "put", - "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", - true - ) - ) - add(InsnNode(POP)) - - //put("methodSwitch",true) - add(VarInsnNode(ALOAD, 0)) - add(LdcInsnNode("methodSwitch")) - add(InsnNode(if (DoKitExtUtil.dokitSlowMethodSwitchOpen()) ICONST_1 else ICONST_0)) - add( - MethodInsnNode( - INVOKESTATIC, - "java/lang/Boolean", - "valueOf", - "(Z)Ljava/lang/Boolean;", - false - ) - ) - add( - MethodInsnNode( - INVOKEINTERFACE, - "java/util/Map", - "put", - "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", - true - ) - ) - add(InsnNode(POP)) - - - //put("methodStrategy",0) - add(VarInsnNode(ALOAD, 0)) - add(LdcInsnNode("methodStrategy")) - add(InsnNode(if (DoKitExtUtil.SLOW_METHOD_STRATEGY == SlowMethodExt.STRATEGY_STACK) ICONST_0 else ICONST_1)) - add( - MethodInsnNode( - INVOKESTATIC, - "java/lang/Integer", - "valueOf", - "(I)Ljava/lang/Integer;", - false - ) - ) - add( - MethodInsnNode( - INVOKEINTERFACE, - "java/util/Map", - "put", - "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", - true - ) - ) - add(InsnNode(POP)) - - //将HashMap注入到DokitPluginConfig中 - add(VarInsnNode(ALOAD, 0)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/aop/DokitPluginConfig", - "inject", - "(Ljava/util/Map;)V", - false - ) - ) - - this - } - - //return insnList - - } - - - /** - * 创建pluginConfig代码指令 - */ - private fun createThirdLibInfoInsnList(): InsnList { - //val insnList = InsnList() - return with(InsnList()) { - //new HashMap - add(TypeInsnNode(NEW, "java/util/HashMap")) - add(InsnNode(DUP)) - add(MethodInsnNode(INVOKESPECIAL, "java/util/HashMap", "", "()V", false)) - //保存变量 - add(VarInsnNode(ASTORE, 0)) - DoKitExtUtil.THIRD_LIB_INFOS.forEach { thirdLibInfo -> - add(VarInsnNode(ALOAD, 0)) - add(LdcInsnNode(thirdLibInfo.variant)) - add(LdcInsnNode(thirdLibInfo.fileSize.toString())) - - add( - MethodInsnNode( - INVOKEINTERFACE, - "java/util/Map", - "put", - "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", - false - ) - ) - add(InsnNode(POP)) - } - - - //将HashMap注入到DokitPluginConfig中 - add(VarInsnNode(ALOAD, 0)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/aop/DokitThirdLibInfo", - "inject", - "(Ljava/util/Map;)V", - false - ) - ) - - this - } - - //return insnList - - } - - - /** - * 创建Amap地图代码指令 - */ - private fun createAmapLocationInsnList(): InsnList { - return with(InsnList()) { - //在AMapLocationClient的 setLocationListener 方法之中插入自定义代理回调类 - add(TypeInsnNode(NEW, "com/didichuxing/doraemonkit/gps_mock/map/AMapLocationListenerProxy")) - add(InsnNode(DUP)) - //访问第一个参数 - add(VarInsnNode(ALOAD, 1)) - add( - MethodInsnNode( - INVOKESPECIAL, - "com/didichuxing/doraemonkit/gps_mock/map/AMapLocationListenerProxy", - "", - "(Lcom/amap/api/location/AMapLocationListener;)V", - false - ) - ) - //对第一个参数进行重新赋值 - add(VarInsnNode(ASTORE, 1)) - this - } - - } - - /** - * 创建Amap地图导航代码指令 - */ - private fun createAmapNaviInsnList(): InsnList { - return with(InsnList()) { - //在AMapNavi的addAMapNaviListener方法之中插入自定义代理回调类 - add(TypeInsnNode(NEW, "com/didichuxing/doraemonkit/gps_mock/map/AMapNaviListenerProxy")) - add(InsnNode(DUP)) - //访问第一个参数 - add(VarInsnNode(ALOAD, 1)) - add( - MethodInsnNode( - INVOKESPECIAL, - "com/didichuxing/doraemonkit/gps_mock/map/AMapNaviListenerProxy", - "", - "(Lcom/amap/api/navi/AMapNaviListener;)V", - false - ) - ) - //对第一个参数进行重新赋值 - add(VarInsnNode(ASTORE, 1)) - this - } - - } - - - /** - * 创建Amap LocationSource代码指令 - */ - private fun createAmapLocationSourceInsnList(): InsnList { - return with(InsnList()) { - //在AMapNavi的addAMapNaviListener方法之中插入自定义代理回调类 - add(TypeInsnNode(NEW, "com/didichuxing/doraemonkit/gps_mock/map/AMapLocationSourceProxy")) - add(InsnNode(DUP)) - //访问第一个参数 - add(VarInsnNode(ALOAD, 1)) - add( - MethodInsnNode( - INVOKESPECIAL, - "com/didichuxing/doraemonkit/gps_mock/map/AMapLocationSourceProxy", - "", - "(Lcom/amap/api/maps/LocationSource;)V", - false - ) - ) - //对第一个参数进行重新赋值 - add(VarInsnNode(ASTORE, 1)) - this - } - - } - - /** - * 创建AMapLocationClient#LastKnownLocation 字节码替换 - */ - private fun createAMapClientLastKnownLocation(): InsnList { - return with(InsnList()) { - add(VarInsnNode(ALOAD, 0)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/gps_mock/map/AMapLocationClientProxy", - "getLastKnownLocation", - "(Lcom/amap/api/location/AMapLocationClient;)Lcom/amap/api/location/AMapLocation;", - false - ) - ) -// add(VarInsnNode(ASTORE, 1)) -// add(VarInsnNode(ALOAD, 1)) - add(InsnNode(ARETURN)) - this - } - - } - - /** - * 创建Amap地图UnRegister代码指令 - */ - private fun createAmapLocationUnRegisterInsnList(): InsnList { - return with(InsnList()) { - //访问第一个参数 - add(VarInsnNode(ALOAD, 1)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/gps_mock/map/ThirdMapLocationListenerUtil", - "unRegisterAmapLocationListener", - "(Lcom/amap/api/location/AMapLocationListener;)Lcom/didichuxing/doraemonkit/gps_mock/map/AMapLocationListenerProxy;", - false - ) - ) - add(VarInsnNode(ASTORE, 1)) - this - } - } - - /** - * 创建Amap地图 Navi UnRegister代码指令 - */ - private fun createAmapNaviUnRegisterInsnList(): InsnList { - return with(InsnList()) { - //访问第一个参数 - add(VarInsnNode(ALOAD, 1)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/gps_mock/map/ThirdMapLocationListenerUtil", - "unRegisterAmapNaviListener", - "(Lcom/amap/api/navi/AMapNaviListener;)Lcom/didichuxing/doraemonkit/gps_mock/map/AMapNaviListenerProxy;", - false - ) - ) - add(VarInsnNode(ASTORE, 1)) - this - } - - } - - - /** - * 创建tencent地图代码指令 - */ - private fun createTencentLocationInsnList(): InsnList { - return with(InsnList()) { - //在AMapLocationClient的setLocationListener方法之中插入自定义代理回调类 - add( - TypeInsnNode( - NEW, - "com/didichuxing/doraemonkit/gps_mock/map/TencentLocationListenerProxy" - ) - ) - add(InsnNode(DUP)) - //访问第一个参数 - add(VarInsnNode(ALOAD, 2)) - add( - MethodInsnNode( - INVOKESPECIAL, - "com/didichuxing/doraemonkit/gps_mock/map/TencentLocationListenerProxy", - "", - "(Lcom/tencent/map/geolocation/TencentLocationListener;)V", - false - ) - ) - //对第二个参数进行重新赋值 - add(VarInsnNode(ASTORE, 2)) - - this - } - - } - - - /** - * 创建Tencent地图UnRegister代码指令 - */ - private fun createTencentLocationUnRegisterInsnList(): InsnList { - return with(InsnList()) { - //访问第一个参数 - add(VarInsnNode(ALOAD, 1)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/gps_mock/map/ThirdMapLocationListenerUtil", - "unRegisterTencentLocationListener", - "(Lcom/tencent/map/geolocation/TencentLocationListener;)Lcom/didichuxing/doraemonkit/gps_mock/map/TencentLocationListenerProxy;", - false - ) - ) - add(VarInsnNode(ASTORE, 1)) - this - } - - } - - - /** - * 创建百度地图代码指令 - */ - private fun createBDLocationListenerInsnList(): InsnList { - return with(InsnList()) { - //在LocationClient的registerLocationListener方法之中插入自定义代理回调类 - add(TypeInsnNode(NEW, "com/didichuxing/doraemonkit/gps_mock/map/BDLocationListenerProxy")) - add(InsnNode(DUP)) - //访问第一个参数 - add(VarInsnNode(ALOAD, 1)) - add( - MethodInsnNode( - INVOKESPECIAL, - "com/didichuxing/doraemonkit/gps_mock/map/BDLocationListenerProxy", - "", - "(Lcom/baidu/location/BDLocationListener;)V", - false - ) - ) - //对第一个参数进行重新赋值 - add(VarInsnNode(ASTORE, 1)) - - this - } - - } - - /** - * 创建百度地图代码指令 - */ - private fun createBDLocationAbsListenerInsnList(): InsnList { - return with(InsnList()) { - //在LocationClient的registerLocationListener方法之中插入自定义代理回调类 - add(TypeInsnNode(NEW, "com/didichuxing/doraemonkit/gps_mock/map/BDAbsLocationListenerProxy")) - add(InsnNode(DUP)) - //访问第一个参数 - add(VarInsnNode(ALOAD, 1)) - add( - MethodInsnNode( - INVOKESPECIAL, - "com/didichuxing/doraemonkit/gps_mock/map/BDAbsLocationListenerProxy", - "", - "(Lcom/baidu/location/BDAbstractLocationListener;)V", - false - ) - ) - //对第一个参数进行重新赋值 - add(VarInsnNode(ASTORE, 1)) - this - } - } - - - /** - * 创建百度地图UnRegister代码指令 - */ - private fun createBDLocationUnRegisterInsnList(): InsnList { - return with(InsnList()) { - //访问第一个参数 - add(VarInsnNode(ALOAD, 1)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/gps_mock/map/ThirdMapLocationListenerUtil", - "unRegisterBDLocationListener", - "(Lcom/baidu/location/BDLocationListener;)Lcom/didichuxing/doraemonkit/gps_mock/map/BDLocationListenerProxy;", - false - ) - ) - add(VarInsnNode(ASTORE, 1)) - this - } - - } - - /** - * 创建百度地图UnRegister代码指令 - */ - private fun createBDAbsLocationUnRegisterInsnList(): InsnList { - return with(InsnList()) { - //访问第一个参数 - add(VarInsnNode(ALOAD, 1)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/gps_mock/map/ThirdMapLocationListenerUtil", - "unRegisterBDLocationListener", - "(Lcom/baidu/location/BDAbstractLocationListener;)Lcom/didichuxing/doraemonkit/gps_mock/map/BDAbsLocationListenerProxy;", - false - ) - ) - //对第一个参数进行重新赋值 - add(VarInsnNode(ASTORE, 1)) - this - } - - } - - /** - * 创建百度地图代码指令 - */ - private fun createBaiduLocationInsnList(): InsnList { - return with(InsnList()) { - //在AMapLocationClient的setLocationListener方法之中插入自定义代理回调类 - add(VarInsnNode(ALOAD, 1)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/gps_mock/map/BDLocationUtil", - "proxy", - "(Lcom/baidu/location/BDLocation;)Lcom/baidu/location/BDLocation;", - false - ) - ) - //对第一个参数进行重新赋值 - add(VarInsnNode(ASTORE, 1)) - this - } - - } - - /** - * 创建OkhttpClient一个数构造函数指令 - */ - private fun createOkHttpClientInsnList(): InsnList { - return with(InsnList()) { - //插入application 拦截器 - add(VarInsnNode(ALOAD, 0)) - - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/aop/OkHttpHook", - "addDoKitIntercept", - "(Lokhttp3/OkHttpClient;)V", - false - ) - ) - this - } - - } - - /** - * 创建OkhttpClient一个数构造函数指令 - */ - private fun createMessageSenderHookInsnList(): InsnList { - return with(InsnList()) { - //插入application 拦截器 - val l0= LabelNode() - add(l0) - add(VarInsnNode(ALOAD, 0)) - add(VarInsnNode(ALOAD, 1)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/tcp/ability/MessageSenderHook", - "hookSendMessage", - "(Lcom/didi/daijia/tcp/message/MessageSender;Ljava/lang/Object;)Z", - false - ) - ) - val l1= LabelNode() - add(JumpInsnNode(IFEQ,l1)) - val l2= LabelNode() - add(l2) - add(InsnNode(ICONST_1)) - add(InsnNode(IRETURN)) - add(l1) - add(FrameNode(F_SAME,0,null,0,null)) - this - } - - } - /** - * 创建OkhttpClient一个数构造函数指令 - */ - private fun createMessageReceiverHookInsnList(): InsnList { - return with(InsnList()) { - //插入application 拦截器 - val l0= LabelNode() - add(l0) - add(VarInsnNode(ALOAD, 0)) - add(VarInsnNode(ALOAD, 1)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/tcp/ability/MessageReceiverHook", - "hookChannelRead", - "(Lcom/didi/daijia/tcp/message/MessageReceiver;Ljava/lang/Object;)Z", - false - ) - ) - val l1= LabelNode() - add(JumpInsnNode(IFEQ,l1)) - val l2= LabelNode() - add(l2) - add(InsnNode(RETURN)) - add(l1) - add(FrameNode(F_SAME,0,null,0,null)) - this - } - - } - - /** - * 创建OkhttpClient一个数构造函数指令 - */ - private fun createDidiHttpClientInsnList(): InsnList { - return with(InsnList()) { - //插入application 拦截器 - add(VarInsnNode(ALOAD, 0)) - - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/foundation/net/rpc/http/DidiHttpHook", - "addRpcIntercept", - "(Ldidihttp/DidiHttpClient;)V", - false - ) - ) - this - } - - } - - /** - * 创建webView函数指令集 - * 参考:https://www.jianshu.com/p/7d623f441bed - */ - private fun createWebViewInsnList(): InsnList { - return with(InsnList()) { - //复制栈顶的2个指令 指令集变为 比如 aload 2 aload0 / aload 2 aload0 - add(InsnNode(DUP2)) - //抛出最上面的指令 指令集变为 aload 2 aload0 / aload 2 其中 aload 2即为我们所需要的对象 - add(InsnNode(POP)) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/aop/WebViewHook", - "inject", - "(Ljava/lang/Object;)V", - false - ) - ) - add( - MethodInsnNode( - INVOKESTATIC, - "com/didichuxing/doraemonkit/aop/WebViewHook", - "getSafeUrl", - "(Ljava/lang/String;)Ljava/lang/String;", - false - ) - ) - this - } - } - - - /** - * 创建new DoKitAppCompatDelegateImpl指令集 - */ - private fun createNewDoKitAppCompatDelegateImplInsnList(): InsnList { - return with(InsnList()) { - add(TypeInsnNode(NEW, "androidx/appcompat/app/DoKitAppCompatDelegateImpl")) - add(InsnNode(DUP)) - this - } - } - - - /** - * 重置ComponentActivity的父类 - */ - private fun createComponentActivitySuperActivityImpl(klass: ClassNode) { - /** - * 修改继承的父类 - */ - klass.superName = "com/didichuxing/doraemonkit/aop/mc/DoKitProxyActivity" - } - - - /** - * 重置View的父类 - */ - private fun createViewImpl(klass: ClassNode) { - /** - * 修改继承的父类 - */ - klass.superName = "com/didichuxing/doraemonkit/aop/mc/DoKitProxyView" - } - - - /** - * 重置ViewGroup的父类 - */ - private fun createViewGroupImpl(klass: ClassNode) { - /** - * 修改继承的父类 - */ - klass.superName = "com/didichuxing/doraemonkit/aop/mc/DoKitProxyViewGroup" - } - -} diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/UrlConnectionTransformer.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/UrlConnectionTransformer.kt deleted file mode 100644 index 641f7950b..000000000 --- a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/UrlConnectionTransformer.kt +++ /dev/null @@ -1,68 +0,0 @@ -package com.didichuxing.doraemonkit.plugin.classtransformer - -import com.didichuxing.doraemonkit.plugin.DoKitExtUtil -import com.didichuxing.doraemonkit.plugin.isRelease -import com.didichuxing.doraemonkit.plugin.lastPath -import com.didichuxing.doraemonkit.plugin.println -import com.didiglobal.booster.annotations.Priority -import com.didiglobal.booster.kotlinx.asIterable -import com.didiglobal.booster.transform.TransformContext -import com.didiglobal.booster.transform.asm.ClassTransformer -import com.didiglobal.booster.transform.asm.className -import com.google.auto.service.AutoService -import org.objectweb.asm.Opcodes.INVOKESTATIC -import org.objectweb.asm.Opcodes.INVOKEVIRTUAL -import org.objectweb.asm.tree.ClassNode -import org.objectweb.asm.tree.MethodInsnNode - -/** - * ================================================ - * 作 者:jint(金台) - * 版 本:1.0 - * 创建日期:2020/5/14-18:07 - * 描 述:wiki:https://juejin.im/post/5e8d87c4f265da47ad218e6b - * 修订历史: - * ================================================ - */ -//@Priority(1) -//@AutoService(ClassTransformer::class) -class UrlConnectionTransformer : AbsClassTransformer() { - private val SHADOW_URL = - "com/didichuxing/doraemonkit/aop/urlconnection/HttpUrlConnectionProxyUtil" - private val DESC = "(Ljava/net/URLConnection;)Ljava/net/URLConnection;" - - override fun transform(context: TransformContext, klass: ClassNode): ClassNode { - if (onCommInterceptor(context, klass)) { - return klass - } - - if (!DoKitExtUtil.commExt.networkSwitch) { - return klass - } - - if (DoKitExtUtil.ignorePackageNames(klass.className)) { - return klass - } - - klass.methods.forEach { method -> - method.instructions?.iterator()?.asIterable() - ?.filterIsInstance(MethodInsnNode::class.java)?.filter { - it.opcode == INVOKEVIRTUAL && - it.owner == "java/net/URL" && - it.name == "openConnection" && - it.desc == "()Ljava/net/URLConnection;" - }?.forEach { - "${context.projectDir.lastPath()}-> hook urlconnection succeed:${klass.name}_${it.name}_${it.desc}".println() - method.instructions.insert( - it, - MethodInsnNode(INVOKESTATIC, SHADOW_URL, "proxy", DESC, false) - ) - } - } - - return klass - } - - -} - diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/BigImageExtension.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/BigImageExtension.kt new file mode 100644 index 000000000..b96d6d8ba --- /dev/null +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/BigImageExtension.kt @@ -0,0 +1,48 @@ +package com.didichuxing.doraemonkit.plugin.extension + + +/** + * didi Create on 2023/3/21 . + * + * Copyright (c) 2023/3/21 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/21 6:07 下午 + * @Description 用一句话说明文件功能 + */ + +open class BigImageExtension( + var glide: Boolean = true, + var picasso: Boolean = true, + var fresco: Boolean = true, + var imageLoader: Boolean = true, + var coil: Boolean = true +) { + + + fun glide(boolean: Boolean) { + glide = boolean + } + + fun picasso(boolean: Boolean) { + picasso = boolean + } + + fun fresco(boolean: Boolean) { + fresco = boolean + } + + fun imageLoader(boolean: Boolean) { + imageLoader = boolean + } + + fun coil(boolean: Boolean) { + coil = boolean + } + + + override fun toString(): String { + return "BigImageExtension(glide=$glide, picasso=$picasso, Fresco=$fresco, imageLoader=$imageLoader, coil=$coil)" + } +} diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/CommExt.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/CommExt.kt deleted file mode 100644 index 4daa03899..000000000 --- a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/CommExt.kt +++ /dev/null @@ -1,46 +0,0 @@ -package com.didichuxing.doraemonkit.plugin.extension - -/** - * ================================================ - * 作 者:jint(金台) - * 版 本:1.0 - * 创建日期:2020/4/28-14:56 - * 描 述: - * 修订历史: - * ================================================ - */ -open class CommExt( - var gpsSwitch: Boolean = true, - var networkSwitch: Boolean = true, - var bigImgSwitch: Boolean = true, - var webViewSwitch: Boolean = true, - var didinetSwitch: Boolean = true -) { - - fun gpsSwitch(gpsSwitch: Boolean) { - this.gpsSwitch = gpsSwitch - } - - fun networkSwitch(networkSwitch: Boolean) { - this.networkSwitch = networkSwitch - } - - fun didinetSwitch(didinetSwitch: Boolean) { - this.didinetSwitch = didinetSwitch - } - - - fun bigImgSwitch(bigImgSwitch: Boolean) { - this.bigImgSwitch = bigImgSwitch - } - - fun webViewSwitch(webViewSwitch: Boolean) { - this.webViewSwitch = webViewSwitch - } - - override fun toString(): String { - return "CommExt(gpsSwitch=$gpsSwitch, networkSwitch=$networkSwitch,didinetSwitch=$didinetSwitch, bigImgSwitch=$bigImgSwitch, webviewSwitch=$webViewSwitch)" - } - - -} \ No newline at end of file diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/DoKitExt.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/DoKitExt.kt deleted file mode 100644 index b88b95f22..000000000 --- a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/DoKitExt.kt +++ /dev/null @@ -1,42 +0,0 @@ -package com.didichuxing.doraemonkit.plugin.extension - -import org.gradle.api.Action - -/** - * Created by jint on 07/10/2018. - */ -open class DoKitExt( - //var dokitPluginSwitch: Boolean = true, - var comm: CommExt = CommExt(), - var slowMethod: SlowMethodExt = SlowMethodExt()) { - - - //方法名必须和插件配置一直才能进行反射注入 -// fun dokitPluginSwitch(dokitPluginSwitch: Boolean) { -// this.dokitPluginSwitch = dokitPluginSwitch -// } - - /** - * 让comm 支持 DSL 语法 - * - * @param action - */ - fun comm(action: Action) { - action.execute(comm) - } - - /** - * 让slowMethod 支持 DSL 语法 - * - * @param action - */ - fun slowMethod(action: Action) { - action.execute(slowMethod) - } - - override fun toString(): String { - return "DoKitExt(comm=$comm, slowMethod=$slowMethod)" - } - - -} \ No newline at end of file diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/DoKitExtension.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/DoKitExtension.kt new file mode 100644 index 000000000..0f29b26d8 --- /dev/null +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/DoKitExtension.kt @@ -0,0 +1,82 @@ +package com.didichuxing.doraemonkit.plugin.extension + +import org.gradle.api.Action + +/** + * Created by jint on 07/10/2018. + * + * DoKit plugin 配置实例 @see DoKitExtension + * + * 支持DSL语法可以在插件中直接配置 + */ +open class DoKitExtension( + var pluginEnable: Boolean = true, + var logEnable: Boolean = true, + var thirdLibEnable: Boolean = true, + + var gpsEnable: Boolean = true, + var gps: GpsExtension = GpsExtension(), + + var networkEnable: Boolean = true, + var network: NetworkExtension = NetworkExtension(), + + var bigImageEnable: Boolean = true, + var bigImage: BigImageExtension = BigImageExtension(), + + var webViewEnable: Boolean = true, + var webView: WebViewExtension = WebViewExtension(), + + var slowMethodEnable: Boolean = true, + var slowMethod: SlowMethodExtension = SlowMethodExtension() +) { + + + /** + * gps 支持 DSL 语法 + * + * @param action + */ + fun gps(action: Action) { + action.execute(gps) + } + + /** + * network 支持 DSL 语法 + * + * @param action + */ + fun network(action: Action) { + action.execute(network) + } + + /** + * bigImage 支持 DSL 语法 + * + * @param action + */ + fun bigImage(action: Action) { + action.execute(bigImage) + } + + fun webView(action: Action) { + action.execute(webView) + } + + /** + * 让slowMethod 支持 DSL 语法 + * + * @param action + */ + fun slowMethod(action: Action) { + action.execute(slowMethod) + } + + + + + override fun toString(): String { + return "DoKitExtension(pluginEnable=$pluginEnable, logEnable=$logEnable, thirdLibEnable=$thirdLibEnable, gpsEnable=$gpsEnable, gps=$gps, networkEnable=$networkEnable, network=$network, bigImageEnable=$bigImageEnable, bigImage=$bigImage, webViewEnable=$webViewEnable, webView=$webView, slowMethodEnable=$slowMethodEnable, slowMethod=$slowMethod)" + } + + +} diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/GpsExtension.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/GpsExtension.kt new file mode 100644 index 000000000..dc97004e2 --- /dev/null +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/GpsExtension.kt @@ -0,0 +1,48 @@ +package com.didichuxing.doraemonkit.plugin.extension + + +/** + * didi Create on 2023/3/21 . + * + * Copyright (c) 2023/3/21 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/21 5:36 下午 + * @Description 用一句话说明文件功能 + * @see DoKitExtension + */ + +open class GpsExtension( + var local: Boolean = true, + var baidu: Boolean = true, + var tencent: Boolean = true, + var amap: Boolean = true, + var didi: Boolean = true +) { + + + fun local(boolean: Boolean) { + local = boolean + } + + fun baidu(boolean: Boolean) { + baidu = boolean + } + + fun tencent(boolean: Boolean) { + tencent = boolean + } + + fun amap(boolean: Boolean) { + amap = boolean + } + + fun didi(boolean: Boolean) { + didi = boolean + } + + override fun toString(): String { + return "GpsExtension(local=$local, baidu=$baidu, tencent=$tencent, didi=$didi)" + } +} diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/NetworkExtension.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/NetworkExtension.kt new file mode 100644 index 000000000..6bd287b86 --- /dev/null +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/NetworkExtension.kt @@ -0,0 +1,47 @@ +package com.didichuxing.doraemonkit.plugin.extension + + +/** + * didi Create on 2023/3/21 . + * + * Copyright (c) 2023/3/21 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/21 5:36 下午 + * @Description 用一句话说明文件功能 + */ + +open class NetworkExtension( + var okHttp: Boolean = true, + var urlConnect: Boolean = true, + var didiHttp: Boolean = true, + var didiSocket: Boolean = true, + var didiDjSocket: Boolean = true +) { + + + fun okHttp(boolean: Boolean) { + okHttp = boolean + } + + fun urlConnect(boolean: Boolean) { + urlConnect = boolean + } + + fun didiHttp(boolean: Boolean) { + didiHttp = boolean + } + + fun didiSocket(boolean: Boolean) { + didiSocket = boolean + } + + fun didiDjSocket(boolean: Boolean) { + didiDjSocket = boolean + } + + override fun toString(): String { + return "NetworkExtension(okHttp=$okHttp, urlConnect=$urlConnect, didiHttp=$didiHttp, didiSocket=$didiSocket, didiDjSocket=$didiDjSocket)" + } +} diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/SlowMethodExt.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/SlowMethodExtension.kt similarity index 98% rename from Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/SlowMethodExt.kt rename to Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/SlowMethodExtension.kt index 82844403e..ede80d619 100644 --- a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/SlowMethodExt.kt +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/SlowMethodExtension.kt @@ -2,7 +2,6 @@ package com.didichuxing.doraemonkit.plugin.extension import groovy.lang.Closure import org.gradle.util.ConfigureUtil -import java.util.* /** * ================================================ @@ -14,7 +13,7 @@ import java.util.* * ================================================ */ -open class SlowMethodExt( +open class SlowMethodExtension( //0:打印函数调用栈 1:普通模式 运行时打印某个函数的耗时 全局业务代码函数插入 @Deprecated("已弃用,请在项目根目录的gradle.properties中通过DOKIT_METHOD_STRATEGY=0|1 来控制") var strategy: Int = STRATEGY_STACK, @@ -125,4 +124,4 @@ open class SlowMethodExt( const val STRATEGY_STACK = 0 const val STRATEGY_NORMAL = 1 } -} \ No newline at end of file +} diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/WebViewExtension.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/WebViewExtension.kt new file mode 100644 index 000000000..1351b8df7 --- /dev/null +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/WebViewExtension.kt @@ -0,0 +1,38 @@ +package com.didichuxing.doraemonkit.plugin.extension + + +/** + * didi Create on 2023/3/21 . + * + * Copyright (c) 2023/3/21 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/21 6:10 下午 + * @Description 用一句话说明文件功能 + */ + +open class WebViewExtension( + var network: Boolean = true, + var dokitWeb: Boolean = false, + var vConsole: Boolean = false +) { + + fun network(boolean: Boolean) { + network = boolean + } + + fun dokitWeb(boolean: Boolean) { + dokitWeb = boolean + } + + fun vConsole(boolean: Boolean) { + vConsole = boolean + } + + override fun toString(): String { + return "WebViewExtension(network=$network, dokitWeb=$dokitWeb, vConsole=$vConsole)" + } + + +} diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/processor/DoKitComponentHandler.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/processor/DoKitComponentHandler.kt index ba6c0d60e..dc50de67d 100644 --- a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/processor/DoKitComponentHandler.kt +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/processor/DoKitComponentHandler.kt @@ -1,6 +1,5 @@ package com.didichuxing.doraemonkit.plugin.processor -import com.didichuxing.doraemonkit.plugin.println import org.xml.sax.Attributes import org.xml.sax.helpers.DefaultHandler @@ -58,4 +57,4 @@ class DoKitComponentHandler : DefaultHandler() { } } -} \ No newline at end of file +} diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/processor/DoKitPluginConfigProcessor.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/processor/DoKitPluginConfigProcessor.kt index 1525e60d9..8684e507e 100644 --- a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/processor/DoKitPluginConfigProcessor.kt +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/processor/DoKitPluginConfigProcessor.kt @@ -3,20 +3,16 @@ package com.didichuxing.doraemonkit.plugin.processor import com.android.build.gradle.AppExtension import com.android.build.gradle.api.ApplicationVariant import com.android.build.gradle.api.BaseVariant -import com.android.build.gradle.internal.pipeline.TransformTask import com.didichuxing.doraemonkit.plugin.* -import com.didichuxing.doraemonkit.plugin.extension.DoKitExt +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.thirdlib.ThirdLibInfo import com.didiglobal.booster.gradle.dependencies import com.didiglobal.booster.gradle.getAndroid import com.didiglobal.booster.gradle.mergedManifests import com.didiglobal.booster.gradle.project import com.didiglobal.booster.task.spi.VariantProcessor -import com.didiglobal.booster.transform.ArtifactManager -import com.didiglobal.booster.transform.artifacts -import com.didiglobal.booster.transform.util.ComponentHandler import org.gradle.api.Project import org.gradle.api.artifacts.result.ResolvedArtifactResult -import java.lang.NullPointerException import javax.xml.parsers.SAXParserFactory /** @@ -42,96 +38,32 @@ class DoKitPluginConfigProcessor(val project: Project) : VariantProcessor { if (DoKitExtUtil.THIRD_LIBINFO_SWITCH) { //遍历三方库 val dependencies = variant.dependencies - DoKitExtUtil.THIRD_LIB_INFOS.clear() for (artifactResult: ResolvedArtifactResult in dependencies) { - //println("三方库信息===>${artifactResult.variant.displayName}____${artifactResult.file.toString()}") - ///Users/didi/project/android/dokit_github/DoraemonKit/Android/java/app/libs/BaiduLBS_Android.jar - ///Users/didi/.gradle/caches/modules-2/files-2.1/androidx.activity/activity-ktx/1.2.0/c16aac66e6c4617b01118ab2509f009bb7919b3b/activity-ktx-1.2.0.aar - //println("三方库信息===>${artifactResult.variant.displayName}____${artifactResult.file.toString()}") -// "artifactResult===>${artifactResult.file}|${artifactResult.variant}|${artifactResult.id}|${artifactResult.type}".println() - //"artifactResult===>${artifactResult.variant.owner}|${artifactResult.variant.attributes}|${artifactResult.variant.displayName}|${artifactResult.variant.capabilities}|${artifactResult.variant.externalVariant}".println() - //"artifactResult===>${artifactResult.variant.displayName}".println() val variants = artifactResult.variant.displayName.split(" ") var thirdLibInfo: ThirdLibInfo? = null if (variants.size == 3) { - thirdLibInfo = ThirdLibInfo( - variants[0], - artifactResult.file.length() - ) - if (thirdLibInfo.variant.contains("dokitx-rpc")) { - DoKitExtUtil.HAS_DOKIT_RPC_MODULE = true - } - if (thirdLibInfo.variant.contains("dokitx-tcp-hook-dj")) { - DoKitExtUtil.HAS_DOKIT_TCP_HOOK_DJ = true - } - - if (thirdLibInfo.variant.contains("dokitx-gps-mock") || thirdLibInfo.variant.contains("dokit-gps-mock")){ - DoKitExtUtil.DOKIT_GPS_MOCK_INCLUDE = true; - } -// "thirdLibInfo.variant===>${thirdLibInfo.variant}".println() - DoKitExtUtil.THIRD_LIB_INFOS.add(thirdLibInfo) + thirdLibInfo = ThirdLibInfo(variants[0], artifactResult.file.length()) + checkConfig(thirdLibInfo.variant) } else if (variants.size == 4) { - thirdLibInfo = ThirdLibInfo( - "porject ${variants[1]}", - artifactResult.file.length() - ) - if (thirdLibInfo.variant.contains("doraemonkit-rpc")) { - DoKitExtUtil.HAS_DOKIT_RPC_MODULE = true - } - if (thirdLibInfo.variant.contains("dokitx-tcp-hook-dj")) { - DoKitExtUtil.HAS_DOKIT_TCP_HOOK_DJ = true - } - - if (thirdLibInfo.variant.contains("dokitx-gps-mock") || thirdLibInfo.variant.contains("dokit-gps-mock")){ - DoKitExtUtil.DOKIT_GPS_MOCK_INCLUDE = true; - } - -// "thirdLibInfo.variant===>${thirdLibInfo.variant}".println() - DoKitExtUtil.THIRD_LIB_INFOS.add(thirdLibInfo) + thirdLibInfo = ThirdLibInfo("porject ${variants[1]}", artifactResult.file.length()) + checkConfig(thirdLibInfo.variant) } + } + } + //查找AndroidManifest.xml 文件 并处理 + processApplicationVariant(variant) + + } - // val paths = artifactResult.file.toString().split("/") -// var fileName: String = "" -// var groupId: String = "" -// var artifactId: String = "" -// var version: String = "" -// if (artifactResult.file.toString().contains(".gradle/caches")) { -// if (paths.size >= 5) { -// groupId = paths[paths.size - 5] -// artifactId = paths[paths.size - 4] -// version = paths[paths.size - 3] -// fileName = -// "$groupId:$artifactId:$version" -// } else { -// fileName = paths[paths.size - 1] -// } -// } else { -// fileName = paths[paths.size - 1] -// } -// -// val thirdLibInfo = -// ThirdLibInfo( -// groupId, -// artifactId, -// version, -// fileName, -// artifactResult.file.length(), -// artifactResult.variant.displayName -// ) -// val key = "$groupId:$artifactId" -// if (DoKitExtUtil.THIRD_LIB_INFOS[key] == null) { -// DoKitExtUtil.THIRD_LIB_INFOS[key] = thirdLibInfo -// } else { -// val libInfo = DoKitExtUtil.THIRD_LIB_INFOS[key] -// if (DoKitPluginUtil.compareVersion(thirdLibInfo.version, libInfo!!.version) > 0) { -// DoKitExtUtil.THIRD_LIB_INFOS[key] = thirdLibInfo -// } -// } - } + private fun checkConfig(variant: String) { + if (variant.contains("dokitx-gps-mock") || variant.contains("dokit-gps-mock")) { + DoKitExtUtil.DOKIT_GPS_MOCK_INCLUDE = true; } + } + private fun processApplicationVariant(variant: BaseVariant) { //查找application module下的配置 if (variant is ApplicationVariant) { @@ -161,13 +93,12 @@ class DoKitPluginConfigProcessor(val project: Project) : VariantProcessor { //读取插件配置 variant.project.getAndroid().let { appExt -> //查找Application路径 - val doKitExt = variant.project.extensions.getByType(DoKitExt::class.java) + val doKitExt = variant.project.extensions.getByType(DoKitExtension::class.java) DoKitExtUtil.init(doKitExt) } } } - } else { "${variant.project.name}-不建议在Library Module下引入dokit插件".println() } diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/stack_method/MethodStackNodeUtil.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/stack_method/MethodStackNodeUtil.kt index b048260fa..a629f10cb 100644 --- a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/stack_method/MethodStackNodeUtil.kt +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/stack_method/MethodStackNodeUtil.kt @@ -1,6 +1,5 @@ package com.didichuxing.doraemonkit.plugin.stack_method -import org.gradle.internal.impldep.org.apache.commons.lang.mutable.Mutable import java.util.* /** @@ -27,4 +26,4 @@ object MethodStackNodeUtil { } -} \ No newline at end of file +} diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/ThirdLibInfo.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/thirdlib/ThirdLibInfo.kt similarity index 56% rename from Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/ThirdLibInfo.kt rename to Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/thirdlib/ThirdLibInfo.kt index 0e641f234..0ef8309f6 100644 --- a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/ThirdLibInfo.kt +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/thirdlib/ThirdLibInfo.kt @@ -1,4 +1,4 @@ -package com.didichuxing.doraemonkit.plugin +package com.didichuxing.doraemonkit.plugin.thirdlib /** * ================================================ @@ -9,14 +9,6 @@ package com.didichuxing.doraemonkit.plugin * 修订历史: * ================================================ */ -//data class ThirdLibInfo( -// val groupId: String, -// val artifactId: String, -// val version: String, -// val fileName: String, -// val fileSize: Long, -// val variant: String -//) data class ThirdLibInfo(val variant: String, val fileSize: Long) diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/thirdlib/ThirdLibVariantProcessor.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/thirdlib/ThirdLibVariantProcessor.kt new file mode 100644 index 000000000..e12718765 --- /dev/null +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/thirdlib/ThirdLibVariantProcessor.kt @@ -0,0 +1,55 @@ +package com.didichuxing.doraemonkit.plugin.thirdlib + +import com.android.build.gradle.api.BaseVariant +import com.didichuxing.doraemonkit.plugin.DoKitExtUtil +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.isRelease +import com.didiglobal.booster.gradle.dependencies +import com.didiglobal.booster.task.spi.VariantProcessor +import org.gradle.api.Project +import org.gradle.api.artifacts.result.ResolvedArtifactResult + + +/** + * didi Create on 2023/3/22 . + * + * Copyright (c) 2023/3/22 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/22 2:57 下午 + * @Description 用一句话说明文件功能 + */ + +class ThirdLibVariantProcessor(val project: Project) : VariantProcessor { + + override fun process(variant: BaseVariant) { + if (!DoKitExtUtil.DOKIT_PLUGIN_SWITCH) { + return + } + + if (variant.isRelease()) { + return + } + + val dokit = project.extensions.getByType(DoKitExtension::class.java) + + //统计三方库信息 + if (dokit.thirdLibEnable && DoKitExtUtil.THIRD_LIBINFO_SWITCH) { + //遍历三方库 + val dependencies = variant.dependencies + DoKitExtUtil.THIRD_LIB_INFOS.clear() + for (artifactResult: ResolvedArtifactResult in dependencies) { + val variants = artifactResult.variant.displayName.split(" ") + var thirdLibInfo: ThirdLibInfo? = null + if (variants.size == 3) { + thirdLibInfo = ThirdLibInfo(variants[0], artifactResult.file.length()) + DoKitExtUtil.THIRD_LIB_INFOS.add(thirdLibInfo) + } else if (variants.size == 4) { + thirdLibInfo = ThirdLibInfo("porject ${variants[1]}", artifactResult.file.length()) + DoKitExtUtil.THIRD_LIB_INFOS.add(thirdLibInfo) + } + } + } + } +} diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitBaseTransform.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitBaseTransform.kt index 87aeab06c..af3072809 100644 --- a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitBaseTransform.kt +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitBaseTransform.kt @@ -5,9 +5,6 @@ import com.android.build.api.transform.Transform import com.android.build.api.transform.TransformInvocation import com.android.build.gradle.BaseExtension import com.android.build.gradle.internal.pipeline.TransformManager -import com.didichuxing.doraemonkit.plugin.DoKitTransformInvocation -import com.didichuxing.doraemonkit.plugin.println -import com.didiglobal.booster.annotations.Priority import com.didiglobal.booster.gradle.* import com.didiglobal.booster.transform.AbstractKlassPool import com.didiglobal.booster.transform.Transformer @@ -18,6 +15,7 @@ import org.gradle.api.Project * DoKitCommTransform 作用于 CommTransformer、BigImgTransformer、UrlConnectionTransformer、GlobalSlowMethodTransformer * @author johnsonlee */ + open class DoKitBaseTransform protected constructor(val project: Project) : Transform() { /*transformers @@ -80,7 +78,6 @@ open class DoKitBaseTransform protected constructor(val project: Project) : Tran } - } /** diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitCommTransform.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitCommTransform.kt deleted file mode 100644 index 6735e152a..000000000 --- a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitCommTransform.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.didichuxing.doraemonkit.plugin.transform - -import com.didichuxing.doraemonkit.plugin.asmtransformer.DoKitAsmTransformer -import com.didichuxing.doraemonkit.plugin.classtransformer.BigImgClassTransformer -import com.didichuxing.doraemonkit.plugin.classtransformer.CommClassTransformer -import com.didichuxing.doraemonkit.plugin.classtransformer.EnterMSClassTransformer -import com.didichuxing.doraemonkit.plugin.classtransformer.GSMClassTransformer -import com.didiglobal.booster.transform.Transformer -import org.gradle.api.Project - -/** - * Represents the transform base - * DoKitCommTransform 作用于 CommTransformer、BigImgTransformer、UrlConnectionTransformer、GlobalSlowMethodTransformer、EnterMethodStackTransformer - * @author johnsonlee - */ -class DoKitCommTransform(androidProject: Project) : DoKitBaseTransform(androidProject) { - - override val transformers = listOf( - DoKitAsmTransformer( - listOf( - CommClassTransformer(), - BigImgClassTransformer(), - GSMClassTransformer(), - EnterMSClassTransformer() - ) - ) - ) - -} diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitCommonTransform.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitCommonTransform.kt new file mode 100644 index 000000000..28b5f72e8 --- /dev/null +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitCommonTransform.kt @@ -0,0 +1,40 @@ +package com.didichuxing.doraemonkit.plugin.transform + +import com.didichuxing.doraemonkit.plugin.transform.asmtransform.DoKitAsmTransformer +import com.didichuxing.doraemonkit.plugin.transform.classtransform.* +import com.didiglobal.booster.transform.Transformer +import org.gradle.api.Project + +/** + * Represents the transform base + * DoKitCommTransform 作用于 CommTransformer、BigImgTransformer、UrlConnectionTransformer、GlobalSlowMethodTransformer、EnterMethodStackTransformer + * @author johnsonlee + */ +class DoKitCommonTransform(androidProject: Project) : DoKitBaseTransform(androidProject) { + + override val transformers = listOf( + DoKitAsmTransformer( + listOf( + CommClassTransformer(), + ThirdLibsClassTransformer(), + //网络 + Okhttp3ClassTransformer(), + UrlConnectionTransformer(), + WebViewClassTransformer(), + + //地图GPS + GPSClassTransformer(), + GPSAMapClassTransformer(), + GPSBDClassTransformer(), + GPSTencentClassTransformer(), + //大图检测 + BigImgClassTransformer(), + //全局慢函数 + GSMClassTransformer(), + //入口慢函数 + EnterMSClassTransformer() + ) + ) + ) + +} diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitCommTransformV34.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitCommonTransformV34.kt similarity index 60% rename from Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitCommTransformV34.kt rename to Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitCommonTransformV34.kt index 40a7342b6..e40e76de6 100644 --- a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitCommTransformV34.kt +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitCommonTransformV34.kt @@ -1,23 +1,34 @@ package com.didichuxing.doraemonkit.plugin.transform import com.android.build.api.variant.VariantInfo -import com.didichuxing.doraemonkit.plugin.DoKitExtUtil -import com.didichuxing.doraemonkit.plugin.asmtransformer.DoKitAsmTransformer -import com.didichuxing.doraemonkit.plugin.classtransformer.* -import com.didichuxing.doraemonkit.plugin.extension.SlowMethodExt -import com.didichuxing.doraemonkit.plugin.stack_method.MethodStackNodeUtil +import com.didichuxing.doraemonkit.plugin.transform.asmtransform.DoKitAsmTransformer +import com.didichuxing.doraemonkit.plugin.transform.classtransform.* import com.didiglobal.booster.transform.Transformer import org.gradle.api.Project -class DoKitCommTransformV34(project: Project) : DoKitBaseTransform(project) { +class DoKitCommonTransformV34(project: Project) : DoKitBaseTransform(project) { override val transformers = listOf( DoKitAsmTransformer( listOf( CommClassTransformer(), + ThirdLibsClassTransformer(), + //网络 + Okhttp3ClassTransformer(), + UrlConnectionTransformer(), + WebViewClassTransformer(), + + //地图GPS + GPSClassTransformer(), + GPSAMapClassTransformer(), + GPSBDClassTransformer(), + GPSTencentClassTransformer(), + //大图检测 BigImgClassTransformer(), + //全局慢函数 GSMClassTransformer(), + //入口慢函数 EnterMSClassTransformer() ) ) diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitDependTransform.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitDependTransform.kt index 9a61ad742..8c1068913 100644 --- a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitDependTransform.kt +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitDependTransform.kt @@ -1,7 +1,7 @@ package com.didichuxing.doraemonkit.plugin.transform -import com.didichuxing.doraemonkit.plugin.asmtransformer.DoKitAsmTransformer -import com.didichuxing.doraemonkit.plugin.classtransformer.MSDClassTransformer +import com.didichuxing.doraemonkit.plugin.transform.asmtransform.DoKitAsmTransformer +import com.didichuxing.doraemonkit.plugin.transform.classtransform.MSDClassTransformer import com.didiglobal.booster.transform.Transformer import org.gradle.api.Project diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitDependTransformV34.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitDependTransformV34.kt index 42b03fe03..6f527aed2 100644 --- a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitDependTransformV34.kt +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitDependTransformV34.kt @@ -1,8 +1,8 @@ package com.didichuxing.doraemonkit.plugin.transform import com.android.build.api.variant.VariantInfo -import com.didichuxing.doraemonkit.plugin.asmtransformer.DoKitAsmTransformer -import com.didichuxing.doraemonkit.plugin.classtransformer.MSDClassTransformer +import com.didichuxing.doraemonkit.plugin.transform.asmtransform.DoKitAsmTransformer +import com.didichuxing.doraemonkit.plugin.transform.classtransform.MSDClassTransformer import com.didiglobal.booster.transform.Transformer import org.gradle.api.Project diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitTransformContext.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitTransformContext.kt new file mode 100644 index 000000000..02b9a56c1 --- /dev/null +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitTransformContext.kt @@ -0,0 +1,23 @@ +package com.didichuxing.doraemonkit.plugin.transform + +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import org.gradle.api.Project + + +/** + * didi Create on 2023/3/21 . + * + * Copyright (c) 2023/3/21 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/21 6:31 下午 + * @Description 用一句话说明文件功能 + */ + +interface DoKitTransformContext { + + fun project(): Project + + fun dokitExtension(): DoKitExtension +} diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitTransformInvocation.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitTransformInvocation.kt similarity index 90% rename from Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitTransformInvocation.kt rename to Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitTransformInvocation.kt index aeea0c9da..a4b193d90 100644 --- a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitTransformInvocation.kt +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitTransformInvocation.kt @@ -1,20 +1,20 @@ -package com.didichuxing.doraemonkit.plugin +package com.didichuxing.doraemonkit.plugin.transform import com.android.build.api.transform.* import com.android.build.api.transform.Status.* import com.android.dex.DexFormat -import com.android.dx.command.dexer.Main -import com.didichuxing.doraemonkit.plugin.transform.DoKitBaseTransform +import com.didichuxing.doraemonkit.plugin.dex +import com.didichuxing.doraemonkit.plugin.dokitTransform +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.println import com.didiglobal.booster.gradle.* import com.didiglobal.booster.kotlinx.NCPU import com.didiglobal.booster.kotlinx.file import com.didiglobal.booster.kotlinx.green import com.didiglobal.booster.kotlinx.red -import com.didiglobal.booster.transform.AbstractKlassPool -import com.didiglobal.booster.transform.ArtifactManager -import com.didiglobal.booster.transform.TransformContext -import com.didiglobal.booster.transform.artifacts +import com.didiglobal.booster.transform.* import com.didiglobal.booster.transform.util.transform +import org.gradle.api.Project import java.io.File import java.net.URI import java.util.concurrent.* @@ -24,10 +24,10 @@ import java.util.concurrent.* * * @author johnsonlee */ -internal class DoKitTransformInvocation( +internal class DoKitTransformInvocation( private val delegate: TransformInvocation, internal val transform: DoKitBaseTransform -) : TransformInvocation by delegate, TransformContext, ArtifactManager { +) : TransformInvocation by delegate, TransformContext, ArtifactManager,DoKitTransformContext { private val project = transform.project @@ -234,4 +234,22 @@ internal class DoKitTransformInvocation( transformer.transform(this@DoKitTransformInvocation, bytes) } } -} \ No newline at end of file + + override fun project(): Project { + return project + } + + override fun dokitExtension(): DoKitExtension { + return project.extensions.getByType(DoKitExtension::class.java) + } + + override fun registerCollector(collector: Collector) { + TODO("Not yet implemented") + } + + override fun unregisterCollector(collector: Collector) { + TODO("Not yet implemented") + } + + +} diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/asmtransformer/BaseDoKitAsmTransformer.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/asmtransform/BaseDoKitAsmTransformer.kt similarity index 96% rename from Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/asmtransformer/BaseDoKitAsmTransformer.kt rename to Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/asmtransform/BaseDoKitAsmTransformer.kt index a5f01256d..cb4e393c2 100644 --- a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/asmtransformer/BaseDoKitAsmTransformer.kt +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/asmtransform/BaseDoKitAsmTransformer.kt @@ -1,6 +1,5 @@ -package com.didichuxing.doraemonkit.plugin.asmtransformer +package com.didichuxing.doraemonkit.plugin.transform.asmtransform -import com.didichuxing.doraemonkit.plugin.println import com.didiglobal.booster.annotations.Priority import com.didiglobal.booster.transform.TransformContext import com.didiglobal.booster.transform.Transformer diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/asmtransformer/DoKitAsmTransformer.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/asmtransform/DoKitAsmTransformer.kt similarity index 86% rename from Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/asmtransformer/DoKitAsmTransformer.kt rename to Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/asmtransform/DoKitAsmTransformer.kt index aa3581105..21a48a94d 100644 --- a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/asmtransformer/DoKitAsmTransformer.kt +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/asmtransform/DoKitAsmTransformer.kt @@ -1,4 +1,4 @@ -package com.didichuxing.doraemonkit.plugin.asmtransformer +package com.didichuxing.doraemonkit.plugin.transform.asmtransform import com.didiglobal.booster.transform.asm.ClassTransformer diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/AbsClassTransformer.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/AbsClassTransformer.kt new file mode 100644 index 000000000..96aa23380 --- /dev/null +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/AbsClassTransformer.kt @@ -0,0 +1,59 @@ +package com.didichuxing.doraemonkit.plugin.transform.classtransform + +import com.didichuxing.doraemonkit.plugin.DoKitExtUtil +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.isRelease +import com.didichuxing.doraemonkit.plugin.transform.DoKitTransformContext +import com.didiglobal.booster.transform.TransformContext +import com.didiglobal.booster.transform.asm.ClassTransformer +import com.didiglobal.booster.transform.asm.className +import org.gradle.api.Project +import org.objectweb.asm.tree.ClassNode + +/** + * ================================================ + * 作 者:jint(金台) + * 版 本:1.0 + * 创建日期:2021/5/12-18:06 + * 描 述: + * 修订历史: + * ================================================ + */ + +open class AbsClassTransformer : ClassTransformer { + + + open fun onDoKitClassInterceptor(context: TransformContext, klass: ClassNode): Boolean { + if (context.isRelease()) { + return true + } + if (!DoKitExtUtil.dokitPluginSwitchOpen()) { + return true + } + + //过滤kotlin module-info + if (klass.className == "module-info") { + return true + } + return false + } + + override fun transform(context: TransformContext, klass: ClassNode): ClassNode { + if (onDoKitClassInterceptor(context, klass)) { + return klass + } + + if (DoKitExtUtil.ignorePackageNames(klass.className)) { + return klass + } + + if (context is DoKitTransformContext) { + val project = context.project() + val dokit = context.dokitExtension() + transform(project, dokit, context, klass) + } + return klass + } + + open fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode = klass +} diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/BigImgClassTransformer.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/BigImgClassTransformer.kt similarity index 79% rename from Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/BigImgClassTransformer.kt rename to Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/BigImgClassTransformer.kt index 855367894..8bc57b91f 100644 --- a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/BigImgClassTransformer.kt +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/BigImgClassTransformer.kt @@ -1,12 +1,13 @@ -package com.didichuxing.doraemonkit.plugin.classtransformer +package com.didichuxing.doraemonkit.plugin.transform.classtransform -import com.didichuxing.doraemonkit.plugin.* -import com.didiglobal.booster.annotations.Priority +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.getMethodExitInsnNodes +import com.didichuxing.doraemonkit.plugin.lastPath +import com.didichuxing.doraemonkit.plugin.println import com.didiglobal.booster.transform.TransformContext -import com.didiglobal.booster.transform.asm.ClassTransformer import com.didiglobal.booster.transform.asm.className -import com.google.auto.service.AutoService -import org.objectweb.asm.Opcodes.* +import org.gradle.api.Project +import org.objectweb.asm.Opcodes import org.objectweb.asm.tree.ClassNode import org.objectweb.asm.tree.InsnList import org.objectweb.asm.tree.MethodInsnNode @@ -21,28 +22,17 @@ import org.objectweb.asm.tree.VarInsnNode * 修订历史: * ================================================ */ -//@Priority(1) -//@AutoService(ClassTransformer::class) class BigImgClassTransformer : AbsClassTransformer() { - override fun transform(context: TransformContext, klass: ClassNode): ClassNode { - if (onCommInterceptor(context, klass)) { - return klass - } - - if (!DoKitExtUtil.commExt.bigImgSwitch) { + override fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode { + if (!dokit.bigImageEnable) { return klass } - if (DoKitExtUtil.ignorePackageNames(klass.className)) { - return klass - } - - val className = klass.className //glide - if (className == "com.bumptech.glide.request.SingleRequest") { + if (dokit.bigImage.glide && className == "com.bumptech.glide.request.SingleRequest") { klass.methods.find { methodNode -> (methodNode.name == "init" || methodNode.name == "") && methodNode.desc != null }.let { methodNode -> @@ -55,7 +45,7 @@ class BigImgClassTransformer : AbsClassTransformer() { } //picasso - if (className == "com.squareup.picasso.Request") { + if (dokit.bigImage.picasso && className == "com.squareup.picasso.Request") { klass.methods.find { methodNode -> methodNode.name == "" && methodNode.desc != null }.let { methodNode -> @@ -68,7 +58,7 @@ class BigImgClassTransformer : AbsClassTransformer() { } //Fresco - if (className == "com.facebook.imagepipeline.request.ImageRequest") { + if (dokit.bigImage.fresco && className == "com.facebook.imagepipeline.request.ImageRequest") { klass.methods.find { methodNode -> methodNode.name == "" && methodNode.desc != null }.let { methodNode -> @@ -79,7 +69,7 @@ class BigImgClassTransformer : AbsClassTransformer() { } //ImageLoader - if (className == "com.nostra13.universalimageloader.core.ImageLoadingInfo") { + if (dokit.bigImage.imageLoader && className == "com.nostra13.universalimageloader.core.ImageLoadingInfo") { klass.methods.find { methodNode -> methodNode.name == "" && methodNode.desc != null }.let { methodNode -> @@ -89,7 +79,7 @@ class BigImgClassTransformer : AbsClassTransformer() { } //Coil - if (className == "coil.request.ImageRequest") { + if (dokit.bigImage.coil && className == "coil.request.ImageRequest") { "hook Coil Start".println() klass.methods.find { methodNode -> methodNode.name == "" && methodNode.desc != null @@ -101,8 +91,6 @@ class BigImgClassTransformer : AbsClassTransformer() { } } } - - return klass } @@ -111,10 +99,10 @@ class BigImgClassTransformer : AbsClassTransformer() { */ private fun createGlideInsnList(): InsnList { return with(InsnList()) { - add(VarInsnNode(ALOAD, 0)) + add(VarInsnNode(Opcodes.ALOAD, 0)) add( MethodInsnNode( - INVOKESTATIC, + Opcodes.INVOKESTATIC, "com/didichuxing/doraemonkit/aop/bigimg/glide/GlideHook", "proxy", "(Ljava/lang/Object;)V", @@ -130,10 +118,10 @@ class BigImgClassTransformer : AbsClassTransformer() { */ private fun createPicassoInsnList(): InsnList { return with(InsnList()) { - add(VarInsnNode(ALOAD, 0)) + add(VarInsnNode(Opcodes.ALOAD, 0)) add( MethodInsnNode( - INVOKESTATIC, + Opcodes.INVOKESTATIC, "com/didichuxing/doraemonkit/aop/bigimg/picasso/PicassoHook", "proxy", "(Ljava/lang/Object;)V", @@ -145,27 +133,26 @@ class BigImgClassTransformer : AbsClassTransformer() { } - /** * 创建Fresco Aop代码指令 */ private fun createFrescoInsnList(): InsnList { return with(InsnList()) { - add(VarInsnNode(ALOAD, 1)) - add(VarInsnNode(ALOAD, 1)) + add(VarInsnNode(Opcodes.ALOAD, 1)) + add(VarInsnNode(Opcodes.ALOAD, 1)) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/facebook/imagepipeline/request/ImageRequestBuilder", "getSourceUri", "()Landroid/net/Uri;", false ) ) - add(VarInsnNode(ALOAD, 1)) + add(VarInsnNode(Opcodes.ALOAD, 1)) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/facebook/imagepipeline/request/ImageRequestBuilder", "getPostprocessor", "()Lcom/facebook/imagepipeline/request/Postprocessor;", @@ -174,7 +161,7 @@ class BigImgClassTransformer : AbsClassTransformer() { ) add( MethodInsnNode( - INVOKESTATIC, + Opcodes.INVOKESTATIC, "com/didichuxing/doraemonkit/aop/bigimg/fresco/FrescoHook", "proxy", "(Landroid/net/Uri;Lcom/facebook/imagepipeline/request/Postprocessor;)Lcom/facebook/imagepipeline/request/Postprocessor;", @@ -183,7 +170,7 @@ class BigImgClassTransformer : AbsClassTransformer() { ) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/facebook/imagepipeline/request/ImageRequestBuilder", "setPostprocessor", "(Lcom/facebook/imagepipeline/request/Postprocessor;)Lcom/facebook/imagepipeline/request/ImageRequestBuilder;", @@ -195,32 +182,32 @@ class BigImgClassTransformer : AbsClassTransformer() { } - /** * 创建ImageLoader Aop代码指令 */ private fun createImageLoaderInsnList(): InsnList { return with(InsnList()) { - add(VarInsnNode(ALOAD, 6)) + add(VarInsnNode(Opcodes.ALOAD, 6)) add( MethodInsnNode( - INVOKESTATIC, + Opcodes.INVOKESTATIC, "com/didichuxing/doraemonkit/aop/bigimg/imageloader/ImageLoaderHook", "proxy", "(Lcom/nostra13/universalimageloader/core/listener/ImageLoadingListener;)Lcom/nostra13/universalimageloader/core/listener/ImageLoadingListener;", false ) ) - add(VarInsnNode(ASTORE, 6)) + add(VarInsnNode(Opcodes.ASTORE, 6)) this } } + private fun createCoilInsnList(): InsnList { return with(InsnList()) { - add(VarInsnNode(ALOAD, 0)) + add(VarInsnNode(Opcodes.ALOAD, 0)) add( MethodInsnNode( - INVOKESTATIC, + Opcodes.INVOKESTATIC, "com/didichuxing/doraemonkit/aop/bigimg/coil/CoilHook", "proxy", "(Ljava/lang/Object;)V", @@ -231,4 +218,3 @@ class BigImgClassTransformer : AbsClassTransformer() { } } } - diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/CommClassTransformer.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/CommClassTransformer.kt new file mode 100644 index 000000000..9a41231ee --- /dev/null +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/CommClassTransformer.kt @@ -0,0 +1,238 @@ +package com.didichuxing.doraemonkit.plugin.transform.classtransform + +import com.didichuxing.doraemonkit.plugin.DoKitExtUtil +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.extension.SlowMethodExtension +import com.didichuxing.doraemonkit.plugin.formatSuperName +import com.didichuxing.doraemonkit.plugin.lastPath +import com.didichuxing.doraemonkit.plugin.println +import com.didiglobal.booster.transform.TransformContext +import com.didiglobal.booster.transform.asm.className +import org.gradle.api.Project +import org.objectweb.asm.Opcodes +import org.objectweb.asm.tree.* + +/** + * ================================================ + * 作 者:jint(金台) + * 版 本:1.0 + * 创建日期:2020/5/14-18:07 + * 描 述:wiki:https://juejin.im/post/5e8d87c4f265da47ad218e6b + * 修订历史: + * ================================================ + */ +class CommClassTransformer : AbsClassTransformer() { + + override fun transform(context: TransformContext, klass: ClassNode): ClassNode { + + val className = klass.className + val superName = klass.formatSuperName + + //hook Androidx的ComponentActivity + if (className != "com.didichuxing.doraemonkit.aop.mc.DoKitProxyActivity" && superName == "android.app.Activity") { + createComponentActivitySuperActivityImpl(klass) + } + + return super.transform(context, klass) + } + + /** + * 类处理转化实现 + */ + override fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode { + val className = klass.className + + //查找DoraemonKitReal&pluginConfig方法并插入指定字节码 + if (className == "com.didichuxing.doraemonkit.DoKitReal") { + //插件配置 + klass.methods?.find { + it.name == "pluginConfig" + }.let { methodNode -> + "${context.projectDir.lastPath()}->insert map to the DoKitReal pluginConfig succeed".println() + methodNode?.instructions?.insert(createPluginConfigInsnList(dokit.gpsEnable, dokit.networkEnable, dokit.bigImageEnable)) + } + } + return klass + } + + /** + * 创建pluginConfig代码指令 + */ + private fun createPluginConfigInsnList(gpsSwitch: Boolean, networkSwitch: Boolean, bigImgSwitch: Boolean): InsnList { + return with(InsnList()) { + //new HashMap + add(TypeInsnNode(Opcodes.NEW, "java/util/HashMap")) + add(InsnNode(Opcodes.DUP)) + add(MethodInsnNode(Opcodes.INVOKESPECIAL, "java/util/HashMap", "", "()V", false)) + //保存变量 + add(VarInsnNode(Opcodes.ASTORE, 0)) + //获取第一个变量 + //put("dokitPluginSwitch",true) + add(VarInsnNode(Opcodes.ALOAD, 0)) + add(LdcInsnNode("dokitPluginSwitch")) + add(InsnNode(if (DoKitExtUtil.dokitPluginSwitchOpen()) Opcodes.ICONST_1 else Opcodes.ICONST_0)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "java/lang/Boolean", + "valueOf", + "(Z)Ljava/lang/Boolean;", + false + ) + ) + add( + MethodInsnNode( + Opcodes.INVOKEINTERFACE, + "java/util/Map", + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + true + ) + ) + add(InsnNode(Opcodes.POP)) + + //put("gpsSwitch",true) + add(VarInsnNode(Opcodes.ALOAD, 0)) + add(LdcInsnNode("gpsSwitch")) + add(InsnNode(if (gpsSwitch) Opcodes.ICONST_1 else Opcodes.ICONST_0)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "java/lang/Boolean", + "valueOf", + "(Z)Ljava/lang/Boolean;", + false + ) + ) + add( + MethodInsnNode( + Opcodes.INVOKEINTERFACE, + "java/util/Map", + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + true + ) + ) + add(InsnNode(Opcodes.POP)) + + //put("networkSwitch",true) + add(VarInsnNode(Opcodes.ALOAD, 0)) + add(LdcInsnNode("networkSwitch")) + add(InsnNode(if (networkSwitch) Opcodes.ICONST_1 else Opcodes.ICONST_0)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "java/lang/Boolean", + "valueOf", + "(Z)Ljava/lang/Boolean;", + false + ) + ) + add( + MethodInsnNode( + Opcodes.INVOKEINTERFACE, + "java/util/Map", + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + true + ) + ) + add(InsnNode(Opcodes.POP)) + + add(VarInsnNode(Opcodes.ALOAD, 0)) + add(LdcInsnNode("bigImgSwitch")) + add(InsnNode(if (bigImgSwitch) Opcodes.ICONST_1 else Opcodes.ICONST_0)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "java/lang/Boolean", + "valueOf", + "(Z)Ljava/lang/Boolean;", + false + ) + ) + add( + MethodInsnNode( + Opcodes.INVOKEINTERFACE, + "java/util/Map", + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + true + ) + ) + add(InsnNode(Opcodes.POP)) + + add(VarInsnNode(Opcodes.ALOAD, 0)) + add(LdcInsnNode("methodSwitch")) + add(InsnNode(if (DoKitExtUtil.dokitSlowMethodSwitchOpen()) Opcodes.ICONST_1 else Opcodes.ICONST_0)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "java/lang/Boolean", + "valueOf", + "(Z)Ljava/lang/Boolean;", + false + ) + ) + add( + MethodInsnNode( + Opcodes.INVOKEINTERFACE, + "java/util/Map", + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + true + ) + ) + add(InsnNode(Opcodes.POP)) + + + //put("methodStrategy",0) + add(VarInsnNode(Opcodes.ALOAD, 0)) + add(LdcInsnNode("methodStrategy")) + add(InsnNode(if (DoKitExtUtil.SLOW_METHOD_STRATEGY == SlowMethodExtension.STRATEGY_STACK) Opcodes.ICONST_0 else Opcodes.ICONST_1)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "java/lang/Integer", + "valueOf", + "(I)Ljava/lang/Integer;", + false + ) + ) + add( + MethodInsnNode( + Opcodes.INVOKEINTERFACE, + "java/util/Map", + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + true + ) + ) + add(InsnNode(Opcodes.POP)) + + //将HashMap注入到DokitPluginConfig中 + add(VarInsnNode(Opcodes.ALOAD, 0)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/aop/DokitPluginConfig", + "inject", + "(Ljava/util/Map;)V", + false + ) + ) + this + } + } + + /** + * 重置ComponentActivity的父类 + */ + private fun createComponentActivitySuperActivityImpl(klass: ClassNode) { + /** + * 修改继承的父类 + */ + klass.superName = "com/didichuxing/doraemonkit/aop/mc/DoKitProxyActivity" + } + +} diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/EnterMSClassTransformer.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/EnterMSClassTransformer.kt similarity index 79% rename from Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/EnterMSClassTransformer.kt rename to Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/EnterMSClassTransformer.kt index 8502967a5..5062fd614 100644 --- a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/EnterMSClassTransformer.kt +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/EnterMSClassTransformer.kt @@ -1,16 +1,15 @@ -package com.didichuxing.doraemonkit.plugin.classtransformer +package com.didichuxing.doraemonkit.plugin.transform.classtransform import com.didichuxing.doraemonkit.plugin.* -import com.didichuxing.doraemonkit.plugin.extension.SlowMethodExt +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.extension.SlowMethodExtension import com.didichuxing.doraemonkit.plugin.stack_method.MethodStackNode import com.didichuxing.doraemonkit.plugin.stack_method.MethodStackNodeUtil -import com.didiglobal.booster.annotations.Priority import com.didiglobal.booster.transform.TransformContext -import com.didiglobal.booster.transform.asm.ClassTransformer import com.didiglobal.booster.transform.asm.asIterable import com.didiglobal.booster.transform.asm.className -import com.google.auto.service.AutoService -import org.objectweb.asm.Opcodes.* +import org.gradle.api.Project +import org.objectweb.asm.Opcodes import org.objectweb.asm.tree.* /** @@ -20,31 +19,25 @@ import org.objectweb.asm.tree.* * 创建日期:2020/5/14-18:07 * 描 述:入口函数 慢函数调用栈 wiki:https://juejin.im/post/5e8d87c4f265da47ad218e6b * 修订历史:不要指定自动注入 需要手动在DoKitAsmTransformer中通过配置创建 - * 原理:transform()方法的调用是无序的 原因:哪一个class会先被transformer执行是不确定的 但是每一个class被transformer执行顺序是遵循transformer的Priority规则的 + * + * 原理:transform()方法的调用是无序的 + * 原因:哪一个class会先被transformer执行是不确定的 但是每一个class被transformer执行顺序是遵循transformer的Priority规则的 * ================================================ + * + * 入口函数 慢函数调用栈 + * */ -//@Priority(3) -//@AutoService(ClassTransformer::class) class EnterMSClassTransformer : AbsClassTransformer() { private val thresholdTime = DoKitExtUtil.slowMethodExt.stackMethod.thresholdTime private val level = 0 - override fun transform(context: TransformContext, klass: ClassNode): ClassNode { - - - if (onCommInterceptor(context, klass)) { - return klass - } + override fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode { if (!DoKitExtUtil.dokitSlowMethodSwitchOpen()) { return klass } - if (DoKitExtUtil.SLOW_METHOD_STRATEGY == SlowMethodExt.STRATEGY_NORMAL) { - return klass - } - - if (DoKitExtUtil.ignorePackageNames(klass.className)) { + if (DoKitExtUtil.SLOW_METHOD_STRATEGY == SlowMethodExtension.STRATEGY_NORMAL) { return klass } @@ -121,26 +114,26 @@ class EnterMSClassTransformer : AbsClassTransformer() { desc: String, access: Int ): InsnList { - val isStaticMethod = access and ACC_STATIC != 0 + val isStaticMethod = access and Opcodes.ACC_STATIC != 0 return with(InsnList()) { if (isStaticMethod) { add( FieldInsnNode( - GETSTATIC, + Opcodes.GETSTATIC, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "INSTANCE", "Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;" ) ) - add(IntInsnNode(BIPUSH, DoKitExtUtil.STACK_METHOD_LEVEL)) - add(IntInsnNode(BIPUSH, thresholdTime)) - add(IntInsnNode(BIPUSH, level)) + add(IntInsnNode(Opcodes.BIPUSH, DoKitExtUtil.STACK_METHOD_LEVEL)) + add(IntInsnNode(Opcodes.BIPUSH, thresholdTime)) + add(IntInsnNode(Opcodes.BIPUSH, level)) add(LdcInsnNode(className)) add(LdcInsnNode(methodName)) add(LdcInsnNode(desc)) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "recodeStaticMethodCostStart", "(IIILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", @@ -150,22 +143,22 @@ class EnterMSClassTransformer : AbsClassTransformer() { } else { add( FieldInsnNode( - GETSTATIC, + Opcodes.GETSTATIC, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "INSTANCE", "Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;" ) ) - add(IntInsnNode(BIPUSH, DoKitExtUtil.STACK_METHOD_LEVEL)) - add(IntInsnNode(BIPUSH, thresholdTime)) - add(IntInsnNode(BIPUSH, level)) + add(IntInsnNode(Opcodes.BIPUSH, DoKitExtUtil.STACK_METHOD_LEVEL)) + add(IntInsnNode(Opcodes.BIPUSH, thresholdTime)) + add(IntInsnNode(Opcodes.BIPUSH, level)) add(LdcInsnNode(className)) add(LdcInsnNode(methodName)) add(LdcInsnNode(desc)) - add(VarInsnNode(ALOAD, 0)) + add(VarInsnNode(Opcodes.ALOAD, 0)) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "recodeObjectMethodCostStart", "(IIILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V", @@ -190,26 +183,26 @@ class EnterMSClassTransformer : AbsClassTransformer() { desc: String, access: Int ): InsnList { - val isStaticMethod = access and ACC_STATIC != 0 + val isStaticMethod = access and Opcodes.ACC_STATIC != 0 return with(InsnList()) { if (isStaticMethod) { add( FieldInsnNode( - GETSTATIC, + Opcodes.GETSTATIC, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "INSTANCE", "Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;" ) ) - add(IntInsnNode(BIPUSH, thresholdTime)) - add(IntInsnNode(BIPUSH, level)) + add(IntInsnNode(Opcodes.BIPUSH, thresholdTime)) + add(IntInsnNode(Opcodes.BIPUSH, level)) add(LdcInsnNode(className)) add(LdcInsnNode(methodName)) add(LdcInsnNode(desc)) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "recodeStaticMethodCostEnd", "(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", @@ -219,21 +212,21 @@ class EnterMSClassTransformer : AbsClassTransformer() { } else { add( FieldInsnNode( - GETSTATIC, + Opcodes.GETSTATIC, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "INSTANCE", "Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;" ) ) - add(IntInsnNode(BIPUSH, thresholdTime)) - add(IntInsnNode(BIPUSH, level)) + add(IntInsnNode(Opcodes.BIPUSH, thresholdTime)) + add(IntInsnNode(Opcodes.BIPUSH, level)) add(LdcInsnNode(className)) add(LdcInsnNode(methodName)) add(LdcInsnNode(desc)) - add(VarInsnNode(ALOAD, 0)) + add(VarInsnNode(Opcodes.ALOAD, 0)) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "recodeObjectMethodCostEnd", "(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V", @@ -247,4 +240,3 @@ class EnterMSClassTransformer : AbsClassTransformer() { } } - diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GPSAMapClassTransformer.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GPSAMapClassTransformer.kt new file mode 100644 index 000000000..8bdc5fc81 --- /dev/null +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GPSAMapClassTransformer.kt @@ -0,0 +1,250 @@ +package com.didichuxing.doraemonkit.plugin.transform.classtransform + +import com.didichuxing.doraemonkit.plugin.DoKitExtUtil +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.lastPath +import com.didichuxing.doraemonkit.plugin.println +import com.didiglobal.booster.transform.TransformContext +import com.didiglobal.booster.transform.asm.className +import org.gradle.api.Project +import org.objectweb.asm.Opcodes +import org.objectweb.asm.tree.* + + +/** + * didi Create on 2023/3/21 . + * + * Copyright (c) 2023/3/21 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/21 3:06 下午 + * @Description 高德地图 hooks + */ + +class GPSAMapClassTransformer : AbsClassTransformer() { + + override fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode { + val className = klass.className + + if (dokit.gpsEnable && dokit.gps.amap && DoKitExtUtil.DOKIT_GPS_MOCK_INCLUDE) { + //插入高德地图定位相关字节码 + if (className == "com.amap.api.location.AMapLocationClient") { + //设置监听器 + klass.methods?.find { + it.name == "setLocationListener" + }.let { methodNode -> + "${context.projectDir.lastPath()}->hook amap map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() + methodNode?.instructions?.insert(createAmapLocationInsnList()) + } + //反注册监听器 + klass.methods?.find { + it.name == "unRegisterLocationListener" + }.let { methodNode -> + "${context.projectDir.lastPath()}->hook amap map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() + methodNode?.instructions?.insert( + createAmapLocationUnRegisterInsnList() + ) + } + //代理getLastKnownLocation + klass.methods?.find { + it.name == "getLastKnownLocation" + }.let { methodNode -> + "${context.projectDir.lastPath()}->hook AMapLocationClient getLastKnownLocation succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() + methodNode?.instructions?.insert(createAMapClientLastKnownLocation()) + } + + } +// //插入高德 地图定位相关字节码 +// if (className == "com.amap.api.maps.AMap") { +// //设置LocationSource代理 +// klass.methods?.find { +// it.name == "setLocationSource" +// }.let { methodNode -> +// "${context.projectDir.lastPath()}->hook amap map LocationSource succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() +// methodNode?.instructions?.insert(createAmapLocationSourceInsnList()) +// } +// } + + //插入高德地图导航相关字节码 + if (className == "com.amap.api.navi.AMapNavi") { + //设置监听器 + klass.methods?.find { + it.name == "addAMapNaviListener" + }.let { methodNode -> + "${context.projectDir.lastPath()}->hook amap map navi succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() + methodNode?.instructions?.insert(createAmapNaviInsnList()) + } + //反注册监听器 + klass.methods?.find { + it.name == "removeAMapNaviListener" + }.let { methodNode -> + "${context.projectDir.lastPath()}->hook amap map navi succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() + methodNode?.instructions?.insert( + createAmapNaviUnRegisterInsnList() + ) + } + } + } + return klass + } + + /** + * 创建Amap地图代码指令 + */ + private fun createAmapLocationInsnList(): InsnList { + return with(InsnList()) { + //在AMapLocationClient的 setLocationListener 方法之中插入自定义代理回调类 + add( + TypeInsnNode( + Opcodes.NEW, + "com/didichuxing/doraemonkit/gps_mock/map/AMapLocationListenerProxy" + ) + ) + add(InsnNode(Opcodes.DUP)) + //访问第一个参数 + add(VarInsnNode(Opcodes.ALOAD, 1)) + add( + MethodInsnNode( + Opcodes.INVOKESPECIAL, + "com/didichuxing/doraemonkit/gps_mock/map/AMapLocationListenerProxy", + "", + "(Lcom/amap/api/location/AMapLocationListener;)V", + false + ) + ) + //对第一个参数进行重新赋值 + add(VarInsnNode(Opcodes.ASTORE, 1)) + this + } + + } + + /** + * 创建Amap地图导航代码指令 + */ + private fun createAmapNaviInsnList(): InsnList { + return with(InsnList()) { + //在AMapNavi的addAMapNaviListener方法之中插入自定义代理回调类 + add( + TypeInsnNode( + Opcodes.NEW, + "com/didichuxing/doraemonkit/gps_mock/map/AMapNaviListenerProxy" + ) + ) + add(InsnNode(Opcodes.DUP)) + //访问第一个参数 + add(VarInsnNode(Opcodes.ALOAD, 1)) + add( + MethodInsnNode( + Opcodes.INVOKESPECIAL, + "com/didichuxing/doraemonkit/gps_mock/map/AMapNaviListenerProxy", + "", + "(Lcom/amap/api/navi/AMapNaviListener;)V", + false + ) + ) + //对第一个参数进行重新赋值 + add(VarInsnNode(Opcodes.ASTORE, 1)) + this + } + + } + + + /** + * 创建Amap LocationSource代码指令 + */ + private fun createAmapLocationSourceInsnList(): InsnList { + return with(InsnList()) { + //在AMapNavi的addAMapNaviListener方法之中插入自定义代理回调类 + add( + TypeInsnNode( + Opcodes.NEW, + "com/didichuxing/doraemonkit/gps_mock/map/AMapLocationSourceProxy" + ) + ) + add(InsnNode(Opcodes.DUP)) + //访问第一个参数 + add(VarInsnNode(Opcodes.ALOAD, 1)) + add( + MethodInsnNode( + Opcodes.INVOKESPECIAL, + "com/didichuxing/doraemonkit/gps_mock/map/AMapLocationSourceProxy", + "", + "(Lcom/amap/api/maps/LocationSource;)V", + false + ) + ) + //对第一个参数进行重新赋值 + add(VarInsnNode(Opcodes.ASTORE, 1)) + this + } + + } + + /** + * 创建AMapLocationClient#LastKnownLocation 字节码替换 + */ + private fun createAMapClientLastKnownLocation(): InsnList { + return with(InsnList()) { + add(VarInsnNode(Opcodes.ALOAD, 0)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/gps_mock/map/AMapLocationClientProxy", + "getLastKnownLocation", + "(Lcom/amap/api/location/AMapLocationClient;)Lcom/amap/api/location/AMapLocation;", + false + ) + ) + add(InsnNode(Opcodes.ARETURN)) + this + } + + } + + /** + * 创建Amap地图UnRegister代码指令 + */ + private fun createAmapLocationUnRegisterInsnList(): InsnList { + return with(InsnList()) { + //访问第一个参数 + add(VarInsnNode(Opcodes.ALOAD, 1)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/gps_mock/map/ThirdMapLocationListenerUtil", + "unRegisterAmapLocationListener", + "(Lcom/amap/api/location/AMapLocationListener;)Lcom/didichuxing/doraemonkit/gps_mock/map/AMapLocationListenerProxy;", + false + ) + ) + add(VarInsnNode(Opcodes.ASTORE, 1)) + this + } + } + + /** + * 创建Amap地图 Navi UnRegister代码指令 + */ + private fun createAmapNaviUnRegisterInsnList(): InsnList { + return with(InsnList()) { + //访问第一个参数 + add(VarInsnNode(Opcodes.ALOAD, 1)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/gps_mock/map/ThirdMapLocationListenerUtil", + "unRegisterAmapNaviListener", + "(Lcom/amap/api/navi/AMapNaviListener;)Lcom/didichuxing/doraemonkit/gps_mock/map/AMapNaviListenerProxy;", + false + ) + ) + add(VarInsnNode(Opcodes.ASTORE, 1)) + this + } + + } + +} diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GPSBDClassTransformer.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GPSBDClassTransformer.kt new file mode 100644 index 000000000..2b25126c5 --- /dev/null +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GPSBDClassTransformer.kt @@ -0,0 +1,197 @@ +package com.didichuxing.doraemonkit.plugin.transform.classtransform + +import com.didichuxing.doraemonkit.plugin.DoKitExtUtil +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.lastPath +import com.didichuxing.doraemonkit.plugin.println +import com.didiglobal.booster.transform.TransformContext +import com.didiglobal.booster.transform.asm.className +import org.gradle.api.Project +import org.objectweb.asm.Opcodes +import org.objectweb.asm.tree.* + + +/** + * didi Create on 2023/3/21 . + * + * Copyright (c) 2023/3/21 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/21 3:06 下午 + * @Description 百度地图 hooks + */ + +class GPSBDClassTransformer : AbsClassTransformer() { + + override fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode { + val className = klass.className + + if (dokit.gpsEnable && dokit.gps.baidu && DoKitExtUtil.DOKIT_GPS_MOCK_INCLUDE) { + //插入百度地图相关字节码 + if (className == "com.baidu.location.LocationClient") { + //拦截注册监听器 + klass.methods?.filter { + it.name == "registerLocationListener" + && (it.desc == "(Lcom/baidu/location/BDLocationListener;)V" || it.desc == "(Lcom/baidu/location/BDAbstractLocationListener;)V") + }?.forEach { methodNode -> + "${context.projectDir.lastPath()}->hook baidu map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() + if (methodNode.desc == "(Lcom/baidu/location/BDLocationListener;)V") { + methodNode?.instructions?.insert(createBDLocationListenerInsnList()) + } else if (methodNode.desc == "(Lcom/baidu/location/BDAbstractLocationListener;)V") { + methodNode?.instructions?.insert(createBDLocationAbsListenerInsnList()) + } + } + //反注册监听器 + klass.methods?.find { + it.name == "unRegisterLocationListener" && it.desc == "(Lcom/baidu/location/BDLocationListener;)V" + }.let { methodNode -> + "${context.projectDir.lastPath()}->hook baidu map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() + methodNode?.instructions?.insert( + createBDLocationUnRegisterInsnList() + ) + } + //反注册监听器 + klass.methods?.find { + it.name == "unRegisterLocationListener" && it.desc == "(Lcom/baidu/location/BDAbstractLocationListener;)V" + }.let { methodNode -> + "${context.projectDir.lastPath()}->hook baidu map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() + methodNode?.instructions?.insert( + createBDAbsLocationUnRegisterInsnList() + ) + } + } + } + return klass + } + + /** + * 创建百度地图代码指令 + */ + private fun createBDLocationListenerInsnList(): InsnList { + return with(InsnList()) { + //在LocationClient的registerLocationListener方法之中插入自定义代理回调类 + add( + TypeInsnNode( + Opcodes.NEW, + "com/didichuxing/doraemonkit/gps_mock/map/BDLocationListenerProxy" + ) + ) + add(InsnNode(Opcodes.DUP)) + //访问第一个参数 + add(VarInsnNode(Opcodes.ALOAD, 1)) + add( + MethodInsnNode( + Opcodes.INVOKESPECIAL, + "com/didichuxing/doraemonkit/gps_mock/map/BDLocationListenerProxy", + "", + "(Lcom/baidu/location/BDLocationListener;)V", + false + ) + ) + //对第一个参数进行重新赋值 + add(VarInsnNode(Opcodes.ASTORE, 1)) + + this + } + + } + + /** + * 创建百度地图代码指令 + */ + private fun createBDLocationAbsListenerInsnList(): InsnList { + return with(InsnList()) { + //在LocationClient的registerLocationListener方法之中插入自定义代理回调类 + add( + TypeInsnNode( + Opcodes.NEW, + "com/didichuxing/doraemonkit/gps_mock/map/BDAbsLocationListenerProxy" + ) + ) + add(InsnNode(Opcodes.DUP)) + //访问第一个参数 + add(VarInsnNode(Opcodes.ALOAD, 1)) + add( + MethodInsnNode( + Opcodes.INVOKESPECIAL, + "com/didichuxing/doraemonkit/gps_mock/map/BDAbsLocationListenerProxy", + "", + "(Lcom/baidu/location/BDAbstractLocationListener;)V", + false + ) + ) + //对第一个参数进行重新赋值 + add(VarInsnNode(Opcodes.ASTORE, 1)) + this + } + } + + /** + * 创建百度地图UnRegister代码指令 + */ + private fun createBDLocationUnRegisterInsnList(): InsnList { + return with(InsnList()) { + //访问第一个参数 + add(VarInsnNode(Opcodes.ALOAD, 1)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/gps_mock/map/ThirdMapLocationListenerUtil", + "unRegisterBDLocationListener", + "(Lcom/baidu/location/BDLocationListener;)Lcom/didichuxing/doraemonkit/gps_mock/map/BDLocationListenerProxy;", + false + ) + ) + add(VarInsnNode(Opcodes.ASTORE, 1)) + this + } + + } + + /** + * 创建百度地图UnRegister代码指令 + */ + private fun createBDAbsLocationUnRegisterInsnList(): InsnList { + return with(InsnList()) { + //访问第一个参数 + add(VarInsnNode(Opcodes.ALOAD, 1)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/gps_mock/map/ThirdMapLocationListenerUtil", + "unRegisterBDLocationListener", + "(Lcom/baidu/location/BDAbstractLocationListener;)Lcom/didichuxing/doraemonkit/gps_mock/map/BDAbsLocationListenerProxy;", + false + ) + ) + //对第一个参数进行重新赋值 + add(VarInsnNode(Opcodes.ASTORE, 1)) + this + } + + } + + /** + * 创建百度地图代码指令 + */ + private fun createBaiduLocationInsnList(): InsnList { + return with(InsnList()) { + //在AMapLocationClient的setLocationListener方法之中插入自定义代理回调类 + add(VarInsnNode(Opcodes.ALOAD, 1)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/gps_mock/map/BDLocationUtil", + "proxy", + "(Lcom/baidu/location/BDLocation;)Lcom/baidu/location/BDLocation;", + false + ) + ) + //对第一个参数进行重新赋值 + add(VarInsnNode(Opcodes.ASTORE, 1)) + this + } + + } +} diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GPSClassTransformer.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GPSClassTransformer.kt new file mode 100644 index 000000000..51f7037f2 --- /dev/null +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GPSClassTransformer.kt @@ -0,0 +1,61 @@ +package com.didichuxing.doraemonkit.plugin.transform.classtransform + +import com.didichuxing.doraemonkit.plugin.DoKitExtUtil +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.lastPath +import com.didichuxing.doraemonkit.plugin.println +import com.didiglobal.booster.kotlinx.asIterable +import com.didiglobal.booster.transform.TransformContext +import com.didiglobal.booster.transform.asm.className +import org.gradle.api.Project +import org.objectweb.asm.Opcodes +import org.objectweb.asm.tree.ClassNode +import org.objectweb.asm.tree.MethodInsnNode + + +/** + * didi Create on 2023/3/21 . + * + * Copyright (c) 2023/3/21 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/21 3:06 下午 + * @Description 系统定位hooks + */ + +class GPSClassTransformer : AbsClassTransformer() { + + override fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode { + val className = klass.className + + //gps字节码操作 + if (dokit.gpsEnable && dokit.gps.local && DoKitExtUtil.DOKIT_GPS_MOCK_INCLUDE) { + //系统 gpsStatus hook + klass.methods.forEach { method -> + method.instructions?.iterator()?.asIterable() + ?.filterIsInstance(MethodInsnNode::class.java)?.filter { + it.opcode == Opcodes.INVOKEVIRTUAL && + it.owner == "android/location/LocationManager" && + it.name == "getGpsStatus" && + it.desc == "(Landroid/location/GpsStatus;)Landroid/location/GpsStatus;" + }?.forEach { + "${context.projectDir.lastPath()}->hook LocationManager#getGpsStatus method succeed in : ${className}_${method.name}_${method.desc}".println() + method.instructions.insert( + it, + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/gps_mock/location/GpsStatusUtil", + "wrap", + "(Landroid/location/GpsStatus;)Landroid/location/GpsStatus;", + false + ) + ) + } + } + } + return klass + } + + +} diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GPSTencentClassTransformer.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GPSTencentClassTransformer.kt new file mode 100644 index 000000000..e90d29e52 --- /dev/null +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GPSTencentClassTransformer.kt @@ -0,0 +1,110 @@ +package com.didichuxing.doraemonkit.plugin.transform.classtransform + +import com.didichuxing.doraemonkit.plugin.DoKitExtUtil +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.lastPath +import com.didichuxing.doraemonkit.plugin.println +import com.didiglobal.booster.transform.TransformContext +import com.didiglobal.booster.transform.asm.className +import org.gradle.api.Project +import org.objectweb.asm.Opcodes +import org.objectweb.asm.tree.* + + +/** + * didi Create on 2023/3/21 . + * + * Copyright (c) 2023/3/21 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/21 3:06 下午 + * @Description 腾讯地图 hooks + */ + +class GPSTencentClassTransformer : AbsClassTransformer() { + + override fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode { + val className = klass.className + + if (dokit.gpsEnable && dokit.gps.tencent && DoKitExtUtil.DOKIT_GPS_MOCK_INCLUDE) { + //插入腾讯地图相关字节码 + if (className == "com.tencent.map.geolocation.TencentLocationManager") { + //持续定位和单次定位 + klass.methods?.filter { + it.name == "requestSingleFreshLocation" || it.name == "requestLocationUpdates" + }?.forEach { methodNode -> + "${context.projectDir.lastPath()}->hook tencent map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() + methodNode?.instructions?.insert(createTencentLocationInsnList()) + } + + //反注册监听器 + klass.methods?.find { + it.name == "removeUpdates" + }.let { methodNode -> + "${context.projectDir.lastPath()}->hook tencent map succeed: ${className}_${methodNode?.name}_${methodNode?.desc}".println() + methodNode?.instructions?.insert( + createTencentLocationUnRegisterInsnList() + ) + } + } + } + return klass + } + + /** + * 创建tencent地图代码指令 + */ + private fun createTencentLocationInsnList(): InsnList { + return with(InsnList()) { + //在AMapLocationClient的setLocationListener方法之中插入自定义代理回调类 + add( + TypeInsnNode( + Opcodes.NEW, + "com/didichuxing/doraemonkit/gps_mock/map/TencentLocationListenerProxy" + ) + ) + add(InsnNode(Opcodes.DUP)) + //访问第一个参数 + add(VarInsnNode(Opcodes.ALOAD, 2)) + add( + MethodInsnNode( + Opcodes.INVOKESPECIAL, + "com/didichuxing/doraemonkit/gps_mock/map/TencentLocationListenerProxy", + "", + "(Lcom/tencent/map/geolocation/TencentLocationListener;)V", + false + ) + ) + //对第二个参数进行重新赋值 + add(VarInsnNode(Opcodes.ASTORE, 2)) + + this + } + + } + + /** + * 创建Tencent地图UnRegister代码指令 + */ + private fun createTencentLocationUnRegisterInsnList(): InsnList { + return with(InsnList()) { + //访问第一个参数 + add(VarInsnNode(Opcodes.ALOAD, 1)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/gps_mock/map/ThirdMapLocationListenerUtil", + "unRegisterTencentLocationListener", + "(Lcom/tencent/map/geolocation/TencentLocationListener;)Lcom/didichuxing/doraemonkit/gps_mock/map/TencentLocationListenerProxy;", + false + ) + ) + add(VarInsnNode(Opcodes.ASTORE, 1)) + this + } + + } + + +} diff --git a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/GSMClassTransformer.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GSMClassTransformer.kt similarity index 79% rename from Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/GSMClassTransformer.kt rename to Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GSMClassTransformer.kt index e6f4a857b..b0d21c920 100644 --- a/Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/GSMClassTransformer.kt +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/GSMClassTransformer.kt @@ -1,14 +1,13 @@ -package com.didichuxing.doraemonkit.plugin.classtransformer +package com.didichuxing.doraemonkit.plugin.transform.classtransform import com.didichuxing.doraemonkit.plugin.* -import com.didichuxing.doraemonkit.plugin.extension.SlowMethodExt -import com.didiglobal.booster.annotations.Priority +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.extension.SlowMethodExtension import com.didiglobal.booster.transform.TransformContext -import com.didiglobal.booster.transform.asm.ClassTransformer import com.didiglobal.booster.transform.asm.asIterable import com.didiglobal.booster.transform.asm.className -import com.google.auto.service.AutoService -import org.objectweb.asm.Opcodes.* +import org.gradle.api.Project +import org.objectweb.asm.Opcodes import org.objectweb.asm.tree.* /** @@ -16,25 +15,26 @@ import org.objectweb.asm.tree.* * 作 者:jint(金台) * 版 本:1.0 * 创建日期:2020/5/14-18:07 - * 描 述:全局慢函数业务代码慢函数 wiki:https://juejin.im/post/5e8d87c4f265da47ad218e6b + * 描 述: + * 全局慢函数业务代码慢函数 + * wiki:https://juejin.im/post/5e8d87c4f265da47ad218e6b + * * 修订历史: * ================================================ + * + * 全局慢函数 + * */ -//@Priority(2) -//@AutoService(ClassTransformer::class) class GSMClassTransformer : AbsClassTransformer() { val thresholdTime = DoKitExtUtil.slowMethodExt.normalMethod.thresholdTime - override fun transform(context: TransformContext, klass: ClassNode): ClassNode { - if (onCommInterceptor(context, klass)) { - return klass - } + override fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode { if (!DoKitExtUtil.dokitSlowMethodSwitchOpen()) { return klass } - if (DoKitExtUtil.SLOW_METHOD_STRATEGY == SlowMethodExt.STRATEGY_STACK) { + if (DoKitExtUtil.SLOW_METHOD_STRATEGY == SlowMethodExtension.STRATEGY_STACK) { return klass } @@ -50,10 +50,10 @@ class GSMClassTransformer : AbsClassTransformer() { if (className.contains(packageName) && notMatchedBlackList(className)) { klass.methods.filter { methodNode -> methodNode.name != "" && - !methodNode.isEmptyMethod() && - !methodNode.isSingleMethod() && - !methodNode.isGetSetMethod() && - !methodNode.isMainMethod(className) + !methodNode.isEmptyMethod() && + !methodNode.isSingleMethod() && + !methodNode.isGetSetMethod() && + !methodNode.isMainMethod(className) }.forEach { methodNode -> methodNode.instructions.asIterable() .filterIsInstance(MethodInsnNode::class.java).let { methodInsnNodes -> @@ -105,22 +105,22 @@ class GSMClassTransformer : AbsClassTransformer() { methodName: String, access: Int ): InsnList { - val isStaticMethod = access and ACC_STATIC != 0 + val isStaticMethod = access and Opcodes.ACC_STATIC != 0 return with(InsnList()) { if (isStaticMethod) { add( FieldInsnNode( - GETSTATIC, + Opcodes.GETSTATIC, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "INSTANCE", "Lcom/didichuxing/doraemonkit/aop/MethodCostUtil;" ) ) - add(IntInsnNode(SIPUSH, thresholdTime)) + add(IntInsnNode(Opcodes.SIPUSH, thresholdTime)) add(LdcInsnNode("$className&$methodName")) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "recodeStaticMethodCostStart", "(ILjava/lang/String;)V", @@ -130,18 +130,18 @@ class GSMClassTransformer : AbsClassTransformer() { } else { add( FieldInsnNode( - GETSTATIC, + Opcodes.GETSTATIC, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "INSTANCE", "Lcom/didichuxing/doraemonkit/aop/MethodCostUtil;" ) ) - add(IntInsnNode(SIPUSH, thresholdTime)) + add(IntInsnNode(Opcodes.SIPUSH, thresholdTime)) add(LdcInsnNode("$className&$methodName")) - add(VarInsnNode(ALOAD, 0)) + add(VarInsnNode(Opcodes.ALOAD, 0)) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "recodeObjectMethodCostStart", "(ILjava/lang/String;Ljava/lang/Object;)V", @@ -164,22 +164,22 @@ class GSMClassTransformer : AbsClassTransformer() { methodName: String, access: Int ): InsnList { - val isStaticMethod = access and ACC_STATIC != 0 + val isStaticMethod = access and Opcodes.ACC_STATIC != 0 return with(InsnList()) { if (isStaticMethod) { add( FieldInsnNode( - GETSTATIC, + Opcodes.GETSTATIC, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "INSTANCE", "Lcom/didichuxing/doraemonkit/aop/MethodCostUtil;" ) ) - add(IntInsnNode(SIPUSH, thresholdTime)) + add(IntInsnNode(Opcodes.SIPUSH, thresholdTime)) add(LdcInsnNode("$className&$methodName")) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "recodeStaticMethodCostEnd", "(ILjava/lang/String;)V", @@ -189,18 +189,18 @@ class GSMClassTransformer : AbsClassTransformer() { } else { add( FieldInsnNode( - GETSTATIC, + Opcodes.GETSTATIC, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "INSTANCE", "Lcom/didichuxing/doraemonkit/aop/MethodCostUtil;" ) ) - add(IntInsnNode(SIPUSH, thresholdTime)) + add(IntInsnNode(Opcodes.SIPUSH, thresholdTime)) add(LdcInsnNode("$className&$methodName")) - add(VarInsnNode(ALOAD, 0)) + add(VarInsnNode(Opcodes.ALOAD, 0)) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "recodeObjectMethodCostEnd", "(ILjava/lang/String;Ljava/lang/Object;)V", @@ -214,4 +214,3 @@ class GSMClassTransformer : AbsClassTransformer() { } - diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/MSDClassTransformer.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/MSDClassTransformer.kt similarity index 79% rename from Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/MSDClassTransformer.kt rename to Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/MSDClassTransformer.kt index 07954979b..b4bdc2c6b 100644 --- a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/MSDClassTransformer.kt +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/MSDClassTransformer.kt @@ -1,14 +1,15 @@ -package com.didichuxing.doraemonkit.plugin.classtransformer +package com.didichuxing.doraemonkit.plugin.transform.classtransform import com.didichuxing.doraemonkit.plugin.* -import com.didichuxing.doraemonkit.plugin.extension.SlowMethodExt +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.extension.SlowMethodExtension import com.didichuxing.doraemonkit.plugin.stack_method.MethodStackNode import com.didichuxing.doraemonkit.plugin.stack_method.MethodStackNodeUtil import com.didiglobal.booster.transform.TransformContext -import com.didiglobal.booster.transform.asm.ClassTransformer import com.didiglobal.booster.transform.asm.asIterable import com.didiglobal.booster.transform.asm.className -import org.objectweb.asm.Opcodes.* +import org.gradle.api.Project +import org.objectweb.asm.Opcodes import org.objectweb.asm.tree.* /** @@ -18,23 +19,21 @@ import org.objectweb.asm.tree.* * 创建日期:2020/5/14-18:07 * 描 述:函数调用栈依赖 慢函数调用栈 wiki:https://juejin.im/post/5e8d87c4f265da47ad218e6b * 修订历史:不要指定自动注入 需要手动在DoKitAsmTransformer中通过配置创建 - * 原理:transform()方法的调用是无序的 原因:哪一个class会先被transformer执行是不确定的 但是每一个class被transformer执行顺序是遵循transformer的Priority规则的 + * + * 原理:transform()方法的调用是无序的 + * 原因:哪一个class会先被transformer执行是不确定的 但是每一个class被transformer执行顺序是遵循transformer的Priority规则的 * ================================================ */ class MSDClassTransformer(private val level: Int = 1) : AbsClassTransformer() { private val thresholdTime = DoKitExtUtil.slowMethodExt.stackMethod.thresholdTime - override fun transform(context: TransformContext, klass: ClassNode): ClassNode { - if (onCommInterceptor(context, klass)) { - return klass - } - + override fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode { if (!DoKitExtUtil.dokitSlowMethodSwitchOpen()) { return klass } - if (DoKitExtUtil.SLOW_METHOD_STRATEGY == SlowMethodExt.STRATEGY_NORMAL) { + if (DoKitExtUtil.SLOW_METHOD_STRATEGY == SlowMethodExtension.STRATEGY_NORMAL) { return klass } @@ -52,10 +51,10 @@ class MSDClassTransformer(private val level: Int = 1) : AbsClassTransformer() { klass.methods.filter { methodNode -> methodNode.name != "" && - !methodNode.isEmptyMethod() && - !methodNode.isSingleMethod() && - !methodNode.isGetSetMethod() && - !methodNode.isMainMethod(klass.className) + !methodNode.isEmptyMethod() && + !methodNode.isSingleMethod() && + !methodNode.isGetSetMethod() && + !methodNode.isMainMethod(klass.className) }.forEach { methodNode -> val key = "${klass.className}&${methodNode.name}&${methodNode.desc}" if (methodStackKeys.contains(key)) { @@ -123,26 +122,26 @@ class MSDClassTransformer(private val level: Int = 1) : AbsClassTransformer() { desc: String, access: Int ): InsnList { - val isStaticMethod = access and ACC_STATIC != 0 + val isStaticMethod = access and Opcodes.ACC_STATIC != 0 return with(InsnList()) { if (isStaticMethod) { add( FieldInsnNode( - GETSTATIC, + Opcodes.GETSTATIC, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "INSTANCE", "Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;" ) ) - add(IntInsnNode(BIPUSH, DoKitExtUtil.STACK_METHOD_LEVEL)) - add(IntInsnNode(BIPUSH, thresholdTime)) - add(IntInsnNode(BIPUSH, level)) + add(IntInsnNode(Opcodes.BIPUSH, DoKitExtUtil.STACK_METHOD_LEVEL)) + add(IntInsnNode(Opcodes.BIPUSH, thresholdTime)) + add(IntInsnNode(Opcodes.BIPUSH, level)) add(LdcInsnNode(className)) add(LdcInsnNode(methodName)) add(LdcInsnNode(desc)) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "recodeStaticMethodCostStart", "(IIILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", @@ -152,22 +151,22 @@ class MSDClassTransformer(private val level: Int = 1) : AbsClassTransformer() { } else { add( FieldInsnNode( - GETSTATIC, + Opcodes.GETSTATIC, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "INSTANCE", "Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;" ) ) - add(IntInsnNode(BIPUSH, DoKitExtUtil.STACK_METHOD_LEVEL)) - add(IntInsnNode(BIPUSH, thresholdTime)) - add(IntInsnNode(BIPUSH, level)) + add(IntInsnNode(Opcodes.BIPUSH, DoKitExtUtil.STACK_METHOD_LEVEL)) + add(IntInsnNode(Opcodes.BIPUSH, thresholdTime)) + add(IntInsnNode(Opcodes.BIPUSH, level)) add(LdcInsnNode(className)) add(LdcInsnNode(methodName)) add(LdcInsnNode(desc)) - add(VarInsnNode(ALOAD, 0)) + add(VarInsnNode(Opcodes.ALOAD, 0)) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "recodeObjectMethodCostStart", "(IIILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V", @@ -191,25 +190,25 @@ class MSDClassTransformer(private val level: Int = 1) : AbsClassTransformer() { desc: String, access: Int ): InsnList { - val isStaticMethod = access and ACC_STATIC != 0 + val isStaticMethod = access and Opcodes.ACC_STATIC != 0 return with(InsnList()) { if (isStaticMethod) { add( FieldInsnNode( - GETSTATIC, + Opcodes.GETSTATIC, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "INSTANCE", "Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;" ) ) - add(IntInsnNode(BIPUSH, thresholdTime)) - add(IntInsnNode(BIPUSH, level)) + add(IntInsnNode(Opcodes.BIPUSH, thresholdTime)) + add(IntInsnNode(Opcodes.BIPUSH, level)) add(LdcInsnNode(className)) add(LdcInsnNode(methodName)) add(LdcInsnNode(desc)) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "recodeStaticMethodCostEnd", "(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", @@ -219,21 +218,21 @@ class MSDClassTransformer(private val level: Int = 1) : AbsClassTransformer() { } else { add( FieldInsnNode( - GETSTATIC, + Opcodes.GETSTATIC, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "INSTANCE", "Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;" ) ) - add(IntInsnNode(BIPUSH, thresholdTime)) - add(IntInsnNode(BIPUSH, level)) + add(IntInsnNode(Opcodes.BIPUSH, thresholdTime)) + add(IntInsnNode(Opcodes.BIPUSH, level)) add(LdcInsnNode(className)) add(LdcInsnNode(methodName)) add(LdcInsnNode(desc)) - add(VarInsnNode(ALOAD, 0)) + add(VarInsnNode(Opcodes.ALOAD, 0)) add( MethodInsnNode( - INVOKEVIRTUAL, + Opcodes.INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "recodeObjectMethodCostEnd", "(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V", @@ -257,4 +256,3 @@ class MSDClassTransformer(private val level: Int = 1) : AbsClassTransformer() { } } - diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/Okhttp3ClassTransformer.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/Okhttp3ClassTransformer.kt new file mode 100644 index 000000000..e8526ed46 --- /dev/null +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/Okhttp3ClassTransformer.kt @@ -0,0 +1,75 @@ +package com.didichuxing.doraemonkit.plugin.transform.classtransform + +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.lastPath +import com.didichuxing.doraemonkit.plugin.println +import com.didiglobal.booster.kotlinx.asIterable +import com.didiglobal.booster.transform.TransformContext +import com.didiglobal.booster.transform.asm.className +import org.gradle.api.Project +import org.objectweb.asm.Opcodes +import org.objectweb.asm.tree.* + + +/** + * didi Create on 2023/3/21 . + * + * Copyright (c) 2023/3/21 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/21 3:06 下午 + * @Description 用一句话说明文件功能 + */ + +class Okhttp3ClassTransformer : AbsClassTransformer() { + + override fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode { + val className = klass.className + + if (dokit.networkEnable && dokit.network.okHttp) { + //hook OkhttpClient + if (className == "okhttp3.OkHttpClient") { + klass.methods?.find { + it.name == "" && it.desc != "()V" + }.let { + "${context.projectDir.lastPath()}->hook OkhttpClient succeed: ${className}_${it?.name}_${it?.desc}".println() + it?.instructions + ?.iterator() + ?.asIterable() + ?.filterIsInstance(FieldInsnNode::class.java) + ?.filter { fieldInsnNode -> + fieldInsnNode.opcode == Opcodes.PUTFIELD + && fieldInsnNode.owner == "okhttp3/OkHttpClient" + && fieldInsnNode.name == "networkInterceptors" + && fieldInsnNode.desc == "Ljava/util/List;" + }?.forEach { fieldInsnNode -> + it.instructions.insert(fieldInsnNode, createOkHttpClientInsnList()) + } + } + } + } + return klass + } + + /** + * 创建OkhttpClient一个数构造函数指令 + */ + private fun createOkHttpClientInsnList(): InsnList { + return with(InsnList()) { + //插入application 拦截器 + add(VarInsnNode(Opcodes.ALOAD, 0)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/aop/OkHttpHook", + "addDoKitIntercept", + "(Lokhttp3/OkHttpClient;)V", + false + ) + ) + this + } + + } +} diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/ThirdLibsClassTransformer.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/ThirdLibsClassTransformer.kt new file mode 100644 index 000000000..b24603419 --- /dev/null +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/ThirdLibsClassTransformer.kt @@ -0,0 +1,89 @@ +package com.didichuxing.doraemonkit.plugin.transform.classtransform + +import com.didichuxing.doraemonkit.plugin.DoKitExtUtil +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.lastPath +import com.didichuxing.doraemonkit.plugin.println +import com.didiglobal.booster.transform.TransformContext +import com.didiglobal.booster.transform.asm.className +import org.gradle.api.Project +import org.objectweb.asm.Opcodes +import org.objectweb.asm.tree.* + + +/** + * didi Create on 2023/3/21 . + * + * Copyright (c) 2023/3/21 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/21 3:06 下午 + * @Description 用一句话说明文件功能 + */ + +class ThirdLibsClassTransformer : AbsClassTransformer() { + + override fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode { + val className = klass.className + + if (dokit.thirdLibEnable) { + //查找DoraemonKitReal&pluginConfig方法并插入指定字节码 + if (className == "com.didichuxing.doraemonkit.DoKitReal") { + //三方库信息注入 + klass.methods?.find { + it.name == "initThirdLibraryInfo" + }.let { methodNode -> + "${context.projectDir.lastPath()}->insert map to the DoKitReal initThirdLibraryInfo succeed".println() + methodNode?.instructions?.insert(createThirdLibInfoInsnList()) + } + } + } + + return klass + } + + /** + * 创建pluginConfig代码指令 + */ + private fun createThirdLibInfoInsnList(): InsnList { + //val insnList = InsnList() + return with(InsnList()) { + //new HashMap + add(TypeInsnNode(Opcodes.NEW, "java/util/HashMap")) + add(InsnNode(Opcodes.DUP)) + add(MethodInsnNode(Opcodes.INVOKESPECIAL, "java/util/HashMap", "", "()V", false)) + //保存变量 + add(VarInsnNode(Opcodes.ASTORE, 0)) + DoKitExtUtil.THIRD_LIB_INFOS.forEach { thirdLibInfo -> + add(VarInsnNode(Opcodes.ALOAD, 0)) + add(LdcInsnNode(thirdLibInfo.variant)) + add(LdcInsnNode(thirdLibInfo.fileSize.toString())) + add( + MethodInsnNode( + Opcodes.INVOKEINTERFACE, + "java/util/Map", + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + false + ) + ) + add(InsnNode(Opcodes.POP)) + } + //将HashMap注入到DokitPluginConfig中 + add(VarInsnNode(Opcodes.ALOAD, 0)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/aop/DokitThirdLibInfo", + "inject", + "(Ljava/util/Map;)V", + false + ) + ) + this + } + } + + +} diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/UrlConnectionTransformer.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/UrlConnectionTransformer.kt new file mode 100644 index 000000000..bf151ae66 --- /dev/null +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/UrlConnectionTransformer.kt @@ -0,0 +1,54 @@ +package com.didichuxing.doraemonkit.plugin.transform.classtransform + +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.lastPath +import com.didichuxing.doraemonkit.plugin.println +import com.didiglobal.booster.kotlinx.asIterable +import com.didiglobal.booster.transform.TransformContext +import com.didiglobal.booster.transform.asm.className +import org.gradle.api.Project +import org.objectweb.asm.Opcodes +import org.objectweb.asm.tree.ClassNode +import org.objectweb.asm.tree.MethodInsnNode + +/** + * ================================================ + * 作 者:jint(金台) + * 版 本:1.0 + * 创建日期:2020/5/14-18:07 + * 描 述:wiki:https://juejin.im/post/5e8d87c4f265da47ad218e6b + * 修订历史: + * ================================================ + */ +class UrlConnectionTransformer : AbsClassTransformer() { + + private val SHADOW_URL = "com/didichuxing/doraemonkit/aop/urlconnection/HttpUrlConnectionProxyUtil" + + private val DESC = "(Ljava/net/URLConnection;)Ljava/net/URLConnection;" + + override fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode { + val className = klass.className + + if (dokit.networkEnable && dokit.network.urlConnect) { + // url connection + klass.methods.forEach { method -> + method.instructions?.iterator()?.asIterable() + ?.filterIsInstance(MethodInsnNode::class.java)?.filter { + it.opcode == Opcodes.INVOKEVIRTUAL && + it.owner == "java/net/URL" && + it.name == "openConnection" && + it.desc == "()Ljava/net/URLConnection;" + }?.forEach { + "${context.projectDir.lastPath()}->hook URL#openConnection method succeed in : ${className}_${method.name}_${method.desc}".println() + method.instructions.insert( + it, + MethodInsnNode(Opcodes.INVOKESTATIC, SHADOW_URL, "proxy", DESC, false) + ) + } + } + } + return klass + } + + +} diff --git a/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/WebViewClassTransformer.kt b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/WebViewClassTransformer.kt new file mode 100644 index 000000000..d2929f1d1 --- /dev/null +++ b/Android/dokit-plugin/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/classtransform/WebViewClassTransformer.kt @@ -0,0 +1,137 @@ +package com.didichuxing.doraemonkit.plugin.transform.classtransform + +import com.didichuxing.doraemonkit.plugin.DoKitExtUtil +import com.didichuxing.doraemonkit.plugin.extension.DoKitExtension +import com.didichuxing.doraemonkit.plugin.formatSuperName +import com.didichuxing.doraemonkit.plugin.lastPath +import com.didichuxing.doraemonkit.plugin.println +import com.didiglobal.booster.kotlinx.asIterable +import com.didiglobal.booster.transform.TransformContext +import com.didiglobal.booster.transform.asm.className +import org.gradle.api.Project +import org.objectweb.asm.Opcodes +import org.objectweb.asm.tree.* + + +/** + * didi Create on 2023/3/21 . + * + * Copyright (c) 2023/3/21 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/21 3:06 下午 + * @Description WebView hooks + */ + +class WebViewClassTransformer : AbsClassTransformer() { + + override fun transform(project: Project, dokit: DoKitExtension, context: TransformContext, klass: ClassNode): ClassNode { + + val className = klass.className + val superName = klass.formatSuperName + + //网络 OkHttp&didi platform aop + if (dokit.webViewEnable) { + //webView 字节码操作 + if (dokit.webView.network) { + //普通的webview + klass.methods.forEach { method -> + method.instructions?.iterator()?.asIterable() + ?.filterIsInstance(MethodInsnNode::class.java)?.filter { + if ("loadUrl".equals(it.name)) { + "hook loadUrl() all ${className} ^${superName}^${it.owner} :: ${it.name} , ${it.desc} ,${it.opcode}".println() + } + (it.opcode == Opcodes.INVOKEVIRTUAL || it.opcode == Opcodes.INVOKESPECIAL) + && it.name == "loadUrl" + && (it.desc == "(Ljava/lang/String;)V" || it.desc == "(Ljava/lang/String;Ljava/util/Map;)V") + && isWebViewOwnerNameMatched(it.owner) + }?.forEach { + "${context.projectDir.lastPath()}->hook WebView#loadurl method succeed in : ${className}_${method.name}_${method.desc} | ${it.owner}".println() + if (it.desc == "(Ljava/lang/String;)V") { + method.instructions.insertBefore(it, createWebViewInsnList()) + } else { + method.instructions.insertBefore(it, createWebViewInsnList(method)) + } + } + } + } + } + return klass + } + + + private fun isWebViewOwnerNameMatched(ownerName: String): Boolean { + return ownerName == "android/webkit/WebView" || + ownerName == "com/tencent/smtt/sdk/WebView" || + ownerName.contentEquals("WebView") || + ownerName == DoKitExtUtil.WEBVIEW_CLASS_NAME + } + + + /** + * 创建webView函数指令集 + * 参考:https://www.jianshu.com/p/7d623f441bed + */ + private fun createWebViewInsnList(): InsnList { + return with(InsnList()) { + //复制栈顶的2个指令 指令集变为 比如 aload 2 aload0 / aload 2 aload0 + add(InsnNode(Opcodes.DUP2)) + //抛出最上面的指令 指令集变为 aload 2 aload0 / aload 2 其中 aload 2即为我们所需要的对象 + add(InsnNode(Opcodes.POP)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/aop/WebViewHook", + "inject", + "(Ljava/lang/Object;)V", + false + ) + ) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/aop/WebViewHook", + "getSafeUrl", + "(Ljava/lang/String;)Ljava/lang/String;", + false + ) + ) + this + } + } + + /** + * 创建webView函数指令集 (多参数,先存参数然后取出) + * 参考:https://www.jianshu.com/p/7d623f441bed + */ + private fun createWebViewInsnList(method: MethodNode): InsnList { + val size = method.localVariables.size + return with(InsnList()) { + add(VarInsnNode(Opcodes.ASTORE, size + 1)) + add(VarInsnNode(Opcodes.ASTORE, size)) + add(InsnNode(Opcodes.DUP)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/aop/WebViewHook", + "inject", + "(Ljava/lang/Object;)V", + false + ) + ) + add(VarInsnNode(Opcodes.ALOAD, size)) + add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/didichuxing/doraemonkit/aop/WebViewHook", + "getSafeUrl", + "(Ljava/lang/String;)Ljava/lang/String;", + false + ) + ) + add(VarInsnNode(Opcodes.ALOAD, size + 1)) + this + } + } +} diff --git a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/DoKitReal.kt b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/DoKitReal.kt index 37c03801c..35a680ec0 100644 --- a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/DoKitReal.kt +++ b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/DoKitReal.kt @@ -85,11 +85,8 @@ object DoKitReal { registerNetworkStatusChangedListener() startAppHealth() initGpsMock() - // 临时处理, Android S(31) 上Sand hook必崩 - if (Build.VERSION.SDK_INT <= 30) { - //全局运行时hook - globalRunTimeHook() - } + + globalRunTimeHook() //注册全局的activity生命周期回调 app.registerActivityLifecycleCallbacks(DoKitActivityLifecycleCallbacks()) diff --git a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/aop/DokitThirdLibInfo.java b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/aop/DokitThirdLibInfo.java index a0db9051a..6cac0e433 100644 --- a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/aop/DokitThirdLibInfo.java +++ b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/aop/DokitThirdLibInfo.java @@ -1,11 +1,9 @@ package com.didichuxing.doraemonkit.aop; -import com.didichuxing.doraemonkit.util.LogHelper; import java.util.HashMap; import java.util.Iterator; import java.util.Map; -import java.util.function.BiConsumer; /** * ================================================ diff --git a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/connect/DoKitConnectFragment.kt b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/connect/DoKitConnectFragment.kt index bd6dbec87..f014988a1 100644 --- a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/connect/DoKitConnectFragment.kt +++ b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/connect/DoKitConnectFragment.kt @@ -193,7 +193,7 @@ class DoKitConnectFragment : BaseFragment() { uri?.let { val name = uri.host.toString() val time = TimeUtils.date2String(Date()) - val history = ConnectAddress(name, url, time) + val history = ConnectAddress(name, url!!, time) ConnectAddressStore.saveAddress(history) handleConnect(history) } diff --git a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/h5_help/DoKitWebViewClient.kt b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/h5_help/DoKitWebViewClient.kt index f36ee4ad1..a4af9d317 100644 --- a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/h5_help/DoKitWebViewClient.kt +++ b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/h5_help/DoKitWebViewClient.kt @@ -1,11 +1,7 @@ package com.didichuxing.doraemonkit.kit.h5_help import android.app.Activity -import android.graphics.Bitmap -import android.net.http.SslError import android.os.Build -import android.os.Message -import android.view.KeyEvent import android.webkit.* import androidx.annotation.RequiresApi import com.didichuxing.doraemonkit.DoKit @@ -33,12 +29,10 @@ import java.net.URLDecoder * 修订历史: * ================================================ */ -class DoKitWebViewClient(webViewClient: WebViewClient?, userAgent: String) : WebViewClient() { +class DoKitWebViewClient(webViewClient: WebViewClient, userAgent: String) : ProxyWebViewClient(webViewClient) { private val TAG = "DoKitWebViewClient" - private val mWebViewClient: WebViewClient? = webViewClient private val mUserAgent = userAgent - //private val mOkHttpClient = OkHttpClient() /** * 更新悬浮窗上的链接 @@ -58,22 +52,25 @@ class DoKitWebViewClient(webViewClient: WebViewClient?, userAgent: String) : Web override fun shouldOverrideUrlLoading(view: WebView?, url: String): Boolean { updateH5DokitUrl(view, url) - if (mWebViewClient != null) { - return mWebViewClient.shouldOverrideUrlLoading(view, url) - } - return super.shouldOverrideUrlLoading(view, url) } + @RequiresApi(Build.VERSION_CODES.N) + override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean { + updateH5DokitUrl(view, request?.url?.path) + return super.shouldOverrideUrlLoading(view, request) + } + + override fun doUpdateVisitedHistory(view: WebView?, url: String?, isReload: Boolean) { + updateH5DokitUrl(view, url) + super.doUpdateVisitedHistory(view, url, isReload) + } /** * https://developer.android.google.cn/reference/android/webkit/WebViewClient.html#shouldInterceptRequest(android.webkit.WebView,%20android.webkit.WebResourceRequest) */ @RequiresApi(Build.VERSION_CODES.LOLLIPOP) - override fun shouldInterceptRequest( - view: WebView?, - request: WebResourceRequest? - ): WebResourceResponse? { + override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest?): WebResourceResponse? { //开关均被关闭则不进行拦截 if (!DoKitManager.H5_JS_INJECT && !DoKitManager.H5_VCONSOLE_INJECT && !DoKitManager.H5_DOKIT_MC_INJECT) { return super.shouldInterceptRequest(view, request) @@ -152,12 +149,7 @@ class DoKitWebViewClient(webViewClient: WebViewClient?, userAgent: String) : Web * 处理数据mock的相关逻辑 */ @RequiresApi(Build.VERSION_CODES.LOLLIPOP) - private fun dealMock( - requestBean: JsRequestBean, - url: HttpUrl?, - view: WebView?, - request: WebResourceRequest? - ): WebResourceResponse? { + private fun dealMock(requestBean: JsRequestBean, url: HttpUrl?, view: WebView?, request: WebResourceRequest?): WebResourceResponse? { url?.let { httpUrl -> try { val path = URLDecoder.decode(OkHttpWrap.toEncodedPath(httpUrl), "utf-8") @@ -194,7 +186,7 @@ class DoKitWebViewClient(webViewClient: WebViewClient?, userAgent: String) : Web try { //构建okhttp用来抓包 val newRequest: Request = - JsHttpUtil.createOkHttpRequest(requestBean,mUserAgent) + JsHttpUtil.createOkHttpRequest(requestBean, mUserAgent) if (JsHttpUtil.matchWhiteHost(newRequest)) { //发送模拟请求 OkhttpClientUtil.okhttpClient.newCall(newRequest).execute() @@ -207,7 +199,7 @@ class DoKitWebViewClient(webViewClient: WebViewClient?, userAgent: String) : Web } val newRequest: Request = - JsHttpUtil.createOkHttpRequest(requestBean,mUserAgent) + JsHttpUtil.createOkHttpRequest(requestBean, mUserAgent) //发送模拟请求 val newResponse = OkhttpClientUtil.okhttpClient.newCall(newRequest).execute() @@ -323,190 +315,5 @@ class DoKitWebViewClient(webViewClient: WebViewClient?, userAgent: String) : Web return doc.toString() } - @RequiresApi(Build.VERSION_CODES.N) - override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean { - updateH5DokitUrl(view, request?.url?.path) - if (mWebViewClient != null) { - return mWebViewClient.shouldOverrideUrlLoading(view, request) - } - return super.shouldOverrideUrlLoading(view, request) - } - - override fun shouldInterceptRequest(view: WebView?, url: String?): WebResourceResponse? { - if (mWebViewClient != null) { - return mWebViewClient.shouldInterceptRequest(view, url) - } - return super.shouldInterceptRequest(view, url) - } - - override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) { - if (mWebViewClient != null) { - return mWebViewClient.onPageStarted(view, url, favicon) - } - super.onPageStarted(view, url, favicon) - } - - override fun onPageFinished(view: WebView?, url: String?) { - if (mWebViewClient != null) { - return mWebViewClient.onPageFinished(view, url) - } - - super.onPageFinished(view, url) - } - - override fun onLoadResource(view: WebView?, url: String?) { - if (mWebViewClient != null) { - return mWebViewClient.onLoadResource(view, url) - } - super.onLoadResource(view, url) - } - - @RequiresApi(Build.VERSION_CODES.M) - override fun onPageCommitVisible(view: WebView?, url: String?) { - if (mWebViewClient != null) { - return mWebViewClient.onPageCommitVisible(view, url) - } - super.onPageCommitVisible(view, url) - } - - override fun onTooManyRedirects(view: WebView?, cancelMsg: Message?, continueMsg: Message?) { - if (mWebViewClient != null) { - return mWebViewClient.onTooManyRedirects(view, cancelMsg, continueMsg) - } - super.onTooManyRedirects(view, cancelMsg, continueMsg) - } - - override fun onReceivedError( - view: WebView?, - errorCode: Int, - description: String?, - failingUrl: String? - ) { - if (mWebViewClient != null) { - return mWebViewClient.onReceivedError(view, errorCode, description, failingUrl) - } - super.onReceivedError(view, errorCode, description, failingUrl) - } - - @RequiresApi(Build.VERSION_CODES.M) - override fun onReceivedError( - view: WebView?, - request: WebResourceRequest?, - error: WebResourceError? - ) { - if (mWebViewClient != null) { - return mWebViewClient.onReceivedError(view, request, error) - } - super.onReceivedError(view, request, error) - } - - @RequiresApi(Build.VERSION_CODES.M) - override fun onReceivedHttpError( - view: WebView?, - request: WebResourceRequest?, - errorResponse: WebResourceResponse? - ) { - if (mWebViewClient != null) { - return mWebViewClient.onReceivedHttpError(view, request, errorResponse) - } - super.onReceivedHttpError(view, request, errorResponse) - } - - override fun onFormResubmission(view: WebView?, dontResend: Message?, resend: Message?) { - if (mWebViewClient != null) { - return mWebViewClient.onFormResubmission(view, dontResend, resend) - } - super.onFormResubmission(view, dontResend, resend) - } - - override fun doUpdateVisitedHistory(view: WebView?, url: String?, isReload: Boolean) { - updateH5DokitUrl(view, url) - if (mWebViewClient != null) { - return mWebViewClient.doUpdateVisitedHistory(view, url, isReload) - } - super.doUpdateVisitedHistory(view, url, isReload) - } - - override fun onReceivedSslError(view: WebView?, handler: SslErrorHandler?, error: SslError?) { - if (mWebViewClient != null) { - return mWebViewClient.onReceivedSslError(view, handler, error) - } - super.onReceivedSslError(view, handler, error) - } - - @RequiresApi(Build.VERSION_CODES.LOLLIPOP) - override fun onReceivedClientCertRequest(view: WebView?, request: ClientCertRequest?) { - if (mWebViewClient != null) { - return mWebViewClient.onReceivedClientCertRequest(view, request) - } - super.onReceivedClientCertRequest(view, request) - } - - override fun onReceivedHttpAuthRequest( - view: WebView?, - handler: HttpAuthHandler?, - host: String?, - realm: String? - ) { - if (mWebViewClient != null) { - return mWebViewClient.onReceivedHttpAuthRequest(view, handler, host, realm) - } - super.onReceivedHttpAuthRequest(view, handler, host, realm) - } - - override fun shouldOverrideKeyEvent(view: WebView?, event: KeyEvent?): Boolean { - if (mWebViewClient != null) { - return mWebViewClient.shouldOverrideKeyEvent(view, event) - } - return super.shouldOverrideKeyEvent(view, event) - } - - override fun onUnhandledKeyEvent(view: WebView?, event: KeyEvent?) { - if (mWebViewClient != null) { - return mWebViewClient.onUnhandledKeyEvent(view, event) - } - super.onUnhandledKeyEvent(view, event) - } - - override fun onScaleChanged(view: WebView?, oldScale: Float, newScale: Float) { - if (mWebViewClient != null) { - return mWebViewClient.onScaleChanged(view, oldScale, newScale) - } - super.onScaleChanged(view, oldScale, newScale) - } - - override fun onReceivedLoginRequest( - view: WebView?, - realm: String?, - account: String?, - args: String? - ) { - if (mWebViewClient != null) { - return mWebViewClient.onReceivedLoginRequest(view, realm, account, args) - } - super.onReceivedLoginRequest(view, realm, account, args) - } - - @RequiresApi(Build.VERSION_CODES.O) - override fun onRenderProcessGone(view: WebView?, detail: RenderProcessGoneDetail?): Boolean { - if (mWebViewClient != null) { - return mWebViewClient.onRenderProcessGone(view, detail) - } - return super.onRenderProcessGone(view, detail) - } - - @RequiresApi(Build.VERSION_CODES.O_MR1) - override fun onSafeBrowsingHit( - view: WebView?, - request: WebResourceRequest?, - threatType: Int, - callback: SafeBrowsingResponse? - ) { - if (mWebViewClient != null) { - return mWebViewClient.onSafeBrowsingHit(view, request, threatType, callback) - } - super.onSafeBrowsingHit(view, request, threatType, callback) - } - } diff --git a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/h5_help/DoKitX5WebViewClient.kt b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/h5_help/DoKitX5WebViewClient.kt index 57df02821..82615e38b 100644 --- a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/h5_help/DoKitX5WebViewClient.kt +++ b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/h5_help/DoKitX5WebViewClient.kt @@ -1,10 +1,7 @@ package com.didichuxing.doraemonkit.kit.h5_help import android.app.Activity -import android.graphics.Bitmap import android.os.Build -import android.os.Message -import android.view.KeyEvent import androidx.annotation.RequiresApi import com.didichuxing.doraemonkit.DoKit import com.didichuxing.doraemonkit.util.ConvertUtils @@ -33,10 +30,9 @@ import java.net.URLDecoder * 修订历史: * ================================================ */ -class DoKitX5WebViewClient(webViewClient: WebViewClient?, userAgent: String) : WebViewClient() { +class DoKitX5WebViewClient(webViewClient: WebViewClient, userAgent: String) : ProxyX5WebViewClient(webViewClient) { private val TAG = "DoKitWebViewClient" - private val mWebViewClient: WebViewClient? = webViewClient private val mUserAgent = userAgent /** @@ -57,18 +53,23 @@ class DoKitX5WebViewClient(webViewClient: WebViewClient?, userAgent: String) : W override fun shouldOverrideUrlLoading(view: WebView?, url: String): Boolean { updateH5DokitUrl(view, url) - if (mWebViewClient != null) { - return mWebViewClient.shouldOverrideUrlLoading(view, url) - } - return super.shouldOverrideUrlLoading(view, url) } + override fun doUpdateVisitedHistory(view: WebView?, url: String?, isReload: Boolean) { + updateH5DokitUrl(view, url) + super.doUpdateVisitedHistory(view, url, isReload) + } + + @RequiresApi(Build.VERSION_CODES.N) + override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean { + updateH5DokitUrl(view, request?.url?.path) + return super.shouldOverrideUrlLoading(view, request) + } + + @RequiresApi(Build.VERSION_CODES.LOLLIPOP) - override fun shouldInterceptRequest( - view: WebView?, - request: WebResourceRequest? - ): WebResourceResponse? { + override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest?): WebResourceResponse? { //开关均被关闭则不进行拦截 if (!DoKitManager.H5_JS_INJECT && !DoKitManager.H5_VCONSOLE_INJECT) { return super.shouldInterceptRequest(view, request) @@ -132,7 +133,6 @@ class DoKitX5WebViewClient(webViewClient: WebViewClient?, userAgent: String) : W } else { return super.shouldInterceptRequest(view, request) } - } } @@ -142,12 +142,7 @@ class DoKitX5WebViewClient(webViewClient: WebViewClient?, userAgent: String) : W /** * 处理数据mock的相关逻辑 */ - private fun dealMock( - requestBean: JsRequestBean, - url: HttpUrl?, - view: WebView?, - request: WebResourceRequest? - ): WebResourceResponse? { + private fun dealMock(requestBean: JsRequestBean, url: HttpUrl?, view: WebView?, request: WebResourceRequest?): WebResourceResponse? { url?.let { httpUrl -> try { val path = URLDecoder.decode(OkHttpWrap.toEncodedPath(httpUrl), "utf-8") @@ -279,181 +274,4 @@ class DoKitX5WebViewClient(webViewClient: WebViewClient?, userAgent: String) : W return doc.toString() } - - @RequiresApi(Build.VERSION_CODES.N) - override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean { - updateH5DokitUrl(view, request?.url?.path) - if (mWebViewClient != null) { - return mWebViewClient.shouldOverrideUrlLoading(view, request) - } - return super.shouldOverrideUrlLoading(view, request) - } - - override fun shouldInterceptRequest(view: WebView?, url: String?): WebResourceResponse? { - if (mWebViewClient != null) { - return mWebViewClient.shouldInterceptRequest(view, url) - } - return super.shouldInterceptRequest(view, url) - } - - override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) { - if (mWebViewClient != null) { - return mWebViewClient.onPageStarted(view, url, favicon) - } - super.onPageStarted(view, url, favicon) - } - - override fun onPageFinished(view: WebView?, url: String?) { - if (mWebViewClient != null) { - return mWebViewClient.onPageFinished(view, url) - } - super.onPageFinished(view, url) - } - - override fun onLoadResource(view: WebView?, url: String?) { - if (mWebViewClient != null) { - return mWebViewClient.onLoadResource(view, url) - } - super.onLoadResource(view, url) - } - - @RequiresApi(Build.VERSION_CODES.M) - override fun onPageCommitVisible(view: WebView?, url: String?) { - if (mWebViewClient != null) { - return mWebViewClient.onPageCommitVisible(view, url) - } - super.onPageCommitVisible(view, url) - } - - override fun onTooManyRedirects(view: WebView?, cancelMsg: Message?, continueMsg: Message?) { - if (mWebViewClient != null) { - return mWebViewClient.onTooManyRedirects(view, cancelMsg, continueMsg) - } - super.onTooManyRedirects(view, cancelMsg, continueMsg) - } - - override fun onReceivedError( - view: WebView?, - errorCode: Int, - description: String?, - failingUrl: String? - ) { - if (mWebViewClient != null) { - return mWebViewClient.onReceivedError(view, errorCode, description, failingUrl) - } - super.onReceivedError(view, errorCode, description, failingUrl) - } - - @RequiresApi(Build.VERSION_CODES.M) - override fun onReceivedError( - view: WebView?, - request: WebResourceRequest?, - error: WebResourceError? - ) { - if (mWebViewClient != null) { - return mWebViewClient.onReceivedError(view, request, error) - } - super.onReceivedError(view, request, error) - } - - @RequiresApi(Build.VERSION_CODES.M) - override fun onReceivedHttpError( - view: WebView?, - request: WebResourceRequest?, - errorResponse: WebResourceResponse? - ) { - if (mWebViewClient != null) { - return mWebViewClient.onReceivedHttpError(view, request, errorResponse) - } - super.onReceivedHttpError(view, request, errorResponse) - } - - override fun onFormResubmission(view: WebView?, dontResend: Message?, resend: Message?) { - if (mWebViewClient != null) { - return mWebViewClient.onFormResubmission(view, dontResend, resend) - } - super.onFormResubmission(view, dontResend, resend) - } - - override fun doUpdateVisitedHistory(view: WebView?, url: String?, isReload: Boolean) { - updateH5DokitUrl(view, url) - if (mWebViewClient != null) { - return mWebViewClient.doUpdateVisitedHistory(view, url, isReload) - } - super.doUpdateVisitedHistory(view, url, isReload) - } - - - @RequiresApi(Build.VERSION_CODES.LOLLIPOP) - override fun onReceivedClientCertRequest(view: WebView?, request: ClientCertRequest?) { - if (mWebViewClient != null) { - return mWebViewClient.onReceivedClientCertRequest(view, request) - } - super.onReceivedClientCertRequest(view, request) - } - - override fun onReceivedHttpAuthRequest( - view: WebView?, - handler: HttpAuthHandler?, - host: String?, - realm: String? - ) { - if (mWebViewClient != null) { - return mWebViewClient.onReceivedHttpAuthRequest(view, handler, host, realm) - } - super.onReceivedHttpAuthRequest(view, handler, host, realm) - } - - override fun shouldOverrideKeyEvent(view: WebView?, event: KeyEvent?): Boolean { - if (mWebViewClient != null) { - return mWebViewClient.shouldOverrideKeyEvent(view, event) - } - return super.shouldOverrideKeyEvent(view, event) - } - - override fun onUnhandledKeyEvent(view: WebView?, event: KeyEvent?) { - if (mWebViewClient != null) { - return mWebViewClient.onUnhandledKeyEvent(view, event) - } - super.onUnhandledKeyEvent(view, event) - } - - override fun onScaleChanged(view: WebView?, oldScale: Float, newScale: Float) { - if (mWebViewClient != null) { - return mWebViewClient.onScaleChanged(view, oldScale, newScale) - } - super.onScaleChanged(view, oldScale, newScale) - } - - override fun onReceivedLoginRequest( - view: WebView?, - realm: String?, - account: String?, - args: String? - ) { - if (mWebViewClient != null) { - return mWebViewClient.onReceivedLoginRequest(view, realm, account, args) - } - super.onReceivedLoginRequest(view, realm, account, args) - } - - - override fun onReceivedSslError( - p0: WebView?, - p1: SslErrorHandler?, - p2: com.tencent.smtt.export.external.interfaces.SslError? - ) { - - if (mWebViewClient != null) { - return mWebViewClient.onReceivedSslError(p0, p1, p2) - } - super.onReceivedSslError(p0, p1, p2) - } - - override fun onDetectedBlankScreen(p0: String?, p1: Int) { - if (mWebViewClient != null) { - return mWebViewClient.onDetectedBlankScreen(p0, p1) - } - super.onDetectedBlankScreen(p0, p1) - } } diff --git a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/h5_help/JsHttpUtil.kt b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/h5_help/JsHttpUtil.kt index 23617cdf8..7125a07e3 100644 --- a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/h5_help/JsHttpUtil.kt +++ b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/h5_help/JsHttpUtil.kt @@ -27,7 +27,7 @@ import org.json.JSONObject * 修订历史: * ================================================ */ -internal object JsHttpUtil { +object JsHttpUtil { val TAG = "JsHttpUtil" /** @@ -443,4 +443,4 @@ internal object JsHttpUtil { return false } -} \ No newline at end of file +} diff --git a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/h5_help/ProxyWebViewClient.kt b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/h5_help/ProxyWebViewClient.kt new file mode 100644 index 000000000..b64c36d60 --- /dev/null +++ b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/h5_help/ProxyWebViewClient.kt @@ -0,0 +1,128 @@ +package com.didichuxing.doraemonkit.kit.h5_help + +import android.graphics.Bitmap +import android.net.http.SslError +import android.os.Build +import android.os.Message +import android.view.KeyEvent +import android.webkit.* +import androidx.annotation.RequiresApi + +/** + * didi Create on 2023/3/23 . + * + * Copyright (c) 2023/3/23 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/23 11:29 上午 + * @Description WebViewClient 代理 + */ + +open class ProxyWebViewClient(webViewClient: WebViewClient) : WebViewClient() { + + private val mWebViewClient: WebViewClient = webViewClient + + + override fun shouldOverrideUrlLoading(view: WebView?, url: String): Boolean { + return mWebViewClient.shouldOverrideUrlLoading(view, url) + } + + @RequiresApi(Build.VERSION_CODES.N) + override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean { + return mWebViewClient.shouldOverrideUrlLoading(view, request) + } + + override fun shouldInterceptRequest(view: WebView?, url: String?): WebResourceResponse? { + return mWebViewClient.shouldInterceptRequest(view, url) + } + + @RequiresApi(Build.VERSION_CODES.LOLLIPOP) + override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest?): WebResourceResponse? { + return mWebViewClient.shouldInterceptRequest(view, request) + } + + override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) { + mWebViewClient.onPageStarted(view, url, favicon) + } + + override fun onPageFinished(view: WebView?, url: String?) { + mWebViewClient.onPageFinished(view, url) + } + + override fun onLoadResource(view: WebView?, url: String?) { + mWebViewClient.onLoadResource(view, url) + } + + @RequiresApi(Build.VERSION_CODES.M) + override fun onPageCommitVisible(view: WebView?, url: String?) { + mWebViewClient.onPageCommitVisible(view, url) + } + + override fun onTooManyRedirects(view: WebView?, cancelMsg: Message?, continueMsg: Message?) { + mWebViewClient.onTooManyRedirects(view, cancelMsg, continueMsg) + } + + override fun onReceivedError(view: WebView?, errorCode: Int, description: String?, failingUrl: String?) { + mWebViewClient.onReceivedError(view, errorCode, description, failingUrl) + } + + @RequiresApi(Build.VERSION_CODES.M) + override fun onReceivedError(view: WebView?, request: WebResourceRequest?, error: WebResourceError?) { + mWebViewClient.onReceivedError(view, request, error) + } + + @RequiresApi(Build.VERSION_CODES.M) + override fun onReceivedHttpError(view: WebView?, request: WebResourceRequest?, errorResponse: WebResourceResponse?) { + mWebViewClient.onReceivedHttpError(view, request, errorResponse) + } + + override fun onFormResubmission(view: WebView?, dontResend: Message?, resend: Message?) { + mWebViewClient.onFormResubmission(view, dontResend, resend) + } + + override fun doUpdateVisitedHistory(view: WebView?, url: String?, isReload: Boolean) { + mWebViewClient.doUpdateVisitedHistory(view, url, isReload) + } + + override fun onReceivedSslError(view: WebView?, handler: SslErrorHandler?, error: SslError?) { + mWebViewClient.onReceivedSslError(view, handler, error) + } + + @RequiresApi(Build.VERSION_CODES.LOLLIPOP) + override fun onReceivedClientCertRequest(view: WebView?, request: ClientCertRequest?) { + mWebViewClient.onReceivedClientCertRequest(view, request) + } + + override fun onReceivedHttpAuthRequest(view: WebView?, handler: HttpAuthHandler?, host: String?, realm: String?) { + mWebViewClient.onReceivedHttpAuthRequest(view, handler, host, realm) + } + + override fun shouldOverrideKeyEvent(view: WebView?, event: KeyEvent?): Boolean { + return mWebViewClient.shouldOverrideKeyEvent(view, event) + } + + override fun onUnhandledKeyEvent(view: WebView?, event: KeyEvent?) { + mWebViewClient.onUnhandledKeyEvent(view, event) + } + + override fun onScaleChanged(view: WebView?, oldScale: Float, newScale: Float) { + mWebViewClient.onScaleChanged(view, oldScale, newScale) + } + + override fun onReceivedLoginRequest(view: WebView?, realm: String?, account: String?, args: String?) { + mWebViewClient.onReceivedLoginRequest(view, realm, account, args) + } + + @RequiresApi(Build.VERSION_CODES.O) + override fun onRenderProcessGone(view: WebView?, detail: RenderProcessGoneDetail?): Boolean { + return mWebViewClient.onRenderProcessGone(view, detail) + } + + @RequiresApi(Build.VERSION_CODES.O_MR1) + override fun onSafeBrowsingHit(view: WebView?, request: WebResourceRequest?, threatType: Int, callback: SafeBrowsingResponse?) { + mWebViewClient.onSafeBrowsingHit(view, request, threatType, callback) + } + + +} diff --git a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/h5_help/ProxyX5WebViewClient.kt b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/h5_help/ProxyX5WebViewClient.kt new file mode 100644 index 000000000..1cf1638a1 --- /dev/null +++ b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/h5_help/ProxyX5WebViewClient.kt @@ -0,0 +1,118 @@ +package com.didichuxing.doraemonkit.kit.h5_help + +import android.graphics.Bitmap +import android.os.Bundle +import android.os.Message +import android.view.KeyEvent +import com.tencent.smtt.export.external.interfaces.* +import com.tencent.smtt.sdk.WebView +import com.tencent.smtt.sdk.WebViewClient + +/** + * didi Create on 2023/3/23 . + * + * Copyright (c) 2023/3/23 by didiglobal.com. + * + * @author zhangjun + * @version 1.0 + * @Date 2023/3/23 11:29 上午 + * @Description WebViewClient 代理 + */ + +open class ProxyX5WebViewClient(webViewClient: WebViewClient) : WebViewClient() { + + private val mWebViewClient: WebViewClient = webViewClient + + + override fun shouldOverrideUrlLoading(view: WebView?, url: String): Boolean { + return mWebViewClient.shouldOverrideUrlLoading(view, url) + } + + override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean { + return mWebViewClient.shouldOverrideUrlLoading(view, request) + } + + override fun shouldInterceptRequest(p0: WebView?, p1: WebResourceRequest?, p2: Bundle?): WebResourceResponse { + return mWebViewClient.shouldInterceptRequest(p0, p1, p2) + } + + override fun shouldInterceptRequest(view: WebView?, url: String?): WebResourceResponse? { + return mWebViewClient.shouldInterceptRequest(view, url) + } + + override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest?): WebResourceResponse? { + return mWebViewClient.shouldInterceptRequest(view, request) + } + + override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) { + mWebViewClient.onPageStarted(view, url, favicon) + } + + override fun onPageFinished(view: WebView?, url: String?) { + mWebViewClient.onPageFinished(view, url) + } + + override fun onLoadResource(view: WebView?, url: String?) { + mWebViewClient.onLoadResource(view, url) + } + + override fun onPageCommitVisible(view: WebView?, url: String?) { + mWebViewClient.onPageCommitVisible(view, url) + } + + override fun onTooManyRedirects(view: WebView?, cancelMsg: Message?, continueMsg: Message?) { + mWebViewClient.onTooManyRedirects(view, cancelMsg, continueMsg) + } + + override fun onReceivedError(view: WebView?, errorCode: Int, description: String?, failingUrl: String?) { + mWebViewClient.onReceivedError(view, errorCode, description, failingUrl) + } + + override fun onReceivedError(view: WebView?, request: WebResourceRequest?, error: WebResourceError?) { + mWebViewClient.onReceivedError(view, request, error) + } + + override fun onReceivedHttpError(view: WebView?, request: WebResourceRequest?, errorResponse: WebResourceResponse?) { + mWebViewClient.onReceivedHttpError(view, request, errorResponse) + } + + override fun onFormResubmission(view: WebView?, dontResend: Message?, resend: Message?) { + mWebViewClient.onFormResubmission(view, dontResend, resend) + } + + override fun doUpdateVisitedHistory(view: WebView?, url: String?, isReload: Boolean) { + mWebViewClient.doUpdateVisitedHistory(view, url, isReload) + } + + override fun onReceivedSslError(view: WebView, handler: SslErrorHandler, error: SslError) { + mWebViewClient.onReceivedSslError(view, handler, error) + } + + override fun onReceivedClientCertRequest(view: WebView?, request: ClientCertRequest?) { + mWebViewClient.onReceivedClientCertRequest(view, request) + } + + override fun onReceivedHttpAuthRequest(view: WebView?, handler: HttpAuthHandler?, host: String?, realm: String?) { + mWebViewClient.onReceivedHttpAuthRequest(view, handler, host, realm) + } + + override fun onReceivedLoginRequest(view: WebView?, realm: String?, account: String?, args: String?) { + mWebViewClient.onReceivedLoginRequest(view, realm, account, args) + } + + override fun shouldOverrideKeyEvent(view: WebView?, event: KeyEvent?): Boolean { + return mWebViewClient.shouldOverrideKeyEvent(view, event) + } + + override fun onUnhandledKeyEvent(view: WebView?, event: KeyEvent?) { + mWebViewClient.onUnhandledKeyEvent(view, event) + } + + override fun onScaleChanged(view: WebView?, oldScale: Float, newScale: Float) { + mWebViewClient.onScaleChanged(view, oldScale, newScale) + } + + override fun onDetectedBlankScreen(p0: String?, p1: Int) { + mWebViewClient.onDetectedBlankScreen(p0, p1) + } +} diff --git a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/network/NetworkManager.java b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/network/NetworkManager.java index 171edd5be..19be8d636 100644 --- a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/network/NetworkManager.java +++ b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/network/NetworkManager.java @@ -73,7 +73,7 @@ public class NetworkManager { /** * dokit 更多页面接口请求 */ - public static final String DOKIT_MORE_PAGE_URL = "http://star.xiaojukeji.com/config/get.node?city=-1&areaid=&name=group"; + public static final String DOKIT_MORE_PAGE_URL = "https://star.xiaojukeji.com/config/get.node?city=-1&areaid=&name=group"; /** * 预发环境 */ diff --git a/README.md b/README.md index f06daba9d..500fab0f5 100644 --- a/README.md +++ b/README.md @@ -172,17 +172,10 @@ tips : 如果使用我们滴滴优秀的开源跨端方案 [chameleon](https:/ -## 微信交流群(一群满员,已开二群) -搜索**justdokit**加我微信好友,注意请添加备注:昵称-DoKit社区用户,否则你的申请将不会被验证通过。 -![51640263734_ pic](https://user-images.githubusercontent.com/4486497/147242854-9693daf9-033e-4523-89da-b7b36c72642c.jpg) - -
- - -## QQ 交流群 +## QQ 技术交流群

- QQ 交流群 + QQ 交流群

@@ -194,8 +187,6 @@ tips : 如果使用我们滴滴优秀的开源跨端方案 [chameleon](https:/


- -


diff --git a/Web/lerna-debug.log b/Web/lerna-debug.log index 44ae92802..483d67ae5 100644 --- a/Web/lerna-debug.log +++ b/Web/lerna-debug.log @@ -1,4 +1,16 @@ -55 error Error: Command failed with exit code 128: git push --follow-tags --no-verify --atomic origin master -55 error fatal: unable to access 'https://github.com/didi/DoraemonKit.git/': LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443 -55 error at makeError (/Users/didi/Desktop/DoKit/DoraemonKit/Web/node_modules/execa/lib/error.js:59:11) -55 error at handlePromise (/Users/didi/Desktop/DoKit/DoraemonKit/Web/node_modules/execa/index.js:114:26) +0 silly argv { _: [ 'bootstrap' ], lernaVersion: '4.0.0', '$0': 'lerna' } +1 notice cli v4.0.0 +2 verbose rootPath /Users/didi/Desktop/DoKit/DoraemonKit/Web +3 error JSONError: Unexpected token "<" (0x3C) in JSON at position 745 while parsing near "... \"dependencies\": {\n<<<<<<< HEAD\n<<<<<<<..." in packages/web/package.json +3 error +3 error   31 | }, +3 error   32 | "dependencies": { +3 error > 33 | <<<<<<< HEAD +3 error   | ^ +3 error   34 | <<<<<<< HEAD +3 error   35 | ======= +3 error   36 | >>>>>>> 4219bdfe (feat: 修改部分一机多控逻辑) +3 error +3 error at parseJson (/Users/didi/Desktop/DoKit/DoraemonKit/Web/node_modules/parse-json/index.js:29:21) +3 error at parse (/Users/didi/Desktop/DoKit/DoraemonKit/Web/node_modules/load-json-file/index.js:15:9) +3 error at module.exports (/Users/didi/Desktop/DoKit/DoraemonKit/Web/node_modules/load-json-file/index.js:18:47) diff --git a/Web/package.json b/Web/package.json index abf7a04a8..c096348da 100644 --- a/Web/package.json +++ b/Web/package.json @@ -26,6 +26,7 @@ "jest": "^26.6.3", "lerna": "^4.0.0", "less": "^4.1.1", + "livereload": "^0.9.3", "npm-run-all": "^4.1.5", "open": "^8.0.6", "postcss": "^8.2.12", @@ -39,11 +40,13 @@ "serve-handler": "^6.1.3" }, "dependencies": { - "vant": "^3.1.0-beta.0", - "vue": "^3.2.21", + "@dokit/web": "file:packages/web", "@dokit/web-core": "file:packages/core", + "@dokit/web-independent": "file:packages/web-independent", "@dokit/web-utils": "file:packages/utils", - "@dokit/web": "file:packages/web", - "@dokit/web-independent": "file:packages/web-independent" + "qrcodejs2": "0.0.2", + "qrcodejs2-fix": "0.0.1", + "vant": "^3.1.0-beta.0", + "vue": "^3.2.21" } } diff --git a/Web/packages/core/src/common/js/EventPlayback.js b/Web/packages/core/src/common/js/EventPlayback.js index 36592c869..c4d7e55d7 100644 --- a/Web/packages/core/src/common/js/EventPlayback.js +++ b/Web/packages/core/src/common/js/EventPlayback.js @@ -7,6 +7,7 @@ export default class EventPlayback { this.socketUrl = url this.state = getGlobalData(); this.init() + this.isAutoTest = false } init() { !this.state.mySocket && (this.state.mySocket = new mySocket(this.socketUrl)) @@ -23,97 +24,128 @@ export default class EventPlayback { } } else if (msg.type === "BROADCAST") { data = JSON.parse(msg.data) + + console.log(data) if (msg.contentType === 'action') { this.state.aid = data.eventId if (this.state.startPlayback) { - let node = document.querySelector(data.viewC12c.viewPath) - let event; - switch (data.viewC12c.actionType) { - // case "navigatorBack": - // window.history.back() - // break; - case "ON_CLICK": - node.click(); - break; - case "ON_TOUCH_START": - event = document.createEvent('MouseEvents'); - event.initMouseEvent('touchstart', true, true, window, 0, data.viewC12c.cloneEvent.targetTouches.screenX, data.viewC12c.cloneEvent.targetTouches.screenY, data.viewC12c.cloneEvent.targetTouches.clientX, data.viewC12c.cloneEvent.targetTouches.clientY, data.viewC12c.cloneEvent.ctrlKey, data.viewC12c.cloneEvent.altKey, data.viewC12c.cloneEvent.shiftKey, data.viewC12c.cloneEvent.metaKey); - event.changedTouches = [{ - clientX: data.viewC12c.cloneEvent.targetTouches.clientX, - clientY: data.viewC12c.cloneEvent.targetTouches.clientY, - force: data.viewC12c.cloneEvent.targetTouches.force, - identifier: data.viewC12c.cloneEvent.targetTouches.identifier, - pageX: data.viewC12c.cloneEvent.targetTouches.pageX, - pageY: data.viewC12c.cloneEvent.targetTouches.pageY, - radiusX: data.viewC12c.cloneEvent.targetTouches.radiusX, - radiusY: data.viewC12c.cloneEvent.targetTouches.radiusY, - rotationAngle: data.viewC12c.cloneEvent.targetTouches.rotationAngle, - screenX: data.viewC12c.cloneEvent.targetTouches.screenX, - screenY: data.viewC12c.cloneEvent.targetTouches.screenY - }] - event.touches = event.changedTouches - event.targetTouches = event.changedTouches - console.log('fyq', event) - node.dispatchEvent(event); - break; - case "ON_TOUCH_MOVE": - event = document.createEvent('MouseEvents'); - event.initMouseEvent('touchmove', true, true, window, 0, data.viewC12c.cloneEvent.targetTouches.screenX, data.viewC12c.cloneEvent.targetTouches.screenY, data.viewC12c.cloneEvent.targetTouches.clientX, data.viewC12c.cloneEvent.targetTouches.clientY, data.viewC12c.cloneEvent.ctrlKey, data.viewC12c.cloneEvent.altKey, data.viewC12c.cloneEvent.shiftKey, data.viewC12c.cloneEvent.metaKey); - event.changedTouches = [{ - clientX: data.viewC12c.cloneEvent.targetTouches.clientX, - clientY: data.viewC12c.cloneEvent.targetTouches.clientY, - force: data.viewC12c.cloneEvent.targetTouches.force, - identifier: data.viewC12c.cloneEvent.targetTouches.identifier, - pageX: data.viewC12c.cloneEvent.targetTouches.pageX, - pageY: data.viewC12c.cloneEvent.targetTouches.pageY, - radiusX: data.viewC12c.cloneEvent.targetTouches.radiusX, - radiusY: data.viewC12c.cloneEvent.targetTouches.radiusY, - rotationAngle: data.viewC12c.cloneEvent.targetTouches.rotationAngle, - screenX: data.viewC12c.cloneEvent.targetTouches.screenX, - screenY: data.viewC12c.cloneEvent.targetTouches.screenY - }] - event.touches = event.changedTouches - event.targetTouches = event.changedTouches - node.dispatchEvent(event); - break; - case "ON_TOUCH_END": - event = document.createEvent('MouseEvents'); - event.initMouseEvent('touchend', true, true, window, 0, data.viewC12c.cloneEvent.changedTouches.screenX, data.viewC12c.cloneEvent.changedTouches.screenY, data.viewC12c.cloneEvent.changedTouches.clientX, data.viewC12c.cloneEvent.changedTouches.clientY, data.viewC12c.cloneEvent.ctrlKey, data.viewC12c.cloneEvent.altKey, data.viewC12c.cloneEvent.shiftKey, data.viewC12c.cloneEvent.metaKey); - event.changedTouches = [{ - clientX: data.viewC12c.cloneEvent.targetTouches.clientX, - clientY: data.viewC12c.cloneEvent.targetTouches.clientY, - force: data.viewC12c.cloneEvent.targetTouches.force, - identifier: data.viewC12c.cloneEvent.targetTouches.identifier, - pageX: data.viewC12c.cloneEvent.targetTouches.pageX, - pageY: data.viewC12c.cloneEvent.targetTouches.pageY, - radiusX: data.viewC12c.cloneEvent.targetTouches.radiusX, - radiusY: data.viewC12c.cloneEvent.targetTouches.radiusY, - rotationAngle: data.viewC12c.cloneEvent.targetTouches.rotationAngle, - screenX: data.viewC12c.cloneEvent.targetTouches.screenX, - screenY: data.viewC12c.cloneEvent.targetTouches.screenY - }] - event.touches = event.changedTouches - event.targetTouches = event.changedTouches - node.dispatchEvent(event); - break; - case "ON_INPUT_CHANGE": - event = document.createEvent('Events'); - event.initEvent('input', true, true); - node.value = data.viewC12c.inputValue; - node.dispatchEvent(event); - break; - case "ON_SCROLL": - node.scrollTop = data.viewC12c.scrollX; - node.scrollLeft = data.viewC12c.scrollY; - break; - default: - break; + const nodeOps = () => { + let node = document.querySelector(data.viewC12c.viewPath) + let event; + switch (data.viewC12c.actionType) { + // case "navigatorBack": + // window.history.back() + // break; + case "ON_CLICK": + node.click(); + break; + case "ON_TOUCH_START": + event = document.createEvent('MouseEvents'); + event.initMouseEvent('touchstart', true, true, window, 0, data.viewC12c.cloneEvent.targetTouches.screenX, data.viewC12c.cloneEvent.targetTouches.screenY, data.viewC12c.cloneEvent.targetTouches.clientX, data.viewC12c.cloneEvent.targetTouches.clientY, data.viewC12c.cloneEvent.ctrlKey, data.viewC12c.cloneEvent.altKey, data.viewC12c.cloneEvent.shiftKey, data.viewC12c.cloneEvent.metaKey); + event.changedTouches = [{ + clientX: data.viewC12c.cloneEvent.targetTouches.clientX, + clientY: data.viewC12c.cloneEvent.targetTouches.clientY, + force: data.viewC12c.cloneEvent.targetTouches.force, + identifier: data.viewC12c.cloneEvent.targetTouches.identifier, + pageX: data.viewC12c.cloneEvent.targetTouches.pageX, + pageY: data.viewC12c.cloneEvent.targetTouches.pageY, + radiusX: data.viewC12c.cloneEvent.targetTouches.radiusX, + radiusY: data.viewC12c.cloneEvent.targetTouches.radiusY, + rotationAngle: data.viewC12c.cloneEvent.targetTouches.rotationAngle, + screenX: data.viewC12c.cloneEvent.targetTouches.screenX, + screenY: data.viewC12c.cloneEvent.targetTouches.screenY + }] + event.touches = event.changedTouches + event.targetTouches = event.changedTouches + console.log('fyq', event) + node.dispatchEvent(event); + break; + case "ON_TOUCH_MOVE": + event = document.createEvent('MouseEvents'); + event.initMouseEvent('touchmove', true, true, window, 0, data.viewC12c.cloneEvent.targetTouches.screenX, data.viewC12c.cloneEvent.targetTouches.screenY, data.viewC12c.cloneEvent.targetTouches.clientX, data.viewC12c.cloneEvent.targetTouches.clientY, data.viewC12c.cloneEvent.ctrlKey, data.viewC12c.cloneEvent.altKey, data.viewC12c.cloneEvent.shiftKey, data.viewC12c.cloneEvent.metaKey); + event.changedTouches = [{ + clientX: data.viewC12c.cloneEvent.targetTouches.clientX, + clientY: data.viewC12c.cloneEvent.targetTouches.clientY, + force: data.viewC12c.cloneEvent.targetTouches.force, + identifier: data.viewC12c.cloneEvent.targetTouches.identifier, + pageX: data.viewC12c.cloneEvent.targetTouches.pageX, + pageY: data.viewC12c.cloneEvent.targetTouches.pageY, + radiusX: data.viewC12c.cloneEvent.targetTouches.radiusX, + radiusY: data.viewC12c.cloneEvent.targetTouches.radiusY, + rotationAngle: data.viewC12c.cloneEvent.targetTouches.rotationAngle, + screenX: data.viewC12c.cloneEvent.targetTouches.screenX, + screenY: data.viewC12c.cloneEvent.targetTouches.screenY + }] + event.touches = event.changedTouches + event.targetTouches = event.changedTouches + node.dispatchEvent(event); + break; + case "ON_TOUCH_END": + event = document.createEvent('MouseEvents'); + event.initMouseEvent('touchend', true, true, window, 0, data.viewC12c.cloneEvent.changedTouches.screenX, data.viewC12c.cloneEvent.changedTouches.screenY, data.viewC12c.cloneEvent.changedTouches.clientX, data.viewC12c.cloneEvent.changedTouches.clientY, data.viewC12c.cloneEvent.ctrlKey, data.viewC12c.cloneEvent.altKey, data.viewC12c.cloneEvent.shiftKey, data.viewC12c.cloneEvent.metaKey); + event.changedTouches = [{ + clientX: data.viewC12c.cloneEvent.targetTouches.clientX, + clientY: data.viewC12c.cloneEvent.targetTouches.clientY, + force: data.viewC12c.cloneEvent.targetTouches.force, + identifier: data.viewC12c.cloneEvent.targetTouches.identifier, + pageX: data.viewC12c.cloneEvent.targetTouches.pageX, + pageY: data.viewC12c.cloneEvent.targetTouches.pageY, + radiusX: data.viewC12c.cloneEvent.targetTouches.radiusX, + radiusY: data.viewC12c.cloneEvent.targetTouches.radiusY, + rotationAngle: data.viewC12c.cloneEvent.targetTouches.rotationAngle, + screenX: data.viewC12c.cloneEvent.targetTouches.screenX, + screenY: data.viewC12c.cloneEvent.targetTouches.screenY + }] + event.touches = event.changedTouches + event.targetTouches = event.changedTouches + node.dispatchEvent(event); + break; + case "ON_INPUT_CHANGE": + event = document.createEvent('Events'); + event.initEvent('input', true, true); + node.value = data.viewC12c.inputValue; + node.dispatchEvent(event); + break; + case "ON_SCROLL": + node.scrollTop = data.viewC12c.scrollX; + node.scrollLeft = data.viewC12c.scrollY; + break; + default: + break; + } + } + if (this.isAutoTest) { + setTimeout(() => { + nodeOps() + this.state.mySocket.send({ + type: 'AUTOTEST', + contentType:'action_response', + channelSerial: this.state.channelSerial, + data: JSON.stringify({ command: 'action_response',message: 'success', params: {eventId: data.eventId}}) + }) + }, data.diffTime); + } else { + nodeOps() } } } else if (msg.contentType === 'mc_host') { this.state.isHost = false; this.state.startPlayback = true } + } else if (msg.type === "AUTOTEST") { + console.log('message', msg) + data = JSON.parse(msg.data) + if (msg.contentType === 'auto_test_control') { + if (data.command === 'startAutoTest' || data.command === 'stopAutoTest') { + this.isAutoTest = data.command === 'startAutoTest' ? true : false + this.state.mySocket.send({ + type: 'AUTOTEST', + contentType:'control_response', + channelSerial: this.state.channelSerial, + data: JSON.stringify({...data, command: 'control_response',message: 'success', params: {command:data.command}}) + }) + } + } } } catch (error) { console.error(error); diff --git a/Web/packages/core/src/components/home.vue b/Web/packages/core/src/components/home.vue index 9d440403d..b3b52b120 100644 --- a/Web/packages/core/src/components/home.vue +++ b/Web/packages/core/src/components/home.vue @@ -23,7 +23,7 @@ export default { }, data(){ return { - version: '0.0.3-alpha.1' + version: '0.0.3-alpha.3' } }, mounted(){ diff --git a/Web/packages/core/src/components/router-container.vue b/Web/packages/core/src/components/router-container.vue index 166fa232c..ae605382a 100644 --- a/Web/packages/core/src/components/router-container.vue +++ b/Web/packages/core/src/components/router-container.vue @@ -20,6 +20,7 @@ export default { }, computed:{ component(){ + return this.$route.component }, title(){ diff --git a/Web/packages/web-independent/src/index.js b/Web/packages/web-independent/src/index.js new file mode 100644 index 000000000..7202c22dc --- /dev/null +++ b/Web/packages/web-independent/src/index.js @@ -0,0 +1,10 @@ +import {Dokit} from '@dokit/web-core-independent' +import {Features} from '../../web/src/feature' +/** + * 0.0.3 alpha 3 +* TODO 全局注册 Dokit +*/ +window.Dokit = new Dokit({ + features: Features, +}); + diff --git a/Web/packages/web/package-lock.json b/Web/packages/web/package-lock.json new file mode 100644 index 000000000..fa8fe7e27 --- /dev/null +++ b/Web/packages/web/package-lock.json @@ -0,0 +1,31 @@ +{ + "name": "@dokit/web", + "version": "0.0.3-alpha.3", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@dokit/web-core": { + "version": "0.0.1", + "resolved": "http://registry.npm.xiaojukeji.com/@dokit/web-core/download/@dokit/web-core-0.0.1.tgz", + "integrity": "sha1-j7nbrKT4mgZHgLnozQs4Au5hH0o=", + "requires": { + "@dokit/web-utils": "^0.0.1" + } + }, + "@dokit/web-utils": { + "version": "0.0.1", + "resolved": "http://registry.npm.xiaojukeji.com/@dokit/web-utils/download/@dokit/web-utils-0.0.1.tgz", + "integrity": "sha1-wr/rh8Ki7vtjMbEdIqyhWUw6xLA=" + }, + "mutation-observer": { + "version": "1.0.3", + "resolved": "http://registry.npm.xiaojukeji.com/mutation-observer/download/mutation-observer-1.0.3.tgz", + "integrity": "sha1-QukiKxAbyoLlup1aes9KFMDyY9A=" + }, + "web-vitals": { + "version": "2.1.2", + "resolved": "http://registry.npm.xiaojukeji.com/web-vitals/download/web-vitals-2.1.2.tgz", + "integrity": "sha1-OmyPrr+Ql6bM0X9fRclIXY1i2rE=" + } + } +} diff --git a/Web/packages/web/playground/index.html b/Web/packages/web/playground/index.html new file mode 100644 index 000000000..7224efebe --- /dev/null +++ b/Web/packages/web/playground/index.html @@ -0,0 +1,213 @@ + + + + + + + + Dokit For Web + + + + + + + + + +
DoKit For Web
+
+
+
+
+ Playground +
+
+
+
+
+ Hummer + +

Playground

+ +

Playground

+

Playground

+

Playground

+

Playground

+

Playground

+
+

接口数据:

+

Playground

+

Playground

+

Playground

+
zepto测试
+ + + + + \ No newline at end of file diff --git a/Web/packages/web/rollup.config.js b/Web/packages/web/rollup.config.js index 445e357b5..1c555bf1d 100644 --- a/Web/packages/web/rollup.config.js +++ b/Web/packages/web/rollup.config.js @@ -3,6 +3,7 @@ import postcssPlugin from 'rollup-plugin-postcss' import resolve from 'rollup-plugin-node-resolve' import commonjs from 'rollup-plugin-commonjs' import replace from 'rollup-plugin-replace' + import { terser } from 'rollup-plugin-terser' diff --git a/Web/packages/web/src/plugins/demo-single-plugin/FPS.vue b/Web/packages/web/src/plugins/demo-single-plugin/FPS.vue new file mode 100644 index 000000000..9bba93f5d --- /dev/null +++ b/Web/packages/web/src/plugins/demo-single-plugin/FPS.vue @@ -0,0 +1,313 @@ + + + diff --git a/Web/packages/web/src/plugins/demo-single-plugin/index.js b/Web/packages/web/src/plugins/demo-single-plugin/index.js index 45a2d8e95..dd63ce44d 100644 --- a/Web/packages/web/src/plugins/demo-single-plugin/index.js +++ b/Web/packages/web/src/plugins/demo-single-plugin/index.js @@ -1,10 +1,9 @@ -import IndependPluginDemo from './IndependPluginDemo.vue' -import {IndependPlugin} from '@dokit/web-core' +import FPS from "./FPS.vue"; +import { IndependPlugin } from "@dokit/web-core"; export default new IndependPlugin({ - nameZh: '独立插件', - name: 'test', - icon: 'https://pt-starimg.didistatic.com/static/starimg/img/z1346TQD531618997547642.png', - component: IndependPluginDemo -}) - + nameZh: "帧率显示", + name: "test", + icon: "https://pt-starimg.didistatic.com/static/starimg/img/z1346TQD531618997547642.png", + component: FPS, +}); diff --git a/Web/packages/web/src/plugins/one-machine-with-multiple-controls/app.vue b/Web/packages/web/src/plugins/one-machine-with-multiple-controls/app.vue index 8112cf80c..4c653f180 100644 --- a/Web/packages/web/src/plugins/one-machine-with-multiple-controls/app.vue +++ b/Web/packages/web/src/plugins/one-machine-with-multiple-controls/app.vue @@ -81,7 +81,7 @@ export default { watch: { socketHistoryList: { handler: function (newVal, oldVal) { - this.historyList = [...newVal]; + this.historyList = newVal && [...newVal] || []; }, deep: true, immediate: true, diff --git a/Web/playground/independent.html b/Web/playground/independent.html index 6d378a4fe..7dd29f58c 100644 --- a/Web/playground/independent.html +++ b/Web/playground/independent.html @@ -175,5 +175,5 @@ // })); // }, 5000); - + \ No newline at end of file diff --git a/Web/playground/index.html b/Web/playground/index.html index 895cf1271..160b720ba 100644 --- a/Web/playground/index.html +++ b/Web/playground/index.html @@ -5,7 +5,7 @@ - Dokit For Web + Dokit For Web11111111