@@ -2,6 +2,7 @@ package com.sensorsdata.analytics.android.plugin
22
33import org.objectweb.asm.AnnotationVisitor
44import org.objectweb.asm.ClassVisitor
5+ import org.objectweb.asm.FieldVisitor
56import org.objectweb.asm.MethodVisitor
67import org.objectweb.asm.Opcodes
78
@@ -12,14 +13,22 @@ class SensorsAnalyticsClassVisitor extends ClassVisitor implements Opcodes {
1213 private HashSet<String > visitedFragMethods = new HashSet<> ()// 无需判空
1314 private ClassVisitor classVisitor
1415
16+ private SensorsAnalyticsTransformHelper transformHelper
17+
18+ private ClassNameAnalytics classNameAnalytics
19+
20+ private ArrayList<SensorsAnalyticsMethodCell > methodCells = new ArrayList<> ()
21+
1522 @Override
1623 protected Object clone () throws CloneNotSupportedException {
1724 return super . clone()
1825 }
1926
20- SensorsAnalyticsClassVisitor (final ClassVisitor classVisitor ) {
27+ SensorsAnalyticsClassVisitor (final ClassVisitor classVisitor , ClassNameAnalytics classNameAnalytics , SensorsAnalyticsTransformHelper transformHelper ) {
2128 super (Opcodes . ASM6 , classVisitor)
2229 this . classVisitor = classVisitor
30+ this . classNameAnalytics = classNameAnalytics
31+ this . transformHelper = transformHelper
2332 }
2433
2534 private
@@ -85,10 +94,38 @@ class SensorsAnalyticsClassVisitor extends ClassVisitor implements Opcodes {
8594 }
8695 }
8796
97+ for (cell in methodCells) {
98+ transformHelper. sensorsAnalyticsHookConfig. " ${ cell.agentName} " (classVisitor,cell)
99+ }
100+
88101 Logger . info(" 结束扫描类:${ mClassName} \n " )
89102 }
90103
91- /**
104+
105+ @Override
106+ FieldVisitor visitField (int access , String name , String descriptor , String signature , Object value ) {
107+ if (classNameAnalytics. isSensorsDataAPI) {
108+ if (' VERSION' == name) {
109+ String version = (String )value
110+ if (SensorsAnalyticsTransform . MIN_SDK_VERSION > version) {
111+ String errMessage = " 你目前集成的神策埋点 SDK 版本号为 v${ version} ,请升级到 v${ SensorsAnalyticsTransform.MIN_SDK_VERSION} 及以上的版本。详情请参考:https://github.com/sensorsdata/sa-sdk-android"
112+ Logger . error(errMessage)
113+ throw new UnsupportedOperationException (errMessage)
114+ }
115+ } else if (' MIN_PLUGIN_VERSION' == name) {
116+ String minPluginVersion = (String )value
117+ if (minPluginVersion != " " && minPluginVersion != null ) {
118+ if (SensorsAnalyticsTransform . VERSION < minPluginVersion) {
119+ String errMessage = " 你目前集成的神策插件版本号为 v${ SensorsAnalyticsTransform.VERSION} ,请升级到 v${ minPluginVersion} 及以上的版本。详情请参考:https://github.com/sensorsdata/sa-sdk-android-plugin2"
120+ Logger . error(errMessage)
121+ throw new UnsupportedOperationException (errMessage)
122+ }
123+ }
124+ }
125+ }
126+ return super . visitField(access, name, descriptor, signature, value)
127+ }
128+ /**
92129 * 该方法是当扫描器扫描到类的方法时进行调用
93130 * @param access 表示方法的修饰符
94131 * @param name 表示方法名,在 ASM 中 “visitMethod” 方法会处理(构造方法、静态代码块、私有方法、受保护的方法、共有方法、native类型方法)。
@@ -100,11 +137,20 @@ class SensorsAnalyticsClassVisitor extends ClassVisitor implements Opcodes {
100137 */
101138 @Override
102139 MethodVisitor visitMethod (int access , String name , String desc , String signature , String [] exceptions ) {
140+ for (methodCell in classNameAnalytics. methodCells) {
141+ if (methodCell. name == name && methodCell. desc == desc) {
142+ methodCells. add(methodCell)
143+ return null
144+ }
145+ }
146+
103147 MethodVisitor methodVisitor = cv. visitMethod(access, name, desc, signature, exceptions)
104148
105149 methodVisitor = new SensorsAnalyticsDefaultMethodVisitor (methodVisitor, access, name, desc) {
106150 boolean isSensorsDataTrackViewOnClickAnnotation = false
107151 boolean isSensorsDataIgnoreTrackOnClick = false
152+ String eventName = null
153+ String eventProperties = null
108154 boolean isHasInstrumented = false
109155 boolean isHasTracked = false
110156
@@ -119,8 +165,12 @@ class SensorsAnalyticsClassVisitor extends ClassVisitor implements Opcodes {
119165 }
120166
121167 @Override
122- protected void onMethodEnter () {
123- super . onMethodEnter()
168+ protected void onMethodExit (int opcode ) {
169+ if (classNameAnalytics. isSensorsDataAPI) {
170+ return
171+ }
172+
173+ super . onMethodExit(opcode)
124174
125175 if (isSensorsDataIgnoreTrackOnClick) {
126176 return
@@ -129,16 +179,46 @@ class SensorsAnalyticsClassVisitor extends ClassVisitor implements Opcodes {
129179 /**
130180 * 在 android.gradle 的 3.2.1 版本中,针对 view 的 setOnClickListener 方法 的 lambda 表达式做特殊处理。
131181 */
132- if (name. trim(). startsWith(' lambda$' ) && SensorsAnalyticsUtil . isPrivate(access) && SensorsAnalyticsUtil . isSynthetic(access)) {
133- SensorsAnalyticsMethodCell sensorsAnalyticsMethodCell = SensorsAnalyticsHookConfig . sLambdaMethods. get(desc)
134- if (sensorsAnalyticsMethodCell != null ) {
135- int paramStart = sensorsAnalyticsMethodCell. paramsStart
136- if (SensorsAnalyticsUtil . isStatic(access)) {
137- paramStart = paramStart - 1
182+ if (transformHelper. lambdaEnabled) {
183+ if (name. trim(). startsWith(' lambda$' ) && SensorsAnalyticsUtil . isPrivate(access) && SensorsAnalyticsUtil . isSynthetic(access)) {
184+ if (desc == ' (Landroid/view/MenuItem;)Z' && SensorsAnalyticsUtil . isStatic(access)) {
185+ SensorsAnalyticsMethodCell sensorsAnalyticsMethodCell = SensorsAnalyticsHookConfig . sLambdaMethods. get(desc + ' 2' )
186+ if (sensorsAnalyticsMethodCell != null ) {
187+ visitMethodWithLoadedParams(methodVisitor, Opcodes . INVOKESTATIC , SensorsAnalyticsHookConfig . sSensorsAnalyticsAPI,
188+ sensorsAnalyticsMethodCell. agentName, sensorsAnalyticsMethodCell. agentDesc,
189+ sensorsAnalyticsMethodCell. paramsStart, sensorsAnalyticsMethodCell. paramsCount, sensorsAnalyticsMethodCell. opcodes)
190+ isHasTracked = true
191+ return
192+ }
193+ } else {
194+ SensorsAnalyticsMethodCell sensorsAnalyticsMethodCell = SensorsAnalyticsHookConfig . sLambdaMethods. get(desc)
195+ if (sensorsAnalyticsMethodCell != null ) {
196+ int paramStart = sensorsAnalyticsMethodCell. paramsStart
197+ if (SensorsAnalyticsUtil . isStatic(access)) {
198+ paramStart = paramStart - 1
199+ }
200+ visitMethodWithLoadedParams(methodVisitor, Opcodes . INVOKESTATIC , SensorsAnalyticsHookConfig . sSensorsAnalyticsAPI,
201+ sensorsAnalyticsMethodCell. agentName, sensorsAnalyticsMethodCell. agentDesc,
202+ paramStart, sensorsAnalyticsMethodCell. paramsCount, sensorsAnalyticsMethodCell. opcodes)
203+ isHasTracked = true
204+ return
205+ }
138206 }
139- visitMethodWithLoadedParams(methodVisitor, Opcodes . INVOKESTATIC , SensorsAnalyticsHookConfig . sSensorsAnalyticsAPI,
140- sensorsAnalyticsMethodCell. agentName, sensorsAnalyticsMethodCell. agentDesc,
141- paramStart, sensorsAnalyticsMethodCell. paramsCount, sensorsAnalyticsMethodCell. opcodes)
207+ }
208+ }
209+
210+ /**
211+ * Method 描述信息
212+ */
213+ String nameDesc = name + desc
214+
215+ /**
216+ * 处理 ViewPager
217+ */
218+ if (mClassName == ' android/support/v4/view/ViewPager' || mClassName == ' androidx/viewpager/widget/ViewPager' ) {
219+ if (nameDesc == ' dispatchOnPageSelected(I)V' ) {
220+ methodVisitor. visitVarInsn(ALOAD , 0 )
221+ methodVisitor. visitMethodInsn(INVOKESTATIC , SensorsAnalyticsHookConfig . sSensorsAnalyticsAPI, " trackViewOnClick" , " (Landroid/view/View;)V" , false )
142222 isHasTracked = true
143223 return
144224 }
@@ -155,11 +235,6 @@ class SensorsAnalyticsClassVisitor extends ClassVisitor implements Opcodes {
155235 return
156236 }
157237
158- /**
159- * Method 描述信息
160- */
161- String nameDesc = name + desc
162-
163238 /**
164239 * React Native
165240 */
@@ -200,9 +275,14 @@ class SensorsAnalyticsClassVisitor extends ClassVisitor implements Opcodes {
200275 * 目前支持 onContextItemSelected(MenuItem item)、onOptionsItemSelected(MenuItem item)
201276 */
202277 if (SensorsAnalyticsUtil . isTargetMenuMethodDesc(nameDesc)) {
203- methodVisitor. visitVarInsn(ALOAD , 0 )
204- methodVisitor. visitVarInsn(ALOAD , 1 )
205- methodVisitor. visitMethodInsn(INVOKESTATIC , SensorsAnalyticsHookConfig . sSensorsAnalyticsAPI, " trackMenuItem" , " (Ljava/lang/Object;Landroid/view/MenuItem;)V" , false )
278+ if (SensorsAnalyticsUtil . isStatic(access)) {
279+ methodVisitor. visitVarInsn(ALOAD , 1 )
280+ methodVisitor. visitMethodInsn(INVOKESTATIC , SensorsAnalyticsHookConfig . sSensorsAnalyticsAPI, " trackMenuItem" , " (Landroid/view/MenuItem;)V" , false )
281+ } else {
282+ methodVisitor. visitVarInsn(ALOAD , 0 )
283+ methodVisitor. visitVarInsn(ALOAD , 1 )
284+ methodVisitor. visitMethodInsn(INVOKESTATIC , SensorsAnalyticsHookConfig . sSensorsAnalyticsAPI, " trackMenuItem" , " (Ljava/lang/Object;Landroid/view/MenuItem;)V" , false )
285+ }
206286 isHasTracked = true
207287 return
208288 }
@@ -250,6 +330,14 @@ class SensorsAnalyticsClassVisitor extends ClassVisitor implements Opcodes {
250330 }
251331 }
252332
333+ if (eventName != null && eventName. length() != 0 ) {
334+ methodVisitor. visitLdcInsn(eventName)
335+ methodVisitor. visitLdcInsn(eventProperties)
336+ methodVisitor. visitMethodInsn(INVOKESTATIC , SensorsAnalyticsHookConfig . sSensorsAnalyticsAPI, " track" , " (Ljava/lang/String;Ljava/lang/String;)V" , false )
337+ isHasTracked = true
338+ return
339+ }
340+
253341 if (mInterfaces != null && mInterfaces. length > 0 ) {
254342 SensorsAnalyticsMethodCell sensorsAnalyticsMethodCell = SensorsAnalyticsHookConfig . sInterfaceMethods. get(nameDesc)
255343 if (sensorsAnalyticsMethodCell != null && mInterfaces. contains(sensorsAnalyticsMethodCell. parent)) {
@@ -292,10 +380,25 @@ class SensorsAnalyticsClassVisitor extends ClassVisitor implements Opcodes {
292380 isHasInstrumented = true
293381 }
294382
383+ if (s == ' Lcom/sensorsdata/analytics/android/sdk/SensorsDataTrackEvent;' ) {
384+ return new AnnotationVisitor (Opcodes . ASM6 ) {
385+ @Override
386+ void visit (String key , Object value ) {
387+ super . visit(key, value)
388+ if (" eventName" == key) {
389+ eventName = (String )value
390+ } else if (" properties" == key) {
391+ eventProperties = value. toString()
392+ }
393+ }
394+ }
395+ }
396+
295397 return super . visitAnnotation(s, b)
296398 }
297399 }
298400
299401 return methodVisitor
300402 }
403+
301404}
0 commit comments