package com.frogermcs.androiddevmetrics.aspect; import com.frogermcs.androiddevmetrics.internal.metrics.InitManager; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.CodeSignature; import org.aspectj.lang.reflect.ConstructorSignature; import org.aspectj.lang.reflect.MethodSignature; import java.util.concurrent.TimeUnit; @Aspect public class Dagger2GraphAnalyzer { private static volatile boolean enabled = false; public static void setEnabled(boolean enabled) { Dagger2GraphAnalyzer.enabled = enabled; } public static boolean isEnabled() { return enabled; } @Pointcut("within(@dagger.Module *)") public void withinAnnotatedClass() { } @Pointcut("execution(@javax.inject.Inject *.new(..))") public void injectConstructor() { } //Exclude methods from *_MonitoringModule (Dagger 2 producers) @Pointcut("!execution(* defaultSetOfFactories())") public void exceprDefaultSetOfFactories() { } @Pointcut("!execution(dagger.producers.monitoring.ProductionComponentMonitor *(..))") public void exceptProductionComponentMonitor() { } @Pointcut("execution(@dagger.Provides * *(..)) &&" + " withinAnnotatedClass() &&" + " exceptProductionComponentMonitor()" + " && exceprDefaultSetOfFactories()") public void providesMethod() { } @Around("providesMethod() || injectConstructor()") public Object logAndExecute(ProceedingJoinPoint joinPoint) throws Throwable { long start = System.nanoTime(); Object result = joinPoint.proceed(); long stop = System.nanoTime(); long took = TimeUnit.NANOSECONDS.toMillis(stop - start); if (!enabled) { return result; } CodeSignature codeSignature = (CodeSignature) joinPoint.getSignature(); Class<?> cls = codeSignature.getDeclaringType(); if (codeSignature instanceof ConstructorSignature) { InitManager.getInstance().addInitMetric(cls, joinPoint.getArgs(), took); } if (isMethodWithReturnType(codeSignature)) { if (result != null) { InitManager.getInstance().addInitMetric(result.getClass(), joinPoint.getArgs(), took); } } return result; } private boolean isMethodWithReturnType(CodeSignature codeSignature) { return codeSignature instanceof MethodSignature && ((MethodSignature) codeSignature).getReturnType() != void.class; } }