All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.imqa.asm.ActivityClassVisitor Maven / Gradle / Ivy

There is a newer version: 2.25.11
Show newest version
package io.imqa.asm;

import org.objectweb.asm.*; 

import java.util.HashMap;
import java.util.Set;

import io.imqa.injector.MappingDecoder;
import io.imqa.injector.util.Logger;

public class ActivityClassVisitor extends ClassVisitor {
	HashMap lifeCycle = new HashMap<>(); // onCreate, onStart, onResume
	String superClass = "";

	public ActivityClassVisitor(ClassVisitor cv) {
		super(Opcodes.ASM5, cv);
		lifeCycle.put("onCreate", false);
		lifeCycle.put("onStart", false);
		lifeCycle.put("onResume", false);
	}

	@Override
	public void visit(int version, int access, String name,
		String signature, String superName, String[] interfaces) {
		cv.visit(version, access, name, signature, superName, interfaces);
		superClass = superName;
		Logger.d("Lifecycle Super Name", superClass);
	}

	@Override 
	public MethodVisitor visitMethod(int access, String name, 
			String desc, String signature, String[] exceptions) { 
		MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
//		Logger.d("Lifecycle VISIT", name+", "+desc + ", "+signature+", "+access);
		switch (name) {
			case "onCreate":
				Logger.d("Lifecycle Name", name+", "+desc + ", "+signature+", "+access);
				lifeCycle.replace("onCreate", true);
//				return new ActivityMethodVisitor(Opcodes.ASM5, mv, name);
				return new LifecycleVisitor(access, name, desc, mv);
			case "onStart":
				Logger.d("Lifecycle Name", name+", "+desc + ", "+signature+", "+access);
				lifeCycle.replace("onStart", true);
//				return new ActivityMethodVisitor(Opcodes.ASM5, mv, name);
				return new LifecycleVisitor(access, name, desc, mv);
			case "onResume":
				lifeCycle.replace("onResume", true);
				Logger.d("Lifecycle Name", name+", "+desc + ", "+signature+", "+access);
//				return new ActivityMethodVisitor(Opcodes.ASM5, mv, name);
				return new LifecycleVisitor(access, name, desc, mv);
			default:
				return mv;
		}
	}
	
	@Override
	public void visitEnd() {
		// 액티비티 클래스에 Life cycle 구현 안된 곳이 있다면 새로 작성
		Set cycleNames = lifeCycle.keySet();
		for(String cycleName : cycleNames) {
			if (!lifeCycle.get(cycleName)) {
				// Adapter 새로 달아서 하고 싶은데..
				//ClassVisitor customCv = new OverrideAdapter(cv);
				//customCv.visitMethod(Opcodes.ACC_PROTECTED, cycleName,"()V", null, null).visitEnd();
				// TODO visitMethod 해서 나온 mv 를 어댑터를 달아서 visitCode를 변경


				//MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PROTECTED, cycleName,"()V", null, null);
				//MethodVisitor mv = new TransformerAdapter();

				String desc = getDesc(cycleName);

//				String superClass = SuperFind.find(ActivityTransformer.buildLocation, this.superClass, cycleName, desc);

				Logger.d("Lifecycle Super Class", superClass);
				Logger.d("Lifecycle Super Desc", desc);

				MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PROTECTED, cycleName, desc, null, null);
/*

				mv.visitMethodInsn(
						Opcodes.INVOKESTATIC,
						"io/imqa/mpm/IMQAMpmAgent",
						"getInstance",
						"()Lio/imqa/mpm/IMQAMpmAgent;",
						false);
				mv.visitFieldInsn(
						Opcodes.GETSTATIC,
						"io/imqa/core/dump/ActivityRenderData",
						cycleName,
						MappingDecoder.getInstance().decodeField("Ljava/lang/String;"));
				mv.visitMethodInsn(
						Opcodes.INVOKEVIRTUAL,
						"io/imqa/mpm/IMQAMpmAgent",
						"startRender",
						MappingDecoder.getInstance().decodeDesc("(Ljava/lang/String;)V"),
						false);


				mv.visitVarInsn(Opcodes.ALOAD, 0);
				if (cycleName.equals("onCreate")) {
					mv.visitVarInsn(Opcodes.ALOAD, 1);
				}
				mv.visitMethodInsn(
						Opcodes.INVOKESPECIAL,
						superClass,
						cycleName,
						desc,
						false);


				mv.visitMethodInsn(
						Opcodes.INVOKESTATIC,
						"io/imqa/mpm/IMQAMpmAgent",
						"getInstance",
						"()Lio/imqa/mpm/IMQAMpmAgent;",
						false);
				mv.visitFieldInsn(
						Opcodes.GETSTATIC,
						"io/imqa/core/dump/ActivityRenderData",
						cycleName,
						MappingDecoder.getInstance().decodeField("Ljava/lang/String;"));
				mv.visitMethodInsn(
						Opcodes.INVOKEVIRTUAL,
						"io/imqa/mpm/IMQAMpmAgent",
						"endRender",
						MappingDecoder.getInstance().decodeDesc("(Ljava/lang/String;)V"),
						false);
*/

				LifecycleMakerVisitor lifecyclemv = new LifecycleMakerVisitor(
					Opcodes.ACC_PROTECTED, 
					cycleName, 
					superClass,
					desc,
					mv);
				lifecyclemv.visitMaxs(1,1);
				lifecyclemv.visitCode();

				lifecyclemv.visitInsn(Opcodes.RETURN);
				/*onMethodTop(mv, fieldName);
				onMethodMiddle(mv, cycleName);
				onMethodBottom(mv, fieldName);
				mv.visitMaxs(1+4,1);
				mv.visitEnd();
				*/
			}
		}

		cv.visitEnd();
	}


	protected String getDesc(String cycleName) {
		String desc = "";
		switch (cycleName) {
			case "onCreate":
				desc = MappingDecoder.getInstance().decodeDesc("(Landroid/os/Bundle;)V");
				break;
			case "onStart":
			case "onResume":
				desc = "()V";
				break;
		}

		return desc;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy