提交 34b44cf6 编写于 作者: J jackjintai

android: plugin parse AndroidManifest.xml

上级 c6b36d49
......@@ -64,16 +64,16 @@ android {
//dokit 扩展
dokitExt {
dokitPluginSwitch = true
slowMethodSwitch = true
bigImgSwitch = true
//单位为ms 1000ms = 1s
thresholdTime = 200
packageNames = ["com.didichuxing.doraemondemo"]
//慢函数 黑名单 可以是包名 也可以是全路径的类名
methodBlacklist = ["com.didichuxing.doraemondemo.dokit"]
}
//dokitExt {
// dokitPluginSwitch = true
// slowMethodSwitch = true
// bigImgSwitch = true
// //单位为ms 1000ms = 1s
// thresholdTime = 200
// packageNames = ["com.didichuxing.doraemondemo"]
// //慢函数 黑名单 可以是包名 也可以是全路径的类名
// methodBlacklist = ["com.didichuxing.doraemondemo.dokit"]
//}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
......
......@@ -31,7 +31,7 @@ public class AopApp extends Application {
kits.add(new DemoKit());
//测试环境:a49842eeebeb1989b3f9565eb12c276b
//线上环境:749a0600b5e48dd77cf8ee680be7b1b7
new AopTest().test();
//new AopTest().test();
ImagePipelineConfig config = ImagePipelineConfig.newBuilder(this)
.setDiskCacheEnabled(false)
.build();
......@@ -39,13 +39,12 @@ public class AopApp extends Application {
//是否显示入口icon
// DoraemonKit.setAwaysShowMainIcon(false);
DoraemonKit.disableUpload();
DoraemonKit.install(this, kits, "749a0600b5e48dd77cf8ee680be7b1b7");
DoraemonKit.disableUpload();
//DoraemonKit.install(this, kits, "70e78c27f9174d68668d8a66a2b66483")
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
......
......@@ -2,8 +2,12 @@ package com.didichuxing.doraemondemo;
import android.util.Log;
import com.didichuxing.doraemonkit.aop.DokitPluginConfig;
import com.didichuxing.doraemonkit.aop.method_stack.MethodStackUtil;
import java.util.HashMap;
import java.util.Map;
/**
* ================================================
* 作 者:jint(金台)
......@@ -23,14 +27,8 @@ public class AopTest {
// }
public void test() {
//long beginTime = System.currentTimeMillis();
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
//long costTime = System.currentTimeMillis() - beginTime;
public void AopTest() {
MethodStackUtil.getInstance().recodeObjectMethodCostStart(500, 0, "AopTest", "AopTest", "desc", this);
}
......
......@@ -13,7 +13,7 @@ buildscript {
classpath 'com.android.tools.build:gradle:3.6.3'
classpath 'com.novoda:bintray-release:0.9.2'
classpath "com.didichuxing.doraemonkit:doraemonkit-plugin:${rootProject.ext.android["pluginVersionName"]}"
// classpath "com.didichuxing.doraemonkit:doraemonkit-plugin:3.1.3"
// classpath "com.didichuxing.doraemonkit:doraemonkit-plugin:3.1.3"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${rootProject.ext.android["kotlin_version"]}"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
......
......@@ -2,10 +2,10 @@ apply plugin: 'groovy'
apply from: 'upload.gradle'
dependencies {
implementation gradleApi()
implementation localGroovy()
compile gradleApi()
compile localGroovy()
//版本不能太高 否则会跟项目的as版本冲突
compileOnly 'com.android.tools.build:gradle:3.0.0'
compile 'com.android.tools.build:gradle:3.0.0'
implementation 'com.didiglobal.booster:booster-android-gradle-api:1.6.0'
implementation 'commons-io:commons-io:2.6'
implementation 'commons-codec:commons-codec:1.11'
......
......@@ -15,14 +15,11 @@ import com.didiglobal.booster.gradle.VariantScopeKt;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.xml.sax.SAXException;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
......@@ -52,26 +49,23 @@ public final class DoKitPlugin implements Plugin<Project> {
}
}
//解析并获取Application 类
//解析注册表文件
appExtension.getApplicationVariants().all(applicationVariant -> {
if (applicationVariant.getName().contains("debug")) {
VariantScopeKt.getMergedManifests(BaseVariantKt.getScope(applicationVariant))
.forEach(file -> {
String manifestPath = file.getPath() + "/AndroidManifest.xml";
File manifest = new File(manifestPath);
if (manifest.exists()) {
try {
try {
String manifestPath = file.getPath() + "/AndroidManifest.xml";
System.out.println("Dokit==manifestPath=>" + manifestPath);
File manifest = new File(manifestPath);
if (manifest.exists()) {
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
CommHandler handler = new CommHandler();
parser.parse(manifest, handler);
DokitExtUtil.getInstance().setApplications(handler.getApplication());
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
});
}
......
......@@ -20,50 +20,21 @@ public class DokitExtUtil {
* dokit 插件开关 字段权限必须为public 否则无法进行赋值
*/
private boolean mDokitPluginSwitch = true;
/**
* 慢函数开关
*/
private boolean mSlowMethodSwitch = true;
/**
* 大图检测开关
*/
private boolean mBigImgSwitch = true;
/**
* 单位为ms 默认500ms
*/
private int mThresholdTime = 500;
private List<String> mPackageNames = new ArrayList<>();
/**
* 黑名单
*/
private List<String> mMethodBlacklist = new ArrayList<>();
private List<String> applications = new ArrayList<>();
private DokitExtension.CommConfig commConfig = new DokitExtension.CommConfig();
private DokitExtension.SlowMethodConfig slowMethodConfig = new DokitExtension.SlowMethodConfig();
public boolean isDokitPluginSwitch() {
public boolean dokitPluginSwitchOpen() {
return mDokitPluginSwitch;
}
public boolean isSlowMethodSwitch() {
return mSlowMethodSwitch;
}
public boolean isBigImgSwitch() {
return mBigImgSwitch;
}
public int getThresholdTime() {
return mThresholdTime;
}
public List<String> getPackageNames() {
return mPackageNames;
public DokitExtension.CommConfig getCommConfig() {
return commConfig;
}
public List<String> getMethodBlacklist() {
return mMethodBlacklist;
public DokitExtension.SlowMethodConfig getSlowMethodConfig() {
return slowMethodConfig;
}
/**
......@@ -86,30 +57,59 @@ public class DokitExtUtil {
public void init(DokitExtension dokitExtension, AppExtension appExtension) {
if (dokitExtension != null) {
this.mDokitPluginSwitch = dokitExtension.dokitPluginSwitch;
this.mSlowMethodSwitch = dokitExtension.slowMethodSwitch;
this.mThresholdTime = dokitExtension.thresholdTime;
this.mBigImgSwitch = dokitExtension.bigImgSwitch;
mPackageNames.clear();
for (String packageName : dokitExtension.packageNames) {
mPackageNames.add(packageName.replaceAll("\\.", "/"));
//设置普通的配置
this.commConfig = dokitExtension.comm;
this.slowMethodConfig.strategy = dokitExtension.slowMethod.strategy;
this.slowMethodConfig.methodSwitch = dokitExtension.slowMethod.methodSwitch;
/**
* ============慢函数普通策略的配置==========
*/
this.slowMethodConfig.normalMethodConfig.thresholdTime = dokitExtension.slowMethod.normalMethodConfig.thresholdTime;
//设置慢函数普通策略插装包名
this.slowMethodConfig.normalMethodConfig.packageNames.clear();
for (String packageName : dokitExtension.slowMethod.normalMethodConfig.packageNames) {
this.slowMethodConfig.normalMethodConfig.packageNames.add(packageName.replaceAll("\\.", "/"));
}
mMethodBlacklist.clear();
for (String blackStr : dokitExtension.methodBlacklist) {
mMethodBlacklist.add(blackStr.replaceAll("\\.", "/"));
}
//添加默认的包名
String applicationId = appExtension.getDefaultConfig().getApplicationId().replaceAll("\\.", "/");
if (mPackageNames.isEmpty()) {
mPackageNames.add(applicationId);
if (this.slowMethodConfig.normalMethodConfig.packageNames.isEmpty()) {
this.slowMethodConfig.normalMethodConfig.packageNames.add(applicationId);
}
}
//设置慢函数普通策略插装包名黑名单
this.slowMethodConfig.normalMethodConfig.methodBlacklist.clear();
for (String blackStr : dokitExtension.slowMethod.normalMethodConfig.methodBlacklist) {
this.slowMethodConfig.normalMethodConfig.methodBlacklist.add(blackStr.replaceAll("\\.", "/"));
}
/**
* ============慢函数普通策略的配置==========
*/
/**
* ============慢函数stack策略的配置==========
*/
this.slowMethodConfig.stackMethodConfig.thresholdTime = dokitExtension.slowMethod.stackMethodConfig.thresholdTime;
this.slowMethodConfig.stackMethodConfig.enterMethods.clear();
for (String methodName : dokitExtension.slowMethod.stackMethodConfig.enterMethods) {
this.slowMethodConfig.stackMethodConfig.enterMethods.add(methodName.replaceAll("\\.", "/"));
}
//添加默认的入口函数
if (this.slowMethodConfig.normalMethodConfig.packageNames.isEmpty()) {
for (String application : applications) {
String attachBaseContextMethodName = application + "/attachBaseContext";
String onCreateMethodName = application + "/onCreate";
this.slowMethodConfig.stackMethodConfig.enterMethods.add(attachBaseContextMethodName);
this.slowMethodConfig.stackMethodConfig.enterMethods.add(onCreateMethodName);
}
}
/**
* ============慢函数stack策略的配置==========
*/
}
}
public void setApplications(List<String> applications) {
void setApplications(List<String> applications) {
if (applications.isEmpty()) {
return;
......@@ -121,9 +121,6 @@ public class DokitExtUtil {
}
public List<String> getApplications() {
return this.applications;
}
public boolean ignorePackageNames(String className) {
boolean isMatched = false;
......
......@@ -16,41 +16,65 @@ public class DokitExtension {
* dokit 插件开关 字段权限必须为public 否则无法进行赋值
*/
public boolean dokitPluginSwitch = true;
/**
* 慢函数开关
*/
public boolean slowMethodSwitch = true;
/**
* 大图检测开关
*/
public boolean bigImgSwitch = true;
/**
* 单位为ms 默认500ms
*/
public int thresholdTime = 500;
public CommConfig comm = new CommConfig();
public SlowMethodConfig slowMethod = new SlowMethodConfig();
/**
* 插桩代码包名
* 通用配置
*/
public List<String> packageNames = new ArrayList<>();
public static class CommConfig {
/**
* 地图经纬度开关
*/
public boolean mapSwitch = true;
/**
* 网络开关
*/
public boolean networkSwitch = true;
/**
* 大图开关
*/
public boolean bigImgSwitch = true;
}
/**
* 慢函数黑名单
* 慢函数配置
*/
public List<String> methodBlacklist = new ArrayList<>();
@Override
public String toString() {
return "DokitExtension{" +
"runVariant=" + runVariant +
", duplcatedClassSafeMode=" + duplcatedClassSafeMode +
", dokitPluginSwitch=" + dokitPluginSwitch +
", slowMethodSwitch=" + slowMethodSwitch +
", bigImgSwitch=" + bigImgSwitch +
", thresholdTime=" + thresholdTime +
", packageNames=" + packageNames +
", blacklist=" + methodBlacklist +
'}';
public static class SlowMethodConfig {
public static final int STRATEGY_STACK = 0;
public static final int STRATEGY_NORMAL = 1;
/**
* 0:打印函数调用栈 1:普通模式 运行时打印某个函数的耗时 全局业务代码函数插入
*/
public int strategy = STRATEGY_STACK;
/**
* 函数功能开关
*/
public boolean methodSwitch = true;
public StackMethodConfig stackMethodConfig = new StackMethodConfig();
public NormalMethodConfig normalMethodConfig = new NormalMethodConfig();
public static class StackMethodConfig {
/**
* 默认值为5ms
*/
public int thresholdTime = 5;
public List<String> enterMethods = new ArrayList<>();
}
public static class NormalMethodConfig {
/**
* 默认值为500ms
*/
public int thresholdTime = 500;
public List<String> packageNames = new ArrayList<>();
public List<String> methodBlacklist = new ArrayList<>();
}
}
}
......@@ -3,7 +3,6 @@ package com.didichuxing.doraemonkit.plugin.bytecode;
import com.didichuxing.doraemonkit.plugin.DokitExtUtil;
import com.didichuxing.doraemonkit.plugin.bytecode.method.bigimg.FrescoMethodAdapter;
import com.didichuxing.doraemonkit.plugin.bytecode.method.bigimg.GlideMethodAdapter;
import com.didichuxing.doraemonkit.plugin.bytecode.method.bigimg.GlideTransformMethodAdapter;
import com.didichuxing.doraemonkit.plugin.bytecode.method.bigimg.ImageLoaderMethodAdapter;
import com.didichuxing.doraemonkit.plugin.bytecode.method.bigimg.PicassoMethodAdapter;
......@@ -62,10 +61,8 @@ public final class DokitBigImageClassAdapter extends ClassVisitor {
//从传进来的ClassWriter中读取MethodVisitor
MethodVisitor mv = cv.visitMethod(access, methodName, desc, signature, exceptions);
//开关被关闭 不插入代码
if (!DokitExtUtil.getInstance().isDokitPluginSwitch()) {
return mv;
}
if (!DokitExtUtil.getInstance().isBigImgSwitch()) {
if (!DokitExtUtil.getInstance().getCommConfig().bigImgSwitch) {
return mv;
}
......
......@@ -3,7 +3,7 @@ package com.didichuxing.doraemonkit.plugin.bytecode;
import com.didichuxing.doraemonkit.plugin.DokitExtUtil;
import com.didichuxing.doraemonkit.plugin.bytecode.method.comm.AmapLocationMethodAdapter;
import com.didichuxing.doraemonkit.plugin.bytecode.method.comm.BaiduLocationMethodAdapter;
import com.didichuxing.doraemonkit.plugin.bytecode.method.comm.FlagMethodAdapter;
import com.didichuxing.doraemonkit.plugin.bytecode.method.comm.PluginConfigMethodAdapter;
import com.didichuxing.doraemonkit.plugin.bytecode.method.comm.OkHttpNullConsMethodAdapter;
import com.didichuxing.doraemonkit.plugin.bytecode.method.comm.OkHttpOneParamConsMethodAdapter;
import com.didichuxing.doraemonkit.plugin.bytecode.method.comm.PlatformNullConsHttpMethodAdapter;
......@@ -67,90 +67,85 @@ public final class DokitCommClassAdapter extends ClassVisitor {
public MethodVisitor visitMethod(int access, String methodName, String desc, String signature, String[] exceptions) {
//从传进来的ClassWriter中读取MethodVisitor
MethodVisitor mv = cv.visitMethod(access, methodName, desc, signature, exceptions);
//开关被关闭 不插入代码
if (!DokitExtUtil.getInstance().isDokitPluginSwitch()) {
return mv;
}
//开发者变量字节码替换
if (className.equals("com/didichuxing/doraemonkit/DoraemonKitReal") && methodName.equals("install") && desc != null) {
if (getParamsSize(desc) == 3) {
log(className, access, methodName, desc, signature);
//创建MethodVisitor代理
return mv == null ? null : new FlagMethodAdapter(access, desc, mv);
}
}
//高德地图字节码替换
if (className.equals("com/amap/api/location/AMapLocationClient") && methodName.equals("setLocationListener")) {
//创建MethodVisitor代理
log(className, access, methodName, desc, signature);
return mv == null ? null : new AmapLocationMethodAdapter(access, desc, mv);
}
//腾讯地图字节码替换
if (className.equals("com/tencent/map/geolocation/TencentLocationManager") && methodName.equals("requestLocationUpdates")) {
//开发者变量字节码替换
if (className.equals("com/didichuxing/doraemonkit/DoraemonKitReal") && methodName.equals("pluginConfig")) {
log(className, access, methodName, desc, signature);
//创建MethodVisitor代理
return mv == null ? null : new TencentLocationMethodAdapter(access, desc, mv);
return mv == null ? null : new PluginConfigMethodAdapter(access, desc, mv, methodName);
}
//腾讯地图单次定位
if (className.equals("com/tencent/map/geolocation/TencentLocationManager") && methodName.equals("requestSingleFreshLocation")) {
log(className, access, methodName, desc, signature);
//创建MethodVisitor代理
return mv == null ? null : new TencentLocationSingleMethodAdapter(access, desc, mv);
}
//百度地图定位 汇报函数签名错误 暂时未找到原因
//地图配置
if (DokitExtUtil.getInstance().getCommConfig().mapSwitch) {
//高德地图字节码替换
if (className.equals("com/amap/api/location/AMapLocationClient") && methodName.equals("setLocationListener")) {
//创建MethodVisitor代理
log(className, access, methodName, desc, signature);
return mv == null ? null : new AmapLocationMethodAdapter(access, desc, mv);
}
//腾讯地图字节码替换
if (className.equals("com/tencent/map/geolocation/TencentLocationManager") && methodName.equals("requestLocationUpdates")) {
log(className, access, methodName, desc, signature);
//创建MethodVisitor代理
return mv == null ? null : new TencentLocationMethodAdapter(access, desc, mv);
}
//腾讯地图单次定位
if (className.equals("com/tencent/map/geolocation/TencentLocationManager") && methodName.equals("requestSingleFreshLocation")) {
log(className, access, methodName, desc, signature);
//创建MethodVisitor代理
return mv == null ? null : new TencentLocationSingleMethodAdapter(access, desc, mv);
}
//百度地图定位 汇报函数签名错误 暂时未找到原因
// if (className.equals("com/baidu/location/LocationClient") && name.equals("registerLocationListener")) {
// log(className, access, name, desc, signature);
// //创建MethodVisitor代理
// return mv == null ? null : new BaiduLocationMethodAdapter(access, desc, mv);
// }
//百度地图定位
if (methodName.equals("onReceiveLocation") && desc.equals("(Lcom/baidu/location/BDLocation;)V")) {
log(className, access, methodName, desc, signature);
//创建MethodVisitor代理
return mv == null ? null : new BaiduLocationMethodAdapter(access, desc, mv);
//百度地图定位
if (methodName.equals("onReceiveLocation") && desc.equals("(Lcom/baidu/location/BDLocation;)V")) {
log(className, access, methodName, desc, signature);
//创建MethodVisitor代理
return mv == null ? null : new BaiduLocationMethodAdapter(access, desc, mv);
}
}
//网络配置
if (DokitExtUtil.getInstance().getCommConfig().networkSwitch) {
//okhttp 拦截器字节码替换 空构造函数
if (className.equals("okhttp3/OkHttpClient$Builder") && methodName.equals("<init>") && getParamsSize(desc) == 0) {
//创建MethodVisitor代理
log(className, access, methodName, desc, signature);
return mv == null ? null : new OkHttpNullConsMethodAdapter(access, desc, mv);
}
//okhttp 拦截器字节码替换 空构造函数
if (className.equals("okhttp3/OkHttpClient$Builder") && methodName.equals("<init>") && getParamsSize(desc) == 0) {
//创建MethodVisitor代理
log(className, access, methodName, desc, signature);
return mv == null ? null : new OkHttpNullConsMethodAdapter(access, desc, mv);
}
//okhttp 拦截器字节码替换 一个参数的构造函数
if (className.equals("okhttp3/OkHttpClient$Builder") && methodName.equals("<init>") && getParamsSize(desc) == 1) {
//创建MethodVisitor代理
log(className, access, methodName, desc, signature);
return mv == null ? null : new OkHttpOneParamConsMethodAdapter(mv, access, methodName, desc);
}
//okhttp 拦截器字节码替换 一个参数的构造函数
if (className.equals("okhttp3/OkHttpClient$Builder") && methodName.equals("<init>") && getParamsSize(desc) == 1) {
//创建MethodVisitor代理
log(className, access, methodName, desc, signature);
return mv == null ? null : new OkHttpOneParamConsMethodAdapter(mv, access, methodName, desc);
}
//didi平台端 网络 空构造函数
if (className.equals("didihttp/DidiHttpClient$Builder") && methodName.equals("<init>") && getParamsSize(desc) == 0) {
//创建MethodVisitor代理
log(className, access, methodName, desc, signature);
return mv == null ? null : new PlatformNullConsHttpMethodAdapter(access, desc, mv);
}
//didi平台端 网络 空构造函数
if (className.equals("didihttp/DidiHttpClient$Builder") && methodName.equals("<init>") && getParamsSize(desc) == 0) {
//创建MethodVisitor代理
log(className, access, methodName, desc, signature);
return mv == null ? null : new PlatformNullConsHttpMethodAdapter(access, desc, mv);
}
//didi平台端 网络 一个参数的构造函数
if (className.equals("didihttp/DidiHttpClient$Builder") && methodName.equals("<init>") && getParamsSize(desc) == 1) {
//创建MethodVisitor代理
log(className, access, methodName, desc, signature);
return mv == null ? null : new PlatformOneParamHttpMethodAdapter(mv, access, methodName, desc);
//didi平台端 网络 一个参数的构造函数
if (className.equals("didihttp/DidiHttpClient$Builder") && methodName.equals("<init>") && getParamsSize(desc) == 1) {
//创建MethodVisitor代理
log(className, access, methodName, desc, signature);
return mv == null ? null : new PlatformOneParamHttpMethodAdapter(mv, access, methodName, desc);
}
}
//app启动hook点 onCreate()函数 兼容MultiDex
// if (!StringUtils.isEmpty(superName) && (superName.equals("android/app/Application") || superName.equals("android/support/multidex/MultiDexApplication")) && methodName.equals("onCreate") && desc.equals("()V")) {
// log(className, access, methodName, desc, signature);
// return mv == null ? null : new ApplicationOnCreateMethodAdapter(access, methodName, desc, mv);
// }
//过滤所有类中当前方法中所有的字节码
return mv;
}
......
......@@ -11,7 +11,6 @@ import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import java.text.MessageFormat;
import java.util.List;
/**
......@@ -77,10 +76,6 @@ public final class DokitMethodStackClassAdapter extends ClassVisitor {
public MethodVisitor visitMethod(int access, String methodName, String desc, String signature, String[] exceptions) {
//从传进来的ClassWriter中读取MethodVisitor
MethodVisitor mv = cv.visitMethod(access, methodName, desc, signature, exceptions);
//开关被关闭 不插入代码
if (!DokitExtUtil.getInstance().isDokitPluginSwitch()) {
return mv;
}
if (DokitExtUtil.getInstance().ignorePackageNames(className)) {
return mv;
......@@ -92,14 +87,14 @@ public final class DokitMethodStackClassAdapter extends ClassVisitor {
switch (level) {
case MethodStackNodeUtil.LEVEL_0:
//匹配Application
List<String> applications = DokitExtUtil.getInstance().getApplications();
if (applications == null || applications.isEmpty()) {
List<String> enterMethods = DokitExtUtil.getInstance().getSlowMethodConfig().stackMethodConfig.enterMethods;
if (enterMethods == null || enterMethods.isEmpty()) {
//app启动hook点 onCreate()函数 兼容MultiDex
if (!StringUtils.isEmpty(superName) &&
(superName.equals("android/app/Application") || superName.equals("android/support/multidex/MultiDexApplication") || superName.equals("androidx/multidex/MultiDexApplication")) &&
methodName.equals("onCreate") && desc.equals("()V")) {
//log(className, access, methodName, desc, signature);
return mv == null ? null : new MethodStackMethodAdapter(mv, className, access, methodName, desc, level);
return mv == null ? null : new MethodStackMethodAdapter(mv, className, DokitExtUtil.getInstance().getSlowMethodConfig().stackMethodConfig.thresholdTime, access, methodName, desc, level);
}
//app启动hook点 attachBaseContext()函数 兼容MultiDex
......@@ -107,16 +102,13 @@ public final class DokitMethodStackClassAdapter extends ClassVisitor {
(superName.equals("android/app/Application") || superName.equals("android/support/multidex/MultiDexApplication") || superName.equals("androidx/multidex/MultiDexApplication")) &&
methodName.equals("attachBaseContext")) {
//log(className, access, methodName, desc, signature);
return mv == null ? null : new MethodStackMethodAdapter(mv, className, access, methodName, desc, level);
return mv == null ? null : new MethodStackMethodAdapter(mv, className, DokitExtUtil.getInstance().getSlowMethodConfig().stackMethodConfig.thresholdTime, access, methodName, desc, level);
}
} else {
for (String application : applications) {
if (className.equals(application)) {
if (methodName.equals("attachBaseContext")) {
return mv == null ? null : new MethodStackMethodAdapter(mv, className, access, methodName, desc, level);
} else if (methodName.equals("onCreate") && desc.equals("()V")) {
return mv == null ? null : new MethodStackMethodAdapter(mv, className, access, methodName, desc, level);
}
for (String enterMethod : enterMethods) {
String allMethodName = className + "/" + methodName;
if (allMethodName.equals(enterMethod)) {
return mv == null ? null : new MethodStackMethodAdapter(mv, className, DokitExtUtil.getInstance().getSlowMethodConfig().stackMethodConfig.thresholdTime, access, methodName, desc, level);
}
}
}
......@@ -126,7 +118,7 @@ public final class DokitMethodStackClassAdapter extends ClassVisitor {
if (MethodStackNodeUtil.firstMethodStackNodes.containsKey(key)) {
methodStackNode = MethodStackNodeUtil.firstMethodStackNodes.get(key);
if (methodStackNode != null) {
return mv == null ? null : new MethodStackMethodAdapter(mv, className, access, methodName, desc, level);
return mv == null ? null : new MethodStackMethodAdapter(mv, className, DokitExtUtil.getInstance().getSlowMethodConfig().stackMethodConfig.thresholdTime, access, methodName, desc, level);
}
}
......@@ -136,7 +128,7 @@ public final class DokitMethodStackClassAdapter extends ClassVisitor {
if (MethodStackNodeUtil.secondMethodStackNodes.containsKey(key)) {
methodStackNode = MethodStackNodeUtil.secondMethodStackNodes.get(key);
if (methodStackNode != null) {
return mv == null ? null : new MethodStackMethodAdapter(mv, className, access, methodName, desc, level);
return mv == null ? null : new MethodStackMethodAdapter(mv, className, DokitExtUtil.getInstance().getSlowMethodConfig().stackMethodConfig.thresholdTime, access, methodName, desc, level);
}
}
......@@ -146,7 +138,7 @@ public final class DokitMethodStackClassAdapter extends ClassVisitor {
if (MethodStackNodeUtil.thirdMethodStackNodes.containsKey(key)) {
methodStackNode = MethodStackNodeUtil.thirdMethodStackNodes.get(key);
if (methodStackNode != null) {
return mv == null ? null : new MethodStackMethodAdapter(mv, className, access, methodName, desc, level);
return mv == null ? null : new MethodStackMethodAdapter(mv, className, DokitExtUtil.getInstance().getSlowMethodConfig().stackMethodConfig.thresholdTime, access, methodName, desc, level);
}
}
......@@ -157,7 +149,7 @@ public final class DokitMethodStackClassAdapter extends ClassVisitor {
if (MethodStackNodeUtil.fourthlyMethodStackNodes.containsKey(key)) {
methodStackNode = MethodStackNodeUtil.fourthlyMethodStackNodes.get(key);
if (methodStackNode != null) {
return mv == null ? null : new MethodStackMethodAdapter(mv, className, access, methodName, desc, level);
return mv == null ? null : new MethodStackMethodAdapter(mv, className, DokitExtUtil.getInstance().getSlowMethodConfig().stackMethodConfig.thresholdTime, access, methodName, desc, level);
}
}
......
......@@ -86,10 +86,10 @@ public final class DokitSlowMethodClassAdapter extends ClassVisitor {
MethodVisitor mv = cv.visitMethod(access, methodName, desc, signature, exceptions);
try {
//插件开关被关闭
if (!DokitExtUtil.getInstance().isDokitPluginSwitch()) {
if (!DokitExtUtil.getInstance().dokitPluginSwitchOpen()) {
return mv;
}
if (!DokitExtUtil.getInstance().isSlowMethodSwitch()) {
if (!DokitExtUtil.getInstance().getSlowMethodConfig().methodSwitch) {
return mv;
}
......@@ -104,13 +104,13 @@ public final class DokitSlowMethodClassAdapter extends ClassVisitor {
boolean matchedMethod = false;
for (String packageName : DokitExtUtil.getInstance().getPackageNames()) {
for (String packageName : DokitExtUtil.getInstance().getSlowMethodConfig().normalMethodConfig.packageNames) {
if (className.contains(packageName)) {
if (DokitExtUtil.getInstance().getMethodBlacklist().isEmpty()) {
if (DokitExtUtil.getInstance().getSlowMethodConfig().normalMethodConfig.methodBlacklist.isEmpty()) {
matchedMethod = true;
break;
} else {
for (String blackStr : DokitExtUtil.getInstance().getMethodBlacklist()) {
for (String blackStr : DokitExtUtil.getInstance().getSlowMethodConfig().normalMethodConfig.methodBlacklist) {
//当前全路径类名不存在在黑名单中
if (!className.contains(blackStr)) {
matchedMethod = true;
......@@ -122,8 +122,8 @@ public final class DokitSlowMethodClassAdapter extends ClassVisitor {
}
if (matchedMethod) {
System.out.println("DokitSlowMethod==className===>" + className + " methodName===>" + methodName + " thresholdTime==>" + DokitExtUtil.getInstance().getThresholdTime());
return mv == null ? null : new SlowMethodAdapter(mv, className, DokitExtUtil.getInstance().getThresholdTime(), access, methodName, desc);
System.out.println("DokitSlowMethod==className===>" + className + " methodName===>" + methodName + " thresholdTime==>" + DokitExtUtil.getInstance().getSlowMethodConfig().normalMethodConfig.thresholdTime);
return mv == null ? null : new SlowMethodAdapter(mv, className, DokitExtUtil.getInstance().getSlowMethodConfig().normalMethodConfig.thresholdTime, access, methodName, desc);
}
} catch (Exception e) {
......
package com.didichuxing.doraemonkit.plugin.bytecode;
import com.didichuxing.doraemonkit.plugin.DokitExtUtil;
import com.didichuxing.doraemonkit.plugin.bytecode.method.urlconnection.UrlConnectionMethodAdapter;
import org.objectweb.asm.ClassVisitor;
......@@ -53,10 +52,6 @@ public final class DokitUrlConnectionClassAdapter extends ClassVisitor {
public MethodVisitor visitMethod(int access, String methodName, String desc, String signature, String[] exceptions) {
//从传进来的ClassWriter中读取MethodVisitor
MethodVisitor mv = cv.visitMethod(access, methodName, desc, signature, exceptions);
//开关被关闭 不插入代码
if (!DokitExtUtil.getInstance().isDokitPluginSwitch()) {
return mv;
}
//过滤所有类中当前方法中所有的字节码
return mv == null ? null : new UrlConnectionMethodAdapter(className, methodName, access, desc, mv);
}
......
package com.didichuxing.doraemonkit.plugin.bytecode.method.comm;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.LocalVariablesSorter;
/**
* Only weave com/didichuxing/doraemonkit/aop/OkHttpHook installInterceptor method
* Created by jint on 13/12/2019.
*/
public final class FlagMethodAdapter extends LocalVariablesSorter implements Opcodes {
public FlagMethodAdapter(int access, String desc, MethodVisitor mv) {
super(Opcodes.ASM7, access, desc, mv);
}
@Override
public void visitCode() {
//在installInterceptor 方法之前插入IS_HOOK = true 的代码
mv.visitInsn(ICONST_1);
mv.visitFieldInsn(PUTSTATIC, "com/didichuxing/doraemonkit/DoraemonKitReal", "IS_HOOK", "Z");
super.visitCode();
}
}
package com.didichuxing.doraemonkit.plugin.bytecode.method.comm;
import com.didichuxing.doraemonkit.plugin.DokitExtUtil;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.AdviceAdapter;
import static com.didichuxing.doraemonkit.plugin.DokitExtension.SlowMethodConfig.STRATEGY_STACK;
/**
* Created by jint on 13/12/2019.
* 注入插件配置信息到dokit的DoraemonKitReal install中
*/
public final class PluginConfigMethodAdapter extends AdviceAdapter implements Opcodes {
public PluginConfigMethodAdapter(int access, String desc, MethodVisitor mv, String methodName) {
super(Opcodes.ASM7, mv, access, methodName, desc);
}
@Override
protected void onMethodEnter() {
mv.visitTypeInsn(NEW, "java/util/HashMap");
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESPECIAL, "java/util/HashMap", "<init>", "()V", false);
mv.visitVarInsn(ASTORE, 0);
mv.visitVarInsn(ALOAD, 0);
mv.visitLdcInsn("dokitPluginSwitch");
mv.visitInsn(DokitExtUtil.getInstance().dokitPluginSwitchOpen() ? ICONST_1 : ICONST_0);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", true);
mv.visitInsn(POP);
mv.visitVarInsn(ALOAD, 0);
mv.visitLdcInsn("mapSwitch");
mv.visitInsn(DokitExtUtil.getInstance().getCommConfig().mapSwitch ? ICONST_1 : ICONST_0);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", true);
mv.visitInsn(POP);
mv.visitVarInsn(ALOAD, 0);
mv.visitLdcInsn("networkSwitch");
mv.visitInsn(DokitExtUtil.getInstance().getCommConfig().networkSwitch ? ICONST_1 : ICONST_0);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", true);
mv.visitInsn(POP);
mv.visitVarInsn(ALOAD, 0);
mv.visitLdcInsn("bigImgSwitch");
mv.visitInsn(DokitExtUtil.getInstance().getCommConfig().bigImgSwitch ? ICONST_1 : ICONST_0);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", true);
mv.visitInsn(POP);
mv.visitVarInsn(ALOAD, 0);
mv.visitLdcInsn("methodSwitch");
mv.visitInsn(DokitExtUtil.getInstance().getSlowMethodConfig().methodSwitch ? ICONST_1 : ICONST_0);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", true);
mv.visitInsn(POP);
mv.visitVarInsn(ALOAD, 0);
mv.visitLdcInsn("methodStrategy");
mv.visitInsn(DokitExtUtil.getInstance().getSlowMethodConfig().strategy == STRATEGY_STACK ? ICONST_0 : ICONST_1);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", true);
mv.visitInsn(POP);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESTATIC, "com/didichuxing/doraemonkit/aop/DokitPluginConfig", "inject", "(Ljava/util/Map;)V", false);
super.onMethodEnter();
}
}
......@@ -16,15 +16,20 @@ public final class MethodStackMethodAdapter extends AdviceAdapter implements Opc
private String methodName;
private String desc;
private int level;
/**
* 函数耗时阈值
*/
private int thresholdTime;
/**
* 是否属于静态方法
*/
private boolean isStaticMethod;
public MethodStackMethodAdapter(MethodVisitor methodVisitor, String className, int access, String methodName, String desc, int level) {
public MethodStackMethodAdapter(MethodVisitor methodVisitor, String className, int thresholdTime, int access, String methodName, String desc, int level) {
super(Opcodes.ASM7, methodVisitor, access, methodName, desc);
this.className = className;
this.methodName = methodName;
this.thresholdTime = thresholdTime;
this.desc = desc;
this.level = level;
//access值得计算方式为 Opcodes.ACC_PUBLIC & Opcodes.ACC_STATIC
......@@ -41,9 +46,7 @@ public final class MethodStackMethodAdapter extends AdviceAdapter implements Opc
@Override
public void visitMethodInsn(int opcode, String innerClassName, String innerMethodName, String innerDesc, boolean isInterface) {
//全局替换URL的openConnection方法为dokit的URLConnection
if (className.equals(DokitExtUtil.getInstance().getApplications().get(0))) {
log(opcode, innerClassName, innerMethodName, innerDesc, isInterface);
}
//普通方法 内部方法 静态方法
if (opcode == Opcodes.INVOKEVIRTUAL || opcode == Opcodes.INVOKESTATIC || opcode == Opcodes.INVOKESPECIAL) {
//过滤掉构造方法
......@@ -62,7 +65,6 @@ public final class MethodStackMethodAdapter extends AdviceAdapter implements Opc
switch (level) {
case MethodStackNodeUtil.LEVEL_0:
methodStackNode.setLevel(MethodStackNodeUtil.LEVEL_1);
System.out.println("methodStackNode==>" + methodStackNode);
MethodStackNodeUtil.addFirstLevel(methodStackNode);
break;
case MethodStackNodeUtil.LEVEL_1:
......@@ -98,21 +100,25 @@ public final class MethodStackMethodAdapter extends AdviceAdapter implements Opc
if (isStaticMethod) {
//静态方法需要插入的代码
mv.visitMethodInsn(INVOKESTATIC, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "getInstance", "()Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;", false);
mv.visitIntInsn(SIPUSH, thresholdTime);
mv.visitInsn(level + ICONST_0);
mv.visitLdcInsn(className);
mv.visitLdcInsn(methodName);
mv.visitLdcInsn(desc);
mv.visitMethodInsn(INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "recodeStaticMethodCostStart", "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "recodeStaticMethodCostStart", "(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", false);
} else {
//普通方法插入的代码
mv.visitMethodInsn(INVOKESTATIC, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "getInstance", "()Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;", false);
mv.visitIntInsn(SIPUSH, thresholdTime);
mv.visitInsn(level + ICONST_0);
mv.visitLdcInsn(className);
mv.visitLdcInsn(methodName);
mv.visitLdcInsn(desc);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "recodeObjectMethodCostStart", "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "recodeObjectMethodCostStart", "(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V", false);
}
} catch (Exception e) {
......@@ -128,21 +134,23 @@ public final class MethodStackMethodAdapter extends AdviceAdapter implements Opc
if (isStaticMethod) {
//静态方法需要插入的代码
mv.visitMethodInsn(INVOKESTATIC, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "getInstance", "()Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;", false);
mv.visitIntInsn(SIPUSH, thresholdTime);
mv.visitInsn(level + ICONST_0);
mv.visitLdcInsn(className);
mv.visitLdcInsn(methodName);
mv.visitLdcInsn(desc);
mv.visitMethodInsn(INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "recodeStaticMethodCostEnd", "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "recodeStaticMethodCostEnd", "(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", false);
} else {
//普通方法插入的代码
mv.visitMethodInsn(INVOKESTATIC, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "getInstance", "()Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;", false);
mv.visitIntInsn(SIPUSH, thresholdTime);
mv.visitInsn(level + ICONST_0);
mv.visitLdcInsn(className);
mv.visitLdcInsn(methodName);
mv.visitLdcInsn(desc);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "recodeObjectMethodCostEnd", "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil", "recodeObjectMethodCostEnd", "(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V", false);
}
} catch (Exception e) {
e.printStackTrace();
......
package com.didichuxing.doraemonkit.plugin.weaver;
import com.android.build.gradle.AppExtension;
import com.didichuxing.doraemonkit.plugin.DokitExtUtil;
import com.didichuxing.doraemonkit.plugin.DokitExtension;
import com.didichuxing.doraemonkit.plugin.bytecode.DokitBigImageClassAdapter;
import com.didichuxing.doraemonkit.plugin.bytecode.DokitCommClassAdapter;
import com.didichuxing.doraemonkit.plugin.bytecode.DokitSlowMethodClassAdapter;
import com.quinn.hunter.transform.asm.BaseWeaver;
......@@ -37,7 +39,11 @@ public class DokitBigImageWeaver extends BaseWeaver {
@Override
protected ClassVisitor wrapClassWriter(ClassWriter classWriter) {
//返回指定的ClassVisitor
return new DokitBigImageClassAdapter(classWriter);
if (DokitExtUtil.getInstance().dokitPluginSwitchOpen()) {
//返回指定的ClassVisitor
return new DokitBigImageClassAdapter(classWriter);
} else {
return super.wrapClassWriter(classWriter);
}
}
}
package com.didichuxing.doraemonkit.plugin.weaver;
import com.android.build.gradle.AppExtension;
import com.didichuxing.doraemonkit.plugin.DokitExtUtil;
import com.didichuxing.doraemonkit.plugin.DokitExtension;
import com.didichuxing.doraemonkit.plugin.bytecode.DokitCommClassAdapter;
import com.quinn.hunter.transform.asm.BaseWeaver;
......@@ -36,7 +37,11 @@ public class DokitCommWeaver extends BaseWeaver {
@Override
protected ClassVisitor wrapClassWriter(ClassWriter classWriter) {
//返回指定的ClassVisitor
return new DokitCommClassAdapter(classWriter);
if (DokitExtUtil.getInstance().dokitPluginSwitchOpen()) {
return new DokitCommClassAdapter(classWriter);
} else {
return super.wrapClassWriter(classWriter);
}
}
}
package com.didichuxing.doraemonkit.plugin.weaver;
import com.android.build.gradle.AppExtension;
import com.didichuxing.doraemonkit.plugin.DokitExtUtil;
import com.didichuxing.doraemonkit.plugin.DokitExtension;
import com.didichuxing.doraemonkit.plugin.bytecode.DokitMethodStackClassAdapter;
import com.quinn.hunter.transform.asm.BaseWeaver;
......@@ -8,6 +9,8 @@ import com.quinn.hunter.transform.asm.BaseWeaver;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import static com.didichuxing.doraemonkit.plugin.DokitExtension.SlowMethodConfig.STRATEGY_STACK;
/**
* ================================================
* 作 者:jint(金台)
......@@ -44,7 +47,14 @@ public class DokitMethodStackWeaver extends BaseWeaver {
*/
@Override
protected ClassVisitor wrapClassWriter(ClassWriter classWriter) {
//返回指定的ClassVisitor
return new DokitMethodStackClassAdapter(classWriter, level);
boolean isOpen = DokitExtUtil.getInstance().dokitPluginSwitchOpen() &&
DokitExtUtil.getInstance().getSlowMethodConfig().methodSwitch &&
DokitExtUtil.getInstance().getSlowMethodConfig().strategy == STRATEGY_STACK;
if (isOpen) {
return new DokitMethodStackClassAdapter(classWriter, level);
} else {
return super.wrapClassWriter(classWriter);
}
}
}
package com.didichuxing.doraemonkit.plugin.weaver;
import com.android.build.gradle.AppExtension;
import com.didichuxing.doraemonkit.plugin.DokitExtUtil;
import com.didichuxing.doraemonkit.plugin.DokitExtension;
import com.didichuxing.doraemonkit.plugin.bytecode.DokitMethodStackClassAdapter;
import com.didichuxing.doraemonkit.plugin.bytecode.DokitSlowMethodClassAdapter;
import com.quinn.hunter.transform.asm.BaseWeaver;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import static com.didichuxing.doraemonkit.plugin.DokitExtension.SlowMethodConfig.STRATEGY_NORMAL;
import static com.didichuxing.doraemonkit.plugin.DokitExtension.SlowMethodConfig.STRATEGY_STACK;
/**
* ================================================
* 作 者:jint(金台)
......@@ -36,7 +41,15 @@ public class DokitSlowMethodWeaver extends BaseWeaver {
@Override
protected ClassVisitor wrapClassWriter(ClassWriter classWriter) {
//返回指定的ClassVisitor
return new DokitSlowMethodClassAdapter(classWriter);
boolean isOpen = DokitExtUtil.getInstance().dokitPluginSwitchOpen() &&
DokitExtUtil.getInstance().getSlowMethodConfig().methodSwitch &&
DokitExtUtil.getInstance().getSlowMethodConfig().strategy == STRATEGY_NORMAL;
if (isOpen) {
return new DokitSlowMethodClassAdapter(classWriter);
} else {
return super.wrapClassWriter(classWriter);
}
}
}
package com.didichuxing.doraemonkit.plugin.weaver;
import com.android.build.gradle.AppExtension;
import com.didichuxing.doraemonkit.plugin.DokitExtUtil;
import com.didichuxing.doraemonkit.plugin.DokitExtension;
import com.didichuxing.doraemonkit.plugin.bytecode.DokitCommClassAdapter;
import com.didichuxing.doraemonkit.plugin.bytecode.DokitSlowMethodClassAdapter;
import com.didichuxing.doraemonkit.plugin.bytecode.DokitUrlConnectionClassAdapter;
import com.quinn.hunter.transform.asm.BaseWeaver;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import static com.didichuxing.doraemonkit.plugin.DokitExtension.SlowMethodConfig.STRATEGY_NORMAL;
/**
* ================================================
* 作 者:jint(金台)
......@@ -37,7 +41,12 @@ public class DokitUrlConnectionWeaver extends BaseWeaver {
@Override
protected ClassVisitor wrapClassWriter(ClassWriter classWriter) {
//返回指定的ClassVisitor
return new DokitUrlConnectionClassAdapter(classWriter);
boolean isOpen = DokitExtUtil.getInstance().dokitPluginSwitchOpen() &&
DokitExtUtil.getInstance().getCommConfig().networkSwitch;
if (isOpen) {
return new DokitUrlConnectionClassAdapter(classWriter);
} else {
return super.wrapClassWriter(classWriter);
}
}
}
......@@ -179,7 +179,7 @@ public class RpcMockInterceptor implements RpcInterceptor<HttpRpcRequest, HttpRp
return matchedTemplateRule(oldResponse, path, templateMatchedId);
}
StringBuffer sb = new StringBuffer();
StringBuilder sb = new StringBuilder();
String newUrl;
if (NetworkManager.MOCK_SCHEME_HTTP.contains(scheme.toLowerCase())) {
newUrl = sb.append(NetworkManager.MOCK_SCHEME_HTTP).append(NetworkManager.MOCK_HOST).append("/api/app/scene/").append(selectedSceneId).toString();
......
......@@ -118,6 +118,7 @@ class DoraemonKitReal {
* @param productId Dokit平台端申请的productId
*/
static void install(final Application app, List<AbstractKit> selfKits, String productId) {
pluginConfig();
DokitConstant.PRODUCT_ID = productId;
DokitConstant.APP_HEALTH_RUNNING = GlobalConfig.getAppHealth();
//添加常用工具
......@@ -305,6 +306,12 @@ class DoraemonKitReal {
DataPickManager.getInstance().postData();
}
/**
* 插件会在当前方法中插入代码
*/
private static void pluginConfig() {
}
private static void checkGPSMock() {
if (GpsMockConfig.isGPSMockOpen()) {
......
package com.didichuxing.doraemonkit.aop;
import com.didichuxing.doraemonkit.util.LogHelper;
import java.util.Map;
/**
* ================================================
* 作 者:jint(金台)
* 版 本:1.0
* 创建日期:2020/4/27-18:24
* 描 述:
* 修订历史:
* ================================================
*/
public class DokitPluginConfig {
// private static final String TAG = "DokitPluginConfig";
public static boolean SWITCH_METHOD = true;
public static int STRATEGY_STACK = 0;
public static int STRATEGY_NORMAL = 1;
/**
* 0 代表调用栈 1:代表普通模式
*/
public static int VALUE_METHOD_STRATEGY = STRATEGY_STACK;
public static boolean SWITCH_DOKIT_PLUGIN = true;
public static boolean SWITCH_BIG_IMG = true;
public static boolean SWITCH_NETWORK = true;
public static boolean SWITCH_MAP = true;
/**
* 注入插件配置 动态注入到DoraemonKitReal#pluginConfig方法中
*/
public static void inject(Map config) {
//LogHelper.i(TAG, "map====>" + config);
SWITCH_DOKIT_PLUGIN = (boolean) config.get("dokitPluginSwitch");
SWITCH_METHOD = (boolean) config.get("methodSwitch");
SWITCH_BIG_IMG = (boolean) config.get("bigImgSwitch");
SWITCH_NETWORK = (boolean) config.get("networkSwitch");
SWITCH_MAP = (boolean) config.get("mapSwitch");
VALUE_METHOD_STRATEGY = (int) config.get("methodStrategy");
}
}
......@@ -47,7 +47,7 @@ public class MethodStackUtil {
* @param methodName
* @param classObj null 代表静态函数
*/
public void recodeObjectMethodCostStart(int level, String className, String methodName, String desc, Object classObj) {
public void recodeObjectMethodCostStart(int thresholdTime, int level, String className, String methodName, String desc, Object classObj) {
try {
MethodInvokNode methodInvokNode = new MethodInvokNode();
......@@ -84,7 +84,7 @@ public class MethodStackUtil {
* @param desc
* @param classObj null 代表静态函数
*/
public void recodeObjectMethodCostEnd(int level, String className, String methodName, String desc, Object classObj) {
public void recodeObjectMethodCostEnd(int thresholdTime, int level, String className, String methodName, String desc, Object classObj) {
synchronized (MethodCostUtil.class) {
try {
......@@ -103,7 +103,7 @@ public class MethodStackUtil {
}
if (methodInvokNode != null) {
methodInvokNode.setEndTimeMillis(System.currentTimeMillis());
bindNode(level, methodInvokNode);
bindNode(thresholdTime, level, methodInvokNode);
}
//打印函数调用栈
......@@ -137,13 +137,13 @@ public class MethodStackUtil {
}
private void bindNode(int level, MethodInvokNode methodInvokNode) {
private void bindNode(int thresholdTime, int level, MethodInvokNode methodInvokNode) {
if (methodInvokNode == null) {
return;
}
//过滤掉小于10ms的函数
if (methodInvokNode.getCostTimeMillis() <= 1) {
if (methodInvokNode.getCostTimeMillis() <= thresholdTime) {
return;
}
......@@ -189,13 +189,13 @@ public class MethodStackUtil {
}
public void recodeStaticMethodCostStart(int level, String className, String methodName, String desc) {
recodeObjectMethodCostStart(level, className, methodName, desc, null);
public void recodeStaticMethodCostStart(int thresholdTime, int level, String className, String methodName, String desc) {
recodeObjectMethodCostStart(thresholdTime, level, className, methodName, desc, null);
}
public void recodeStaticMethodCostEnd(int level, String className, String methodName, String desc) {
recodeObjectMethodCostEnd(level, className, methodName, desc, null);
public void recodeStaticMethodCostEnd(int thresholdTime, int level, String className, String methodName, String desc) {
recodeObjectMethodCostEnd(thresholdTime, level, className, methodName, desc, null);
}
private void jsonTravel(List<MethodStackBean> methodStackBeans, List<MethodInvokNode> methodInvokNodes) {
......
......@@ -251,7 +251,7 @@ public class MockInterceptor implements Interceptor {
matchedTemplateRule(oldResponse, path, templateMatchedId);
return oldResponse;
}
StringBuffer sb = new StringBuffer();
StringBuilder sb = new StringBuilder();
String newUrl;
if (NetworkManager.MOCK_SCHEME_HTTP.contains(scheme.toLowerCase())) {
newUrl = sb.append(NetworkManager.MOCK_SCHEME_HTTP).append(NetworkManager.MOCK_HOST).append("/api/app/scene/").append(selectedSceneId).toString();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册