?,
+ interceptor: Interceptor,
+ ) {
+ if (interceptors != null && !interceptors.any { interceptor.javaClass.isInstance(it) }) {
+ interceptors.add(0, interceptor)
+ }
+ }
+}
diff --git a/embrace-android-okhttp3/src/main/java/io/embrace/android/embracesdk/okhttp3/swazzle/callback/okhttp3/OkHttpClient.java b/embrace-android-okhttp3/src/main/java/io/embrace/android/embracesdk/okhttp3/swazzle/callback/okhttp3/OkHttpClient.java
deleted file mode 100644
index eb76efdb10..0000000000
--- a/embrace-android-okhttp3/src/main/java/io/embrace/android/embracesdk/okhttp3/swazzle/callback/okhttp3/OkHttpClient.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package io.embrace.android.embracesdk.okhttp3.swazzle.callback.okhttp3;
-
-import java.util.List;
-
-import io.embrace.android.embracesdk.Embrace;
-import io.embrace.android.embracesdk.internal.EmbraceInternalApi;
-import io.embrace.android.embracesdk.okhttp3.EmbraceOkHttp3ApplicationInterceptor;
-import io.embrace.android.embracesdk.okhttp3.EmbraceOkHttp3NetworkInterceptor;
-import okhttp3.Interceptor;
-
-/**
- * Callback hooks for the okhttp3.OkHttpClient class.
- */
-public final class OkHttpClient {
-
- private OkHttpClient() {
- }
-
- public static final class Builder {
-
- private Builder() {
- }
-
- /**
- * As there was a way to clear the injected interceptors during the OkHttpClient
- * initialization using the builder, we are hooking the build method as well, instead of
- * just the Builder constructor.
- *
- * Once the build method is called, OkHTTP mushes everything and returns the OkHttpClient
- * instance, where the developer has no way to alter any of the interceptors during or
- * after this point, without having to rebuild the client.
- */
- @SuppressWarnings("MethodNameCheck")
- public static void _preBuild(okhttp3.OkHttpClient.Builder thiz) {
- addEmbraceInterceptors(thiz);
- }
-
- @SuppressWarnings("MethodNameCheck")
- public static void _constructorOnPostBody(okhttp3.OkHttpClient.Builder thiz) {
- addEmbraceInterceptors(thiz);
- }
-
- /**
- * Adds embrace interceptors if they don't exist already to the OkHTTPClient provided.
- *
- * @param thiz the OkHttpClient builder in matter.
- */
- private static void addEmbraceInterceptors(okhttp3.OkHttpClient.Builder thiz) {
- try {
- addInterceptor(thiz.interceptors(), new EmbraceOkHttp3ApplicationInterceptor(Embrace.getInstance(), EmbraceInternalApi.getInstance()));
- addInterceptor(thiz.networkInterceptors(), new EmbraceOkHttp3NetworkInterceptor(Embrace.getInstance(), EmbraceInternalApi.getInstance()));
- } catch (NoSuchMethodError exception) {
- // The customer may be overwriting OkHttpClient with their own implementation, and some of the
- // methods we use are missing.
- logInternalError(exception);
- } catch (Exception exception) {
- logInternalError(exception);
- }
- }
-
- /**
- * Adds the interceptor to the interceptors list if it doesn't exist already.
- *
- * @param interceptors list of existing interceptors.
- * @param interceptor interceptor to be added.
- */
- private static void addInterceptor(List interceptors,
- Interceptor interceptor) {
- if (interceptors != null && !containsInstance(interceptors, interceptor.getClass())) {
- interceptors.add(0, interceptor);
- }
- }
-
- /**
- * Checks for the existence in the elements list of an instance of the same class as the
- * one provided in the arguments.
- *
- * @param elementsList list of elements.
- * @param clazz class of the instance that's being checked if exists.
- * @return if an instance of the provided class exists in the list of elements.
- */
- private static boolean containsInstance(List elementsList,
- Class extends T> clazz) {
- for (T classInstance : elementsList) {
- if (clazz.isInstance(classInstance)) {
- return true;
- }
- }
- return false;
- }
-
- private static void logInternalError(Throwable throwable) {
- EmbraceInternalApi.getInstance().getInternalInterface().logInternalError(throwable);
- }
- }
-}
diff --git a/embrace-android-sdk/api/embrace-android-sdk.api b/embrace-android-sdk/api/embrace-android-sdk.api
index 8e06c17e74..96a2f21399 100644
--- a/embrace-android-sdk/api/embrace-android-sdk.api
+++ b/embrace-android-sdk/api/embrace-android-sdk.api
@@ -82,18 +82,18 @@ public final class io/embrace/android/embracesdk/Embrace$Companion {
public final fun getInstance ()Lio/embrace/android/embracesdk/Embrace;
}
-public final class io/embrace/android/embracesdk/ViewSwazzledHooks {
+public final class io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnClickBytecodeEntrypoint {
+ public static final field INSTANCE Lio/embrace/android/embracesdk/internal/instrumentation/bytecode/OnClickBytecodeEntrypoint;
+ public static final fun onClick (Landroid/view/View;)V
}
-public final class io/embrace/android/embracesdk/ViewSwazzledHooks$OnClickListener {
- public static fun _preOnClick (Landroid/view/View$OnClickListener;Landroid/view/View;)V
+public final class io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnLongClickBytecodeEntrypoint {
+ public static final field INSTANCE Lio/embrace/android/embracesdk/internal/instrumentation/bytecode/OnLongClickBytecodeEntrypoint;
+ public static final fun onLongClick (Landroid/view/View;)V
}
-public final class io/embrace/android/embracesdk/ViewSwazzledHooks$OnLongClickListener {
- public static fun _preOnLongClick (Landroid/view/View$OnLongClickListener;Landroid/view/View;)V
-}
-
-public final class io/embrace/android/embracesdk/WebViewClientSwazzledHooks {
- public static fun _preOnPageStarted (Landroid/webkit/WebView;Ljava/lang/String;Landroid/graphics/Bitmap;)V
+public final class io/embrace/android/embracesdk/internal/instrumentation/bytecode/WebViewClientBytecodeEntrypoint {
+ public static final field INSTANCE Lio/embrace/android/embracesdk/internal/instrumentation/bytecode/WebViewClientBytecodeEntrypoint;
+ public static final fun onPageStarted (Ljava/lang/String;)V
}
diff --git a/embrace-android-sdk/embrace-proguard.cfg b/embrace-android-sdk/embrace-proguard.cfg
index 024a96b22e..625cbded8e 100644
--- a/embrace-android-sdk/embrace-proguard.cfg
+++ b/embrace-android-sdk/embrace-proguard.cfg
@@ -12,7 +12,6 @@
## Keep classes used by hosted SDKs
-keep class io.embrace.android.embracesdk.Embrace$AppFramework { *; }
-keep class io.embrace.android.embracesdk.Embrace$LastRunEndState { *; }
--keep class io.embrace.android.embracesdk.Severity { *; }
-keep public class * implements io.embrace.android.embracesdk.internal.EmbraceInternalInterface { *; }
## Keep classes used from native code
@@ -25,6 +24,12 @@
-keep class io.embrace.android.embracesdk.internal.anr.ndk.NativeThreadSamplerNdkDelegate { *; }
-keep class io.embrace.android.embracesdk.internal.ndk.jni.JniDelegateImpl { *; }
+## Keep gradle plugin hooks
+-keep class io.embrace.android.embracesdk.internal.config.instrumented.** { *; }
+
+## Keep internal files for tracing
+-keep class io.embrace.android.embracesdk.internal.injection.** { *; }
+
## OpenTelemetry Java SDK
-keep class io.opentelemetry.api.trace.StatusCode { *; }
-dontwarn com.google.auto.value.extension.memoized.Memoized
@@ -46,14 +51,3 @@
-dontwarn com.google.errorprone.annotations.MustBeClosed
-dontwarn com.google.firebase.messaging.RemoteMessage$Notification
-dontwarn com.google.firebase.messaging.RemoteMessage
-
-## Keep gradle plugin hooks
--keep class io.embrace.android.embracesdk.okhttp3.** { *; }
--keep class io.embrace.android.embracesdk.ViewSwazzledHooks { *; }
--keep class io.embrace.android.embracesdk.WebViewClientSwazzledHooks { *; }
--keep class io.embrace.android.embracesdk.WebViewChromeClientSwazzledHooks { *; }
--keep class io.embrace.android.embracesdk.fcm.swazzle.callback.com.android.fcm.FirebaseSwazzledHooks { *; }
--keep class io.embrace.android.embracesdk.internal.config.instrumented.** { *; }
-
-## Keep internal files for tracing
--keep class io.embrace.android.embracesdk.internal.injection.** { *; }
diff --git a/embrace-android-sdk/lint-baseline.xml b/embrace-android-sdk/lint-baseline.xml
index 143e25e8df..8365a556b8 100644
--- a/embrace-android-sdk/lint-baseline.xml
+++ b/embrace-android-sdk/lint-baseline.xml
@@ -1,5 +1,5 @@
-
+
+ errorLine1="public object WebViewClientBytecodeEntrypoint {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ file="src/main/java/io/embrace/android/embracesdk/WebViewClientBytecodeEntrypoint.kt"
+ line="13"
+ column="15"/>
point = null;
- try {
- point = new Pair<>(view.getX(), view.getY());
- } catch (Exception e) {
- point = new Pair<>(0.0F, 0.0F);
- }
- EmbraceInternalApi.getInstance().getInternalInterface().logTap(point, viewName, breadcrumbType);
- } catch (NoSuchMethodError error) {
- // The customer may be overwriting View with their own implementation, and some of the
- // methods we use are missing.
- logError(error);
- } catch (Exception exception) {
- logError(exception);
- }
- }
-
- private static void logError(@NonNull Throwable throwable) {
- EmbraceInternalApi.getInstance().getInternalInterface().logInternalError(throwable);
- }
-
- @InternalApi
- public static final class OnClickListener {
- private OnClickListener() {
- }
-
- @SuppressWarnings("MethodNameCheck")
- public static void _preOnClick(android.view.View.OnClickListener thiz, android.view.View view) {
- logOnClickEvent(view, TapBreadcrumbType.TAP);
- }
- }
-
- @InternalApi
- public static final class OnLongClickListener {
- private OnLongClickListener() {
- }
-
- @SuppressWarnings("MethodNameCheck")
- public static void _preOnLongClick(android.view.View.OnLongClickListener thiz, android.view.View view) {
- if (thiz != null) {
- logOnClickEvent(view, TapBreadcrumbType.LONG_PRESS);
- }
- }
- }
-}
diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/WebViewClientSwazzledHooks.java b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/WebViewClientSwazzledHooks.java
deleted file mode 100644
index a7b03c00a5..0000000000
--- a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/WebViewClientSwazzledHooks.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package io.embrace.android.embracesdk;
-
-import androidx.annotation.Nullable;
-
-import io.embrace.android.embracesdk.annotation.InternalApi;
-
-/**
- * @hide
- */
-@InternalApi
-public final class WebViewClientSwazzledHooks {
-
- private WebViewClientSwazzledHooks() {
- }
-
- @SuppressWarnings("MethodNameCheck")
- public static void _preOnPageStarted(@Nullable android.webkit.WebView view,
- @Nullable java.lang.String url,
- @Nullable android.graphics.Bitmap favicon) {
- Embrace.getInstance().logWebView(url);
- }
-}
diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnClickBytecodeEntrypoint.kt b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnClickBytecodeEntrypoint.kt
new file mode 100644
index 0000000000..ddd164e6bc
--- /dev/null
+++ b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnClickBytecodeEntrypoint.kt
@@ -0,0 +1,20 @@
+package io.embrace.android.embracesdk.internal.instrumentation.bytecode
+
+import android.view.View
+import androidx.annotation.Keep
+import io.embrace.android.embracesdk.annotation.InternalApi
+import io.embrace.android.embracesdk.internal.payload.TapBreadcrumb.TapBreadcrumbType
+
+/**
+ * @hide
+ */
+@InternalApi
+@Keep
+public object OnClickBytecodeEntrypoint {
+
+ @Keep
+ @JvmStatic
+ public fun onClick(view: View) {
+ logTouchEvent(view, TapBreadcrumbType.TAP)
+ }
+}
diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnLongClickBytecodeEntrypoint.kt b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnLongClickBytecodeEntrypoint.kt
new file mode 100644
index 0000000000..e21db4736c
--- /dev/null
+++ b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnLongClickBytecodeEntrypoint.kt
@@ -0,0 +1,20 @@
+package io.embrace.android.embracesdk.internal.instrumentation.bytecode
+
+import android.view.View
+import androidx.annotation.Keep
+import io.embrace.android.embracesdk.annotation.InternalApi
+import io.embrace.android.embracesdk.internal.payload.TapBreadcrumb.TapBreadcrumbType
+
+/**
+ * @hide
+ */
+@InternalApi
+@Keep
+public object OnLongClickBytecodeEntrypoint {
+
+ @Keep
+ @JvmStatic
+ public fun onLongClick(view: View) {
+ logTouchEvent(view, TapBreadcrumbType.LONG_PRESS)
+ }
+}
diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/instrumentation/bytecode/TouchEvent.kt b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/instrumentation/bytecode/TouchEvent.kt
new file mode 100644
index 0000000000..4fcf522fd2
--- /dev/null
+++ b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/instrumentation/bytecode/TouchEvent.kt
@@ -0,0 +1,29 @@
+package io.embrace.android.embracesdk.internal.instrumentation.bytecode
+
+import android.view.View
+import io.embrace.android.embracesdk.internal.EmbraceInternalApi
+import io.embrace.android.embracesdk.internal.payload.TapBreadcrumb.TapBreadcrumbType
+
+private const val UNKNOWN_ELEMENT_NAME = "Unknown element"
+
+internal fun logTouchEvent(view: View, breadcrumbType: TapBreadcrumbType) {
+ try {
+ val viewName = try {
+ view.resources.getResourceName(view.id)
+ } catch (e: Exception) {
+ UNKNOWN_ELEMENT_NAME
+ }
+ val point: Pair = try {
+ Pair(view.x, view.y)
+ } catch (e: Exception) {
+ Pair(0.0f, 0.0f)
+ }
+ EmbraceInternalApi.getInstance().internalInterface.logTap(
+ point,
+ viewName,
+ breadcrumbType
+ )
+ } catch (throwable: Throwable) {
+ EmbraceInternalApi.getInstance().internalInterface.logInternalError(throwable)
+ }
+}
diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/instrumentation/bytecode/WebViewClientBytecodeEntrypoint.kt b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/instrumentation/bytecode/WebViewClientBytecodeEntrypoint.kt
new file mode 100644
index 0000000000..67b68feff6
--- /dev/null
+++ b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/instrumentation/bytecode/WebViewClientBytecodeEntrypoint.kt
@@ -0,0 +1,19 @@
+package io.embrace.android.embracesdk.internal.instrumentation.bytecode
+
+import androidx.annotation.Keep
+import io.embrace.android.embracesdk.Embrace
+import io.embrace.android.embracesdk.annotation.InternalApi
+
+/**
+ * @hide
+ */
+@InternalApi
+@Keep
+public object WebViewClientBytecodeEntrypoint {
+
+ @JvmStatic
+ @Keep
+ public fun onPageStarted(url: String?,) {
+ Embrace.getInstance().logWebView(url)
+ }
+}
diff --git a/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/BytecodeTestParams.kt b/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/BytecodeTestParams.kt
index dadf7323af..83a74ce57f 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/BytecodeTestParams.kt
+++ b/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/BytecodeTestParams.kt
@@ -17,32 +17,32 @@ internal const val ASM_CLASS_READER_FLAGS = ClassReader.EXPAND_FRAMES
// com.android.build.gradle.internal.instrumentation.AsmInstrumentationManager#getClassWriterFlags
internal const val ASM_CLASS_WRITER_FLAGS = ClassWriter.COMPUTE_FRAMES
-internal typealias ClassVisitorFactory = (nextVisitor: ClassVisitor) -> ClassVisitor
+internal typealias ClassVisitorFactory = (nextVisitor: ClassVisitor, params: BytecodeTestParams) -> ClassVisitor
/**
* Test parameters used to instrument bytecode.
*/
class BytecodeTestParams(
- clz: Class<*>,
- val qualifiedClzName: String = clz.name,
- val simpleClzName: String = clz.simpleName,
+ clz: KClass<*>,
+ val qualifiedClzName: String = clz.java.name,
+ val simpleClzName: String = clz.java.simpleName,
val expectedOutput: String = "${simpleClzName}_expected.txt",
- val factory: ClassVisitorFactory = { nextVisitor ->
+ val factory: ClassVisitorFactory = { nextVisitor, _ ->
nextVisitor
- }
+ },
) {
companion object {
fun forInnerClass(
- kClass: KClass<*>,
+ clz: KClass<*>,
innerClzName: String,
- factory: ClassVisitorFactory = { nextVisitor ->
+ factory: ClassVisitorFactory = { nextVisitor, _ ->
nextVisitor
- }
+ },
): BytecodeTestParams {
return BytecodeTestParams(
- kClass.java,
- qualifiedClzName = "${kClass.java.name}$innerClzName",
+ clz,
+ qualifiedClzName = "${clz.java.name}$innerClzName",
factory = factory
)
}
diff --git a/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/FakeBytecodeInstrumentationParams.kt b/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/FakeBytecodeInstrumentationParams.kt
new file mode 100644
index 0000000000..2ee01efd47
--- /dev/null
+++ b/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/FakeBytecodeInstrumentationParams.kt
@@ -0,0 +1,22 @@
+package io.embrace.gradle.plugin.instrumentation
+
+import io.embrace.android.gradle.plugin.instrumentation.BytecodeInstrumentationParams
+import io.embrace.android.gradle.plugin.instrumentation.ClassInstrumentationFilter
+import io.embrace.android.gradle.plugin.instrumentation.config.model.VariantConfig
+import org.gradle.api.provider.Property
+
+class FakeBytecodeInstrumentationParams(
+ override val disabled: Property = fakeProperty(false),
+ override val shouldInstrumentFirebaseMessaging: Property = fakeProperty(false),
+ override val shouldInstrumentWebview: Property = fakeProperty(true),
+ override val shouldInstrumentOkHttp: Property = fakeProperty(true),
+ override val shouldInstrumentOnLongClick: Property = fakeProperty(true),
+ override val shouldInstrumentOnClick: Property = fakeProperty(true),
+) : BytecodeInstrumentationParams {
+ override val config: Property
+ get() = TODO("Not yet implemented")
+ override val encodedSharedObjectFilesMap: Property
+ get() = TODO("Not yet implemented")
+ override val classInstrumentationFilter: Property
+ get() = TODO("Not yet implemented")
+}
diff --git a/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/FakeProperty.kt b/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/FakeProperty.kt
new file mode 100644
index 0000000000..1deedd59ae
--- /dev/null
+++ b/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/FakeProperty.kt
@@ -0,0 +1,12 @@
+package io.embrace.gradle.plugin.instrumentation
+
+import io.mockk.every
+import io.mockk.mockk
+import org.gradle.api.provider.Property
+
+@Suppress("UNCHECKED_CAST")
+fun fakeProperty(value: T): Property {
+ return mockk(relaxed = true) {
+ every { get() } returns value as (T & Any)
+ }
+}
diff --git a/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/InstrumentationRunner.kt b/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/InstrumentationRunner.kt
index 1ff7328d9e..f84f2dce89 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/InstrumentationRunner.kt
+++ b/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/InstrumentationRunner.kt
@@ -21,16 +21,14 @@ object InstrumentationRunner {
* is failed if it differs.
*/
fun runInstrumentationAndCompareOutput(params: BytecodeTestParams) {
- with(params) {
- val output = runInstrumentation(qualifiedClzName, factory)
- assertEquals(
- "The bytecode representation has changed from the known valid " +
- "output. Please confirm whether this is intentional by comparing the " +
- "input/output generated via TraceClassVisitor.",
- loadResourceAsText(expectedOutput),
- sanitizeOutput(output)
- )
- }
+ val output = runInstrumentation(params)
+ assertEquals(
+ "The bytecode representation has changed from the known valid " +
+ "output. Please confirm whether this is intentional by comparing the " +
+ "input/output generated via TraceClassVisitor.",
+ loadResourceAsText(params.expectedOutput),
+ sanitizeOutput(output)
+ )
}
/**
@@ -38,17 +36,16 @@ object InstrumentationRunner {
* the bytecode output.
*/
private fun runInstrumentation(
- fqClzName: String,
- factory: ClassVisitorFactory
+ params: BytecodeTestParams
): String {
- val reader = ClassReader(fqClzName)
+ val reader = ClassReader(params.qualifiedClzName)
val writer = ClassWriter(reader, ASM_CLASS_WRITER_FLAGS)
// visit the class with a TraceClassVisitor which prints a textual representation
// of the generated bytecode.
val stringWriter = StringWriter()
val traceVisitor = TraceClassVisitor(writer, PrintWriter(stringWriter))
- reader.accept(factory(traceVisitor), ASM_CLASS_READER_FLAGS)
+ reader.accept(params.factory(traceVisitor, params), ASM_CLASS_READER_FLAGS)
// perform a sanity check that the bytecode is well-formed
val bytecode = writer.toByteArray()
@@ -61,7 +58,7 @@ object InstrumentationRunner {
/**
* Loads a resource and reads it as a [String].
*/
- fun loadResourceAsText(resName: String): String {
+ private fun loadResourceAsText(resName: String): String {
val classLoader = checkNotNull(javaClass.classLoader)
val res = classLoader.getResourceAsStream(resName)
?: error("Could not find expected fixture resource named '$resName'")
diff --git a/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/InstrumentedBytecodeTest.kt b/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/InstrumentedBytecodeTest.kt
index e7f1c3fe05..3032a2f368 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/InstrumentedBytecodeTest.kt
+++ b/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/InstrumentedBytecodeTest.kt
@@ -1,5 +1,31 @@
package io.embrace.gradle.plugin.instrumentation
+import io.embrace.android.gradle.plugin.instrumentation.VisitorFactoryImpl
+import io.embrace.android.gradle.plugin.instrumentation.json.readBytecodeInstrumentationFeatures
+import io.embrace.test.fixtures.ActivityOnClickListener
+import io.embrace.test.fixtures.AnonInnerClassOnClickListener
+import io.embrace.test.fixtures.AnonInnerClassOnLongClickListener
+import io.embrace.test.fixtures.ControlObject
+import io.embrace.test.fixtures.CustomOnClickListener
+import io.embrace.test.fixtures.CustomOnLongClickListener
+import io.embrace.test.fixtures.CustomWebViewClient
+import io.embrace.test.fixtures.ExtendedCustomWebViewClient
+import io.embrace.test.fixtures.ExtendedOnClickListener
+import io.embrace.test.fixtures.ExtendedOnLongClickListener
+import io.embrace.test.fixtures.FragmentOnClickListener
+import io.embrace.test.fixtures.JavaAnonOnClickListener
+import io.embrace.test.fixtures.JavaLambdaOnClickListener
+import io.embrace.test.fixtures.JavaLambdaOnLongClickListener
+import io.embrace.test.fixtures.JavaNested
+import io.embrace.test.fixtures.KotlinNested
+import io.embrace.test.fixtures.KotlinNestedOnLongClick
+import io.embrace.test.fixtures.KotlinObjectOnClickListener
+import io.embrace.test.fixtures.MissingInterfaceOnClickListener
+import io.embrace.test.fixtures.MissingInterfaceOnLongClickListener
+import io.embrace.test.fixtures.MissingOverrideOnClickListener
+import io.embrace.test.fixtures.MissingOverrideOnLongClickListener
+import io.embrace.test.fixtures.NoOverrideWebViewClient
+import io.embrace.test.fixtures.VirtualMethodRefNamedOnClick
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
@@ -7,12 +33,44 @@ import org.objectweb.asm.ClassReader
import org.objectweb.asm.ClassVisitor
import org.objectweb.asm.util.TraceClassVisitor
+private val features = readBytecodeInstrumentationFeatures()
+private val factory = VisitorFactoryImpl(ASM_API_VERSION, FakeBytecodeInstrumentationParams())
+
+private fun createFactory(
+ params: BytecodeTestParams,
+ visitor: ClassVisitor,
+ name: String,
+ superClassName: String? = null,
+): ClassVisitor {
+ val superClasses = when (superClassName) {
+ null -> emptyList()
+ else -> listOf(superClassName)
+ }
+ return factory.createClassVisitor(
+ feature = features.single { it.name == name },
+ classContext = FakeClassContext(FakeClassData(className = params.qualifiedClzName, superClasses = superClasses)),
+ nextVisitor = visitor
+ )
+}
+
+private val onClickFactory: ClassVisitorFactory = { visitor, params ->
+ createFactory(params, visitor, "on_click")
+}
+
+private val onLongClickFactory: ClassVisitorFactory = { visitor, params ->
+ createFactory(params, visitor, "on_long_click")
+}
+
+private val webviewFactory: ClassVisitorFactory = { visitor, params ->
+ createFactory(params, visitor, "webview_page_start", "android.webkit.WebViewClient")
+}
+
/**
* Verifies that a [ClassVisitor] produces the correct bytecode output for a given class.
*
- * For example, if a class implements [View.OnClickListener] then the embrace gradle plugin should
- * instrument the bytecode so that the first line of the onClick method contains a call to
- * [ViewSwazzledHooks._preOnClick]. If a class does not implement the interface, then its
+ * For example, if a class implements View.OnClickListener then the embrace gradle plugin should
+ * instrument the bytecode so that the first line of the onClick method contains a call to our API
+ * If a class does not implement the interface, then its
* bytecode should remain the same.
*
* The test achieves this verification using the following approach:
@@ -22,22 +80,54 @@ import org.objectweb.asm.util.TraceClassVisitor
* 3. Process the class using the [ClassVisitor] instance that instruments the bytecode
* 4. Compare the bytecode representation obtained from a [TraceClassVisitor] with a known output
*
- * To add more test cases please use [instrumentedBytecodeTestCases] and read the README.
- *
* For more information on WebObject ASM, see https://asm.ow2.io/
*/
@RunWith(Parameterized::class)
class InstrumentedBytecodeTest(
- private val params: BytecodeTestParams
+ private val params: BytecodeTestParams,
) {
- /**
- * To add more test cases please use [instrumentedBytecodeTestCases] and read the README.
- */
companion object {
+
@JvmStatic
@Parameterized.Parameters(name = "{index}: {0}")
- fun testCases() = instrumentedBytecodeTestCases()
+ fun testCases() = listOf(
+ BytecodeTestParams(clz = ActivityOnClickListener::class, factory = onClickFactory),
+ BytecodeTestParams(clz = ControlObject::class, factory = onClickFactory),
+ BytecodeTestParams(clz = CustomOnClickListener::class, factory = onClickFactory),
+ BytecodeTestParams(clz = ExtendedOnClickListener::class, factory = onClickFactory),
+ BytecodeTestParams(clz = FragmentOnClickListener::class, factory = onClickFactory),
+ BytecodeTestParams(clz = JavaNested.JavaInnerListener::class, factory = onClickFactory),
+ BytecodeTestParams(clz = JavaNested.JavaStaticListener::class, factory = onClickFactory),
+ BytecodeTestParams(clz = KotlinNested.KotlinInnerListener::class, factory = onClickFactory),
+ BytecodeTestParams(clz = KotlinNested.KotlinStaticListener::class, factory = onClickFactory),
+ BytecodeTestParams(clz = MissingInterfaceOnClickListener::class, factory = onClickFactory),
+ BytecodeTestParams(clz = MissingOverrideOnClickListener::class, factory = onClickFactory),
+ BytecodeTestParams(clz = VirtualMethodRefNamedOnClick::class, factory = onClickFactory),
+ BytecodeTestParams(clz = JavaLambdaOnClickListener::class, factory = onClickFactory),
+ BytecodeTestParams.forInnerClass(clz = AnonInnerClassOnClickListener::class, innerClzName = "$1", factory = onClickFactory),
+ BytecodeTestParams.forInnerClass(clz = JavaAnonOnClickListener::class, innerClzName = "$1", factory = onClickFactory),
+ BytecodeTestParams.forInnerClass(
+ clz = KotlinObjectOnClickListener::class,
+ innerClzName = "\$onCreateView\$1",
+ factory = onClickFactory
+ ),
+ BytecodeTestParams(clz = CustomOnLongClickListener::class, factory = onLongClickFactory),
+ BytecodeTestParams(clz = ExtendedOnLongClickListener::class, factory = onLongClickFactory),
+ BytecodeTestParams(clz = JavaLambdaOnLongClickListener::class, factory = onLongClickFactory),
+ BytecodeTestParams(clz = KotlinNestedOnLongClick.OnLongClickInnerListener::class, factory = onLongClickFactory),
+ BytecodeTestParams(clz = KotlinNestedOnLongClick.OnLongClickStaticListener::class, factory = onLongClickFactory),
+ BytecodeTestParams(clz = MissingInterfaceOnLongClickListener::class, factory = onLongClickFactory),
+ BytecodeTestParams(clz = MissingOverrideOnLongClickListener::class, factory = onLongClickFactory),
+ BytecodeTestParams.forInnerClass(
+ clz = AnonInnerClassOnLongClickListener::class,
+ innerClzName = "$1",
+ factory = onLongClickFactory
+ ),
+ BytecodeTestParams(clz = CustomWebViewClient::class, factory = webviewFactory),
+ BytecodeTestParams(clz = ExtendedCustomWebViewClient::class, factory = webviewFactory),
+ BytecodeTestParams(clz = NoOverrideWebViewClient::class, factory = webviewFactory),
+ )
}
@Test
diff --git a/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/InstrumentedBytecodeTestCases.kt b/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/InstrumentedBytecodeTestCases.kt
deleted file mode 100644
index 029944cdd3..0000000000
--- a/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/InstrumentedBytecodeTestCases.kt
+++ /dev/null
@@ -1,134 +0,0 @@
-package io.embrace.gradle.plugin.instrumentation
-
-import io.embrace.android.gradle.plugin.instrumentation.visitor.OkHttpClassAdapter
-import io.embrace.android.gradle.plugin.instrumentation.visitor.OnClickClassAdapter
-import io.embrace.android.gradle.plugin.instrumentation.visitor.OnLongClickClassAdapter
-import io.embrace.android.gradle.plugin.instrumentation.visitor.WebViewClientClassAdapter
-import io.embrace.test.fixtures.ActivityOnClickListener
-import io.embrace.test.fixtures.AnonInnerClassOnClickListener
-import io.embrace.test.fixtures.AnonInnerClassOnLongClickListener
-import io.embrace.test.fixtures.ControlObject
-import io.embrace.test.fixtures.CustomOnClickListener
-import io.embrace.test.fixtures.CustomOnLongClickListener
-import io.embrace.test.fixtures.CustomWebViewClient
-import io.embrace.test.fixtures.ExtendedCustomWebViewClient
-import io.embrace.test.fixtures.ExtendedOnClickListener
-import io.embrace.test.fixtures.ExtendedOnLongClickListener
-import io.embrace.test.fixtures.FragmentOnClickListener
-import io.embrace.test.fixtures.JavaAnonOnClickListener
-import io.embrace.test.fixtures.JavaLambdaOnClickListener
-import io.embrace.test.fixtures.JavaLambdaOnLongClickListener
-import io.embrace.test.fixtures.JavaNested
-import io.embrace.test.fixtures.KotlinNested
-import io.embrace.test.fixtures.KotlinNestedOnLongClick
-import io.embrace.test.fixtures.KotlinObjectOnClickListener
-import io.embrace.test.fixtures.MissingInterfaceOnClickListener
-import io.embrace.test.fixtures.MissingInterfaceOnLongClickListener
-import io.embrace.test.fixtures.MissingOverrideOnClickListener
-import io.embrace.test.fixtures.MissingOverrideOnLongClickListener
-import io.embrace.test.fixtures.NoOverrideWebViewClient
-import io.embrace.test.fixtures.VirtualMethodRefNamedOnClick
-import okhttp3.OkHttpClient
-import org.objectweb.asm.ClassVisitor
-
-private val onClickFactory: ClassVisitorFactory = { visitor ->
- OnClickClassAdapter(ASM_API_VERSION, visitor) {}
-}
-
-private val onLongClickFactory: ClassVisitorFactory = { visitor ->
- OnLongClickClassAdapter(ASM_API_VERSION, visitor) {}
-}
-
-private val webviewFactory: ClassVisitorFactory = { visitor ->
- WebViewClientClassAdapter(ASM_API_VERSION, visitor) {}
-}
-
-private val okHttpFactory: ClassVisitorFactory = { visitor ->
- OkHttpClassAdapter(ASM_API_VERSION, visitor) {}
-}
-
-/**
- * Declares the test cases for bytecode in [InstrumentedBytecodeTest]. You should define the
- * input class, the expected output, and the [ClassVisitor] which will instrument the bytecode.
- *
- * After doing that, [InstrumentedBytecodeTest] will perform all the necessary checks automatically!
- */
-internal fun instrumentedBytecodeTestCases(): List {
- return onClickTestCases
- .plus(onClickInnerTestCases)
- .plus(onLongClickTestCases)
- .plus(onLongClickInnerTestCases)
- .plus(webclientTestCases)
- .plus(okHttpTestCases)
- .distinct() // filter out any unintentional duplicate test cases
- .sortedBy(BytecodeTestParams::simpleClzName)
-}
-
-private val okHttpTestCases = listOf(
- OkHttpClient.Builder::class
-).map {
- BytecodeTestParams(it.java, factory = okHttpFactory)
-}
-private val webclientTestCases = listOf(
- CustomWebViewClient::class,
- ExtendedCustomWebViewClient::class,
- NoOverrideWebViewClient::class
-).map {
- BytecodeTestParams(it.java, factory = webviewFactory)
-}
-
-private val onClickTestCases = listOf(
- ActivityOnClickListener::class,
- ControlObject::class,
- CustomOnClickListener::class,
- ExtendedOnClickListener::class,
- FragmentOnClickListener::class,
- JavaNested.JavaInnerListener::class,
- JavaNested.JavaStaticListener::class,
- KotlinNested.KotlinInnerListener::class,
- KotlinNested.KotlinStaticListener::class,
- MissingInterfaceOnClickListener::class,
- MissingOverrideOnClickListener::class,
- VirtualMethodRefNamedOnClick::class,
- JavaLambdaOnClickListener::class,
-).map { clz ->
- BytecodeTestParams(clz.java, factory = onClickFactory)
-}
-
-private val onClickInnerTestCases = listOf(
- BytecodeTestParams.forInnerClass(
- AnonInnerClassOnClickListener::class,
- "$1",
- factory = onClickFactory
- ),
- BytecodeTestParams.forInnerClass(
- JavaAnonOnClickListener::class,
- "$1",
- factory = onClickFactory
- ),
- BytecodeTestParams.forInnerClass(
- KotlinObjectOnClickListener::class,
- "\$onCreateView$1",
- factory = onClickFactory
- )
-)
-
-private val onLongClickTestCases = listOf(
- CustomOnLongClickListener::class,
- ExtendedOnLongClickListener::class,
- JavaLambdaOnLongClickListener::class,
- KotlinNestedOnLongClick.OnLongClickInnerListener::class,
- KotlinNestedOnLongClick.OnLongClickStaticListener::class,
- MissingInterfaceOnLongClickListener::class,
- MissingOverrideOnLongClickListener::class,
-).map { clz ->
- BytecodeTestParams(clz.java, factory = onLongClickFactory)
-}
-
-private val onLongClickInnerTestCases = listOf(
- BytecodeTestParams.forInnerClass(
- AnonInnerClassOnLongClickListener::class,
- "$1",
- factory = onLongClickFactory
- )
-)
diff --git a/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/MethodReturnValueVisitorTest.kt b/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/MethodReturnValueVisitorTest.kt
index fbba8eab03..c1d91ef951 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/MethodReturnValueVisitorTest.kt
+++ b/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/MethodReturnValueVisitorTest.kt
@@ -30,7 +30,7 @@ class MethodReturnValueVisitorTest {
@Test
fun `instrument bytecode`() {
- val params = BytecodeTestParams(MethodReturnValueVisitorObj::class.java) { nextVisitor ->
+ val params = BytecodeTestParams(MethodReturnValueVisitorObj::class) { nextVisitor, _ ->
TestClassVisitor(ASM_API_VERSION, nextVisitor)
}
InstrumentationRunner.runInstrumentationAndCompareOutput(params)
@@ -74,7 +74,7 @@ class MethodReturnValueVisitorTest {
} else if (name == STRING_METHOD_NAME && descriptor == STRING_METHOD_DESCRIPTOR) {
return StringReturnValueMethodVisitor("Hello world! I'm a string.", api, nextVisitor)
} else if (name == LIST_METHOD_NAME && descriptor == LIST_METHOD_DESCRIPTOR) {
- return io.embrace.android.gradle.plugin.instrumentation.config.StringListReturnValueMethodVisitor(
+ return StringListReturnValueMethodVisitor(
listOf("adam aardvark", "bob banana"),
api,
nextVisitor
diff --git a/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/OkHttpClassFilterTest.kt b/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/OkHttpClassFilterTest.kt
deleted file mode 100644
index 1d7393a5c5..0000000000
--- a/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/OkHttpClassFilterTest.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-package io.embrace.gradle.plugin.instrumentation
-
-import io.embrace.android.gradle.plugin.instrumentation.visitor.OkHttpClassAdapter
-import org.junit.Assert.assertFalse
-import org.junit.Assert.assertTrue
-import org.junit.Test
-
-class OkHttpClassFilterTest {
-
- @Test
- fun testClassAccepted() {
- val ctx = FakeClassContext("okhttp3.OkHttpClient\$Builder")
- assertTrue(OkHttpClassAdapter.accept(ctx))
- }
-
- @Test
- fun testClassNotAccepted() {
- val ctx = FakeClassContext("okhttp3.OkHttpClient")
- assertFalse(OkHttpClassAdapter.accept(ctx))
- }
-}
diff --git a/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/OnClickClassFilterTest.kt b/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/OnClickClassFilterTest.kt
deleted file mode 100644
index de82b2d820..0000000000
--- a/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/OnClickClassFilterTest.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package io.embrace.gradle.plugin.instrumentation
-
-import io.embrace.android.gradle.plugin.instrumentation.visitor.OnClickClassAdapter
-import org.junit.Assert.assertTrue
-import org.junit.Test
-
-class OnClickClassFilterTest {
-
- @Test
- fun testClassAccepted() {
- val ctx = FakeClassContext("org/test/FooBar")
- assertTrue(OnClickClassAdapter.accept(ctx))
- }
-}
diff --git a/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/WebViewClassFilterTest.kt b/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/WebViewClassFilterTest.kt
deleted file mode 100644
index 56e999e512..0000000000
--- a/embrace-bytecode-instrumentation-tests/src/test/java/io/embrace/gradle/plugin/instrumentation/WebViewClassFilterTest.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-package io.embrace.gradle.plugin.instrumentation
-
-import io.embrace.android.gradle.plugin.instrumentation.visitor.WebViewClientClassAdapter
-import org.junit.Assert.assertFalse
-import org.junit.Assert.assertTrue
-import org.junit.Test
-
-class WebViewClassFilterTest {
-
- @Test
- fun testClassAccepted() {
- val ctx = FakeClassContext(
- FakeClassData(
- "",
- superClasses = listOf("android.webkit.WebViewClient")
- )
- )
- assertTrue(WebViewClientClassAdapter.accept(ctx))
- }
-
- @Test
- fun testClassNotAccepted() {
- val ctx = FakeClassContext(
- FakeClassData(
- "",
- superClasses = emptyList()
- )
- )
- assertFalse(WebViewClientClassAdapter.accept(ctx))
- }
-}
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/ActivityOnClickListener_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/ActivityOnClickListener_expected.txt
index 960ea3da79..0d3f0dc607 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/ActivityOnClickListener_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/ActivityOnClickListener_expected.txt
@@ -20,9 +20,8 @@ public class io/embrace/test/fixtures/ActivityOnClickListener extends androidx/a
// access flags 0x1
public onClick(Landroid/view/View;)V
- ALOAD 0
ALOAD 1
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnClickListener._preOnClick (Landroid/view/View$OnClickListener;Landroid/view/View;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnClickBytecodeEntrypoint.onClick (Landroid/view/View;)V
L0
LINENUMBER 14 L0
RETURN
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/AnonInnerClassOnClickListener_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/AnonInnerClassOnClickListener_expected.txt
index 96c8748be1..8a7eb82ee8 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/AnonInnerClassOnClickListener_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/AnonInnerClassOnClickListener_expected.txt
@@ -31,9 +31,8 @@ class io/embrace/test/fixtures/AnonInnerClassOnClickListener$1 implements androi
// access flags 0x1
public onClick(Landroid/view/View;)V
- ALOAD 0
ALOAD 1
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnClickListener._preOnClick (Landroid/view/View$OnClickListener;Landroid/view/View;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnClickBytecodeEntrypoint.onClick (Landroid/view/View;)V
L0
LINENUMBER 14 L0
RETURN
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/AnonInnerClassOnLongClickListener_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/AnonInnerClassOnLongClickListener_expected.txt
index 679e21da83..c9aff02571 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/AnonInnerClassOnLongClickListener_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/AnonInnerClassOnLongClickListener_expected.txt
@@ -31,9 +31,8 @@ class io/embrace/test/fixtures/AnonInnerClassOnLongClickListener$1 implements an
// access flags 0x1
public onLongClick(Landroid/view/View;)Z
- ALOAD 0
ALOAD 1
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnLongClickListener._preOnLongClick (Landroid/view/View$OnLongClickListener;Landroid/view/View;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnLongClickBytecodeEntrypoint.onLongClick (Landroid/view/View;)V
L0
LINENUMBER 13 L0
ICONST_0
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/Builder_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/Builder_expected.txt
index dbe58cf7f2..ed4f2abe94 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/Builder_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/Builder_expected.txt
@@ -3380,7 +3380,7 @@ kotlin/jvm/internal/FakeKt
public final build()Lokhttp3/OkHttpClient;
@Lorg/jetbrains/annotations/NotNull;() // invisible
ALOAD 0
- INVOKESTATIC io/embrace/android/embracesdk/okhttp3/swazzle/callback/okhttp3/OkHttpClient$Builder._preBuild (Lokhttp3/OkHttpClient$Builder;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/OkHttpBytecodeEntrypoint.build (Lokhttp3/OkHttpClient$Builder;)V
L0
LINENUMBER 1069 L0
NEW okhttp3/OkHttpClient
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/CustomOnClickListener_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/CustomOnClickListener_expected.txt
index c5c98e969f..2f3eacef25 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/CustomOnClickListener_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/CustomOnClickListener_expected.txt
@@ -24,9 +24,8 @@ public class io/embrace/test/fixtures/CustomOnClickListener implements android/v
public onClick(Landroid/view/View;)V
// annotable parameter count: 1 (invisible)
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
- ALOAD 0
ALOAD 1
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnClickListener._preOnClick (Landroid/view/View$OnClickListener;Landroid/view/View;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnClickBytecodeEntrypoint.onClick (Landroid/view/View;)V
L0
ALOAD 1
LDC "view"
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/CustomOnLongClickListener_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/CustomOnLongClickListener_expected.txt
index 593f8d7403..a450ac7261 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/CustomOnLongClickListener_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/CustomOnLongClickListener_expected.txt
@@ -24,9 +24,8 @@ public class io/embrace/test/fixtures/CustomOnLongClickListener implements andro
public onLongClick(Landroid/view/View;)Z
// annotable parameter count: 1 (invisible)
@Lorg/jetbrains/annotations/Nullable;() // invisible, parameter 0
- ALOAD 0
ALOAD 1
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnLongClickListener._preOnLongClick (Landroid/view/View$OnLongClickListener;Landroid/view/View;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnLongClickBytecodeEntrypoint.onLongClick (Landroid/view/View;)V
L0
LINENUMBER 11 L0
ALOAD 1
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/CustomWebViewClient_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/CustomWebViewClient_expected.txt
index a62fc6a188..11ff463a10 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/CustomWebViewClient_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/CustomWebViewClient_expected.txt
@@ -24,10 +24,8 @@ public class io/embrace/test/fixtures/CustomWebViewClient extends android/webkit
@Lorg/jetbrains/annotations/Nullable;() // invisible, parameter 0
@Lorg/jetbrains/annotations/Nullable;() // invisible, parameter 1
@Lorg/jetbrains/annotations/Nullable;() // invisible, parameter 2
- ALOAD 1
ALOAD 2
- ALOAD 3
- INVOKESTATIC io/embrace/android/embracesdk/WebViewClientSwazzledHooks._preOnPageStarted (Landroid/webkit/WebView;Ljava/lang/String;Landroid/graphics/Bitmap;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/WebViewClientBytecodeEntrypoint.onPageStarted (Ljava/lang/String;)V
L0
LINENUMBER 10 L0
ALOAD 0
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/ExtendedCustomWebViewClient_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/ExtendedCustomWebViewClient_expected.txt
index e528f1d770..7a4996c4a2 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/ExtendedCustomWebViewClient_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/ExtendedCustomWebViewClient_expected.txt
@@ -24,10 +24,8 @@ public final class io/embrace/test/fixtures/ExtendedCustomWebViewClient extends
@Lorg/jetbrains/annotations/Nullable;() // invisible, parameter 0
@Lorg/jetbrains/annotations/Nullable;() // invisible, parameter 1
@Lorg/jetbrains/annotations/Nullable;() // invisible, parameter 2
- ALOAD 1
ALOAD 2
- ALOAD 3
- INVOKESTATIC io/embrace/android/embracesdk/WebViewClientSwazzledHooks._preOnPageStarted (Landroid/webkit/WebView;Ljava/lang/String;Landroid/graphics/Bitmap;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/WebViewClientBytecodeEntrypoint.onPageStarted (Ljava/lang/String;)V
L0
LINENUMBER 8 L0
ALOAD 0
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/ExtendedOnClickListener_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/ExtendedOnClickListener_expected.txt
index 47aa4f7241..c9cb791419 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/ExtendedOnClickListener_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/ExtendedOnClickListener_expected.txt
@@ -20,9 +20,8 @@ public class io/embrace/test/fixtures/ExtendedOnClickListener extends io/embrace
public onClick(Landroid/view/View;)V
// annotable parameter count: 1 (invisible)
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
- ALOAD 0
ALOAD 1
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnClickListener._preOnClick (Landroid/view/View$OnClickListener;Landroid/view/View;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnClickBytecodeEntrypoint.onClick (Landroid/view/View;)V
L0
LINENUMBER 16 L0
ALOAD 0
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/ExtendedOnLongClickListener_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/ExtendedOnLongClickListener_expected.txt
index ab59254080..d7dd9b8be6 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/ExtendedOnLongClickListener_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/ExtendedOnLongClickListener_expected.txt
@@ -20,9 +20,8 @@ public class io/embrace/test/fixtures/ExtendedOnLongClickListener extends io/emb
public onLongClick(Landroid/view/View;)Z
// annotable parameter count: 1 (invisible)
@Landroidx/annotation/Nullable;() // invisible, parameter 0
- ALOAD 0
ALOAD 1
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnLongClickListener._preOnLongClick (Landroid/view/View$OnLongClickListener;Landroid/view/View;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnLongClickBytecodeEntrypoint.onLongClick (Landroid/view/View;)V
L0
LINENUMBER 17 L0
ALOAD 1
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/FragmentOnClickListener_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/FragmentOnClickListener_expected.txt
index 1c336d93a5..9ed379c607 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/FragmentOnClickListener_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/FragmentOnClickListener_expected.txt
@@ -26,9 +26,8 @@ public final class io/embrace/test/fixtures/FragmentOnClickListener extends andr
public onClick(Landroid/view/View;)V
// annotable parameter count: 1 (invisible)
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
- ALOAD 0
ALOAD 1
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnClickListener._preOnClick (Landroid/view/View$OnClickListener;Landroid/view/View;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnClickBytecodeEntrypoint.onClick (Landroid/view/View;)V
L0
ALOAD 1
LDC "view"
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/JavaAnonOnClickListener_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/JavaAnonOnClickListener_expected.txt
index 5ffa8d6ff0..1216e9d0f4 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/JavaAnonOnClickListener_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/JavaAnonOnClickListener_expected.txt
@@ -31,9 +31,8 @@ class io/embrace/test/fixtures/JavaAnonOnClickListener$1 implements android/view
// access flags 0x1
public onClick(Landroid/view/View;)V
- ALOAD 0
ALOAD 1
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnClickListener._preOnClick (Landroid/view/View$OnClickListener;Landroid/view/View;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnClickBytecodeEntrypoint.onClick (Landroid/view/View;)V
L0
LINENUMBER 25 L0
LDC "Embrace"
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/JavaInnerListener_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/JavaInnerListener_expected.txt
index 2a91b24faf..503132c372 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/JavaInnerListener_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/JavaInnerListener_expected.txt
@@ -30,9 +30,8 @@ public class io/embrace/test/fixtures/JavaNested$JavaInnerListener implements an
// access flags 0x1
public onClick(Landroid/view/View;)V
- ALOAD 0
ALOAD 1
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnClickListener._preOnClick (Landroid/view/View$OnClickListener;Landroid/view/View;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnClickBytecodeEntrypoint.onClick (Landroid/view/View;)V
L0
LINENUMBER 15 L0
RETURN
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/JavaLambdaOnClickListener_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/JavaLambdaOnClickListener_expected.txt
index 015abdecb2..251d0fca08 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/JavaLambdaOnClickListener_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/JavaLambdaOnClickListener_expected.txt
@@ -65,9 +65,6 @@ public class io/embrace/test/fixtures/JavaLambdaOnClickListener extends androidx
// access flags 0x100A
private static synthetic lambda$onCreateView$0(Landroid/view/View;)V
- ACONST_NULL
- ALOAD 0
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnClickListener._preOnClick (Landroid/view/View$OnClickListener;Landroid/view/View;)V
L0
LINENUMBER 22 L0
LDC "Embrace"
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/JavaLambdaOnLongClickListener_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/JavaLambdaOnLongClickListener_expected.txt
index 4dea0c5f0a..ef12ed6c6f 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/JavaLambdaOnLongClickListener_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/JavaLambdaOnLongClickListener_expected.txt
@@ -65,9 +65,6 @@ public class io/embrace/test/fixtures/JavaLambdaOnLongClickListener extends andr
// access flags 0x100A
private static synthetic lambda$onCreateView$0(Landroid/view/View;)Z
- ACONST_NULL
- ALOAD 0
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnLongClickListener._preOnLongClick (Landroid/view/View$OnLongClickListener;Landroid/view/View;)V
L0
LINENUMBER 22 L0
LDC "Embrace"
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/JavaStaticListener_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/JavaStaticListener_expected.txt
index d515cafae0..1a2efcdd74 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/JavaStaticListener_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/JavaStaticListener_expected.txt
@@ -23,9 +23,8 @@ public class io/embrace/test/fixtures/JavaNested$JavaStaticListener implements a
// access flags 0x1
public onClick(Landroid/view/View;)V
- ALOAD 0
ALOAD 1
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnClickListener._preOnClick (Landroid/view/View$OnClickListener;Landroid/view/View;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnClickBytecodeEntrypoint.onClick (Landroid/view/View;)V
L0
LINENUMBER 22 L0
RETURN
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinInnerListener_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinInnerListener_expected.txt
index 690d89a6f5..6c64da69bf 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinInnerListener_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinInnerListener_expected.txt
@@ -35,9 +35,8 @@ public final class io/embrace/test/fixtures/KotlinNested$KotlinInnerListener imp
public onClick(Landroid/view/View;)V
// annotable parameter count: 1 (invisible)
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
- ALOAD 0
ALOAD 1
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnClickListener._preOnClick (Landroid/view/View$OnClickListener;Landroid/view/View;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnClickBytecodeEntrypoint.onClick (Landroid/view/View;)V
L0
ALOAD 1
LDC "view"
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinLambdaOnClickListener_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinLambdaOnClickListener_expected.txt
index 621424d627..e024b6230b 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinLambdaOnClickListener_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinLambdaOnClickListener_expected.txt
@@ -27,7 +27,7 @@ public final class io/embrace/test/fixtures/KotlinObjectOnClickListener$onCreate
@Lorg/jetbrains/annotations/Nullable;() // invisible, parameter 0
ALOAD 0
ALOAD 1
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnClickListener._preOnClick (Landroid/view/View$OnClickListener;Landroid/view/View;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnClickBytecodeEntrypoint.onClick (Landroid/view/View;)V
L0
LINENUMBER 20 L0
RETURN
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinLambdaOnLongClickListener_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinLambdaOnLongClickListener_expected.txt
index 7e70f9dcae..9b740d3f48 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinLambdaOnLongClickListener_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinLambdaOnLongClickListener_expected.txt
@@ -16,7 +16,7 @@ final class io/embrace/test/fixtures/KotlinLambdaOnLongClickListener$onCreateVie
public final onLongClick(Landroid/view/View;)Z
ALOAD 0
ALOAD 1
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnLongClickListener._preOnLongClick (Landroid/view/View$OnLongClickListener;Landroid/view/View;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnLongClickBytecodeEntrypoint.onLongClick (Landroid/view/View;)V
L0
LINENUMBER 18 L0
ICONST_0
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinMethodRef2OnClickListener_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinMethodRef2OnClickListener_expected.txt
index 3f1b43ad6d..080eded371 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinMethodRef2OnClickListener_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinMethodRef2OnClickListener_expected.txt
@@ -24,7 +24,7 @@ final class io/embrace/test/fixtures/KotlinMethodRef2OnClickListener$sam$android
public final synthetic onClick(Landroid/view/View;)V
ALOAD 0
ALOAD 1
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnClickListener._preOnClick (Landroid/view/View$OnClickListener;Landroid/view/View;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnClickBytecodeEntrypoint.onClick (Landroid/view/View;)V
L0
ALOAD 0
GETFIELD io/embrace/test/fixtures/KotlinMethodRef2OnClickListener$sam$android_view_View_OnClickListener$0.function : Lkotlin/jvm/functions/Function1;
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinMethodRefOnClickListener_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinMethodRefOnClickListener_expected.txt
index 6faa88a798..6cc2f4da34 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinMethodRefOnClickListener_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinMethodRefOnClickListener_expected.txt
@@ -24,7 +24,7 @@ final class io/embrace/test/fixtures/KotlinMethodRefOnClickListener$sam$android_
public final synthetic onClick(Landroid/view/View;)V
ALOAD 0
ALOAD 1
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnClickListener._preOnClick (Landroid/view/View$OnClickListener;Landroid/view/View;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnClickBytecodeEntrypoint.onClick (Landroid/view/View;)V
L0
ALOAD 0
GETFIELD io/embrace/test/fixtures/KotlinMethodRefOnClickListener$sam$android_view_View_OnClickListener$0.function : Lkotlin/jvm/functions/Function1;
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinMethodRefOnLongClickListener_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinMethodRefOnLongClickListener_expected.txt
index 7d89a000c6..ccd07a1052 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinMethodRefOnLongClickListener_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinMethodRefOnLongClickListener_expected.txt
@@ -24,7 +24,7 @@ final class io/embrace/test/fixtures/KotlinMethodRefOnLongClickListener$sam$andr
public final synthetic onLongClick(Landroid/view/View;)Z
ALOAD 0
ALOAD 1
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnLongClickListener._preOnLongClick (Landroid/view/View$OnLongClickListener;Landroid/view/View;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnLongClickBytecodeEntrypoint.onLongClick (Landroid/view/View;)V
L0
ALOAD 0
GETFIELD io/embrace/test/fixtures/KotlinMethodRefOnLongClickListener$sam$android_view_View_OnLongClickListener$0.function : Lkotlin/jvm/functions/Function1;
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinObjectOnClickListener_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinObjectOnClickListener_expected.txt
index 6163eca7db..b1073bb2cf 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinObjectOnClickListener_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinObjectOnClickListener_expected.txt
@@ -25,9 +25,8 @@ public final class io/embrace/test/fixtures/KotlinObjectOnClickListener$onCreate
// access flags 0x1
public onClick(Landroid/view/View;)V
- ALOAD 0
ALOAD 1
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnClickListener._preOnClick (Landroid/view/View$OnClickListener;Landroid/view/View;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnClickBytecodeEntrypoint.onClick (Landroid/view/View;)V
L0
LINENUMBER 19 L0
RETURN
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinStaticListener_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinStaticListener_expected.txt
index b6b0fbd4e7..8d8c515039 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinStaticListener_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/KotlinStaticListener_expected.txt
@@ -26,9 +26,8 @@ public final class io/embrace/test/fixtures/KotlinNested$KotlinStaticListener im
public onClick(Landroid/view/View;)V
// annotable parameter count: 1 (invisible)
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
- ALOAD 0
ALOAD 1
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnClickListener._preOnClick (Landroid/view/View$OnClickListener;Landroid/view/View;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnClickBytecodeEntrypoint.onClick (Landroid/view/View;)V
L0
ALOAD 1
LDC "view"
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/MissingInterfaceOnClickListener_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/MissingInterfaceOnClickListener_expected.txt
index 1832e100dd..2f7dc83e18 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/MissingInterfaceOnClickListener_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/MissingInterfaceOnClickListener_expected.txt
@@ -18,9 +18,8 @@ public class io/embrace/test/fixtures/MissingInterfaceOnClickListener {
// access flags 0x1
public onClick(Landroid/view/View;)V
- ALOAD 0
ALOAD 1
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnClickListener._preOnClick (Landroid/view/View$OnClickListener;Landroid/view/View;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnClickBytecodeEntrypoint.onClick (Landroid/view/View;)V
L0
LINENUMBER 11 L0
RETURN
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/MissingInterfaceOnLongClickListener_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/MissingInterfaceOnLongClickListener_expected.txt
index 2b608e943f..998d17c080 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/MissingInterfaceOnLongClickListener_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/MissingInterfaceOnLongClickListener_expected.txt
@@ -18,9 +18,8 @@ public class io/embrace/test/fixtures/MissingInterfaceOnLongClickListener {
// access flags 0x1
public onLongClick(Landroid/view/View;)Z
- ALOAD 0
ALOAD 1
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnLongClickListener._preOnLongClick (Landroid/view/View$OnLongClickListener;Landroid/view/View;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnLongClickBytecodeEntrypoint.onLongClick (Landroid/view/View;)V
L0
LINENUMBER 10 L0
ICONST_1
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/MissingOverrideOnClickListener_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/MissingOverrideOnClickListener_expected.txt
index 1ce673c9a2..de43a69d27 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/MissingOverrideOnClickListener_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/MissingOverrideOnClickListener_expected.txt
@@ -20,9 +20,8 @@ public class io/embrace/test/fixtures/MissingOverrideOnClickListener implements
// access flags 0x1
public onClick(Landroid/view/View;)V
- ALOAD 0
ALOAD 1
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnClickListener._preOnClick (Landroid/view/View$OnClickListener;Landroid/view/View;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnClickBytecodeEntrypoint.onClick (Landroid/view/View;)V
L0
LINENUMBER 11 L0
RETURN
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/MissingOverrideOnLongClickListener_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/MissingOverrideOnLongClickListener_expected.txt
index 4e048fd4dd..654af50b34 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/MissingOverrideOnLongClickListener_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/MissingOverrideOnLongClickListener_expected.txt
@@ -20,9 +20,8 @@ public class io/embrace/test/fixtures/MissingOverrideOnLongClickListener impleme
// access flags 0x1
public onLongClick(Landroid/view/View;)Z
- ALOAD 0
ALOAD 1
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnLongClickListener._preOnLongClick (Landroid/view/View$OnLongClickListener;Landroid/view/View;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnLongClickBytecodeEntrypoint.onLongClick (Landroid/view/View;)V
L0
LINENUMBER 10 L0
ICONST_0
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/NoOverrideWebViewClient_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/NoOverrideWebViewClient_expected.txt
index 87f0838f74..a0a6b37057 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/NoOverrideWebViewClient_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/NoOverrideWebViewClient_expected.txt
@@ -20,15 +20,13 @@ public final class io/embrace/test/fixtures/NoOverrideWebViewClient extends andr
// access flags 0x1
public onPageStarted(Landroid/webkit/WebView;Ljava/lang/String;Landroid/graphics/Bitmap;)V
- ALOAD 1
- ALOAD 2
- ALOAD 3
- INVOKESTATIC io/embrace/android/embracesdk/WebViewClientSwazzledHooks._preOnPageStarted (Landroid/webkit/WebView;Ljava/lang/String;Landroid/graphics/Bitmap;)V
ALOAD 0
ALOAD 1
ALOAD 2
ALOAD 3
INVOKESPECIAL android/webkit/WebViewClient.onPageStarted (Landroid/webkit/WebView;Ljava/lang/String;Landroid/graphics/Bitmap;)V
+ ALOAD 2
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/WebViewClientBytecodeEntrypoint.onPageStarted (Ljava/lang/String;)V
RETURN
MAXSTACK = 4
MAXLOCALS = 0
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/OnLongClickInnerListener_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/OnLongClickInnerListener_expected.txt
index 255d27e6b1..3bb6317a63 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/OnLongClickInnerListener_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/OnLongClickInnerListener_expected.txt
@@ -35,9 +35,8 @@ public final class io/embrace/test/fixtures/KotlinNestedOnLongClick$OnLongClickI
public onLongClick(Landroid/view/View;)Z
// annotable parameter count: 1 (invisible)
@Lorg/jetbrains/annotations/Nullable;() // invisible, parameter 0
- ALOAD 0
ALOAD 1
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnLongClickListener._preOnLongClick (Landroid/view/View$OnLongClickListener;Landroid/view/View;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnLongClickBytecodeEntrypoint.onLongClick (Landroid/view/View;)V
L0
LINENUMBER 11 L0
ICONST_1
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/OnLongClickStaticListener_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/OnLongClickStaticListener_expected.txt
index 56b4834c1b..c07deaeb41 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/OnLongClickStaticListener_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/OnLongClickStaticListener_expected.txt
@@ -26,9 +26,8 @@ public final class io/embrace/test/fixtures/KotlinNestedOnLongClick$OnLongClickS
public onLongClick(Landroid/view/View;)Z
// annotable parameter count: 1 (invisible)
@Lorg/jetbrains/annotations/Nullable;() // invisible, parameter 0
- ALOAD 0
ALOAD 1
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnLongClickListener._preOnLongClick (Landroid/view/View$OnLongClickListener;Landroid/view/View;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnLongClickBytecodeEntrypoint.onLongClick (Landroid/view/View;)V
L0
LINENUMBER 17 L0
ICONST_1
diff --git a/embrace-bytecode-instrumentation-tests/src/test/resources/VirtualMethodRefNamedOnClick_expected.txt b/embrace-bytecode-instrumentation-tests/src/test/resources/VirtualMethodRefNamedOnClick_expected.txt
index d476161785..4e89a3bed1 100644
--- a/embrace-bytecode-instrumentation-tests/src/test/resources/VirtualMethodRefNamedOnClick_expected.txt
+++ b/embrace-bytecode-instrumentation-tests/src/test/resources/VirtualMethodRefNamedOnClick_expected.txt
@@ -22,9 +22,8 @@ public class io/embrace/test/fixtures/VirtualMethodRefNamedOnClick extends andro
// access flags 0x2
private onClick(Landroid/view/View;)V
- ALOAD 0
ALOAD 1
- INVOKESTATIC io/embrace/android/embracesdk/ViewSwazzledHooks$OnClickListener._preOnClick (Landroid/view/View$OnClickListener;Landroid/view/View;)V
+ INVOKESTATIC io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnClickBytecodeEntrypoint.onClick (Landroid/view/View;)V
L0
LINENUMBER 21 L0
LDC "Embrace"
diff --git a/embrace-gradle-plugin-integration-tests/build.gradle.kts b/embrace-gradle-plugin-integration-tests/build.gradle.kts
index 47d80b161a..52a921e69a 100644
--- a/embrace-gradle-plugin-integration-tests/build.gradle.kts
+++ b/embrace-gradle-plugin-integration-tests/build.gradle.kts
@@ -38,6 +38,7 @@ tasks.withType(Test::class.java).configureEach {
":embrace-android-sdk",
":embrace-android-core",
":embrace-android-api",
+ ":embrace-android-fcm",
":embrace-android-okhttp3",
":embrace-android-infra",
":embrace-android-features",
diff --git a/embrace-gradle-plugin-integration-tests/fixtures/android-instrumentation/build.gradle b/embrace-gradle-plugin-integration-tests/fixtures/android-instrumentation/build.gradle
index 85fea8403d..4fcbfa1df6 100644
--- a/embrace-gradle-plugin-integration-tests/fixtures/android-instrumentation/build.gradle
+++ b/embrace-gradle-plugin-integration-tests/fixtures/android-instrumentation/build.gradle
@@ -49,6 +49,7 @@ android {
dependencies {
implementation("com.squareup.okhttp3:okhttp:4.12.0")
implementation("com.google.firebase:firebase-messaging:23.1.0")
+ implementation("io.embrace:embrace-android-sdk:+")
implementation("io.embrace:embrace-android-fcm:+")
}
diff --git a/embrace-gradle-plugin-integration-tests/fixtures/android-instrumentation/proguard-rules.pro b/embrace-gradle-plugin-integration-tests/fixtures/android-instrumentation/proguard-rules.pro
index bf47913286..545d7c3e16 100644
--- a/embrace-gradle-plugin-integration-tests/fixtures/android-instrumentation/proguard-rules.pro
+++ b/embrace-gradle-plugin-integration-tests/fixtures/android-instrumentation/proguard-rules.pro
@@ -1,6 +1,3 @@
-keep class com.example.app.** { *; }
-keep class okhttp3.** { *; }
--keep class io.embrace.android.embracesdk.internal.config.instrumented.** { *; }
--keep class io.embrace.android.embracesdk.ViewSwazzledHooks$OnClickListener { *; }
--keep class io.embrace.android.embracesdk.ViewSwazzledHooks$OnLongClickListener { *; }
-keep class com.google.firebase.messaging.RemoteMessage
diff --git a/embrace-gradle-plugin-integration-tests/src/test/resources/bytecode-instrumentation-enabled.json b/embrace-gradle-plugin-integration-tests/src/test/resources/bytecode-instrumentation-enabled.json
index 665ba81d1c..50d3596dc6 100644
--- a/embrace-gradle-plugin-integration-tests/src/test/resources/bytecode-instrumentation-enabled.json
+++ b/embrace-gradle-plugin-integration-tests/src/test/resources/bytecode-instrumentation-enabled.json
@@ -5,7 +5,7 @@
"methods": [
{
"signature": "onPageStarted(Landroid/webkit/WebView;Ljava/lang/String;Landroid/graphics/Bitmap;)V",
- "embraceHook": "invoke-static {p1, p2, p3}, Lio/embrace/android/embracesdk/WebViewClientSwazzledHooks;->_preOnPageStarted(Landroid/webkit/WebView;Ljava/lang/String;Landroid/graphics/Bitmap;)V"
+ "embraceHook": "invoke-static {p2}, Lio/embrace/android/embracesdk/internal/instrumentation/bytecode/WebViewClientBytecodeEntrypoint;->onPageStarted(Ljava/lang/String;)V"
}
]
},
@@ -14,7 +14,7 @@
"methods": [
{
"signature": "onClick(Landroid/view/View;)V",
- "embraceHook": "invoke-static {p0, p1}, Lio/embrace/android/embracesdk/ViewSwazzledHooks$OnClickListener;->_preOnClick(Landroid/view/View$OnClickListener;Landroid/view/View;)V"
+ "embraceHook": "invoke-static {p1}, Lio/embrace/android/embracesdk/internal/instrumentation/bytecode/OnClickBytecodeEntrypoint;->onClick(Landroid/view/View;)V"
}
]
},
@@ -23,7 +23,7 @@
"methods": [
{
"signature": "onLongClick(Landroid/view/View;)Z",
- "embraceHook": "invoke-static {p0, p1}, Lio/embrace/android/embracesdk/ViewSwazzledHooks$OnLongClickListener;->_preOnLongClick(Landroid/view/View$OnLongClickListener;Landroid/view/View;)V",
+ "embraceHook": "invoke-static {p1}, Lio/embrace/android/embracesdk/internal/instrumentation/bytecode/OnLongClickBytecodeEntrypoint;->onLongClick(Landroid/view/View;)V",
"returnValue": "false"
}
]
@@ -33,7 +33,7 @@
"methods": [
{
"signature": "build()Lokhttp3/OkHttpClient;",
- "embraceHook": "invoke-static {p0}, Lio/embrace/android/embracesdk/okhttp3/swazzle/callback/okhttp3/OkHttpClient$Builder;->_preBuild(Lokhttp3/OkHttpClient$Builder;)V"
+ "embraceHook": "invoke-static {p0}, Lio/embrace/android/embracesdk/internal/instrumentation/bytecode/OkHttpBytecodeEntrypoint;->build(Lokhttp3/OkHttpClient$Builder;)V"
}
]
},
@@ -42,7 +42,7 @@
"methods": [
{
"signature": "onMessageReceived(Lcom/google/firebase/messaging/RemoteMessage;)V",
- "embraceHook": "invoke-static {p1}, Lio/embrace/android/embracesdk/fcm/swazzle/callback/com/android/fcm/FirebaseSwazzledHooks;->_onMessageReceived(Lcom/google/firebase/messaging/RemoteMessage;)V"
+ "embraceHook": "invoke-static {p1}, Lio/embrace/android/embracesdk/internal/instrumentation/bytecode/FcmBytecodeEntrypoint;->onMessageReceived(Lcom/google/firebase/messaging/RemoteMessage;)V"
}
]
}
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/EmbraceClassVisitorFactory.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/EmbraceClassVisitorFactory.kt
index 9821619c2c..5eda5b939f 100644
--- a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/EmbraceClassVisitorFactory.kt
+++ b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/EmbraceClassVisitorFactory.kt
@@ -3,7 +3,8 @@ package io.embrace.android.gradle.plugin.instrumentation
import com.android.build.api.instrumentation.AsmClassVisitorFactory
import com.android.build.api.instrumentation.ClassContext
import com.android.build.api.instrumentation.ClassData
-import io.embrace.android.gradle.plugin.Logger
+import io.embrace.android.gradle.plugin.instrumentation.config.ConfigClassVisitorFactory
+import io.embrace.android.gradle.plugin.instrumentation.json.readBytecodeInstrumentationFeatures
import org.objectweb.asm.ClassVisitor
/**
@@ -18,16 +19,27 @@ abstract class EmbraceClassVisitorFactory : AsmClassVisitorFactory
+ visitor = factory.createClassVisitor(feature, classContext, visitor)
+ }
+ return visitor
}
override fun isInstrumentable(classData: ClassData): Boolean {
@@ -39,12 +51,6 @@ abstract class EmbraceClassVisitorFactory : AsmClassVisitorFactory,
- logger: (() -> String) -> Unit,
-): ClassVisitor {
- val api = instrumentationContext.apiVersion.get()
- var visitor = nextClassVisitor
- val className = classContext.currentClassData.className
-
- // Add a visitor if this is a config class provided by the SDK
- val cfg = parameters.get().config.get()
- val encodedSharedObjectFilesMap = parameters.get().encodedSharedObjectFilesMap.orNull
- ConfigClassVisitorFactory.createClassVisitor(className, cfg, encodedSharedObjectFilesMap, api, visitor)?.let {
- visitor = it
- }
-
- // chain our own visitors to avoid unlikely (but possible) cases such as a custom
- // WebViewClient implementing an OnClickListener
- if (parameters.get().shouldInstrumentFirebaseMessaging.get() &&
- FirebaseMessagingServiceClassAdapter.accept(classContext)
- ) {
- visitor = FirebaseMessagingServiceClassAdapter(api, visitor, logger)
- logger { "Added FirebaseMessagingServiceClassAdapter for $className." }
- }
-
- if (parameters.get().shouldInstrumentWebview.get() && WebViewClientClassAdapter.accept(classContext)) {
- visitor = WebViewClientClassAdapter(api, visitor, logger)
- logger { "Added WebViewClientClassAdapter for $className." }
- }
- if (parameters.get().shouldInstrumentOkHttp.get() && OkHttpClassAdapter.accept(classContext)) {
- visitor = OkHttpClassAdapter(api, visitor, logger)
- logger { "Added OkHttpClassAdapter for $className." }
- }
- if (parameters.get().shouldInstrumentOnLongClick.get() && OnLongClickClassAdapter.accept(classContext)) {
- visitor = OnLongClickClassAdapter(api, visitor, logger)
- logger { "Added OnLongClickClassAdapter for $className." }
- }
- if (parameters.get().shouldInstrumentOnClick.get() && OnClickClassAdapter.accept(classContext)) {
- visitor = OnClickClassAdapter(api, visitor, logger)
- logger { "Added OnClickClassAdapter for $className." }
- }
- return visitor
-}
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/TransformClassesWithReflectionException.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/TransformClassesWithReflectionException.kt
deleted file mode 100644
index 516b2db1e3..0000000000
--- a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/TransformClassesWithReflectionException.kt
+++ /dev/null
@@ -1,3 +0,0 @@
-package io.embrace.android.gradle.plugin.instrumentation
-
-class TransformClassesWithReflectionException(message: String?) : Exception(message)
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/VisitorFactoryImpl.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/VisitorFactoryImpl.kt
new file mode 100644
index 0000000000..0b77f9f0e6
--- /dev/null
+++ b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/VisitorFactoryImpl.kt
@@ -0,0 +1,52 @@
+package io.embrace.android.gradle.plugin.instrumentation
+
+import com.android.build.api.instrumentation.ClassContext
+import io.embrace.android.gradle.plugin.instrumentation.visitor.BytecodeInstrumentationFeature
+import io.embrace.android.gradle.plugin.instrumentation.visitor.InsertSuperOverrideClassVisitor
+import io.embrace.android.gradle.plugin.instrumentation.visitor.InstrumentationTargetClassVisitor
+import org.objectweb.asm.ClassVisitor
+
+class VisitorFactoryImpl(
+ private val api: Int,
+ private val params: BytecodeInstrumentationParams,
+) {
+
+ fun createClassVisitor(
+ feature: BytecodeInstrumentationFeature,
+ classContext: ClassContext,
+ nextVisitor: ClassVisitor,
+ ): ClassVisitor {
+ if (feature.isEnabled(params, classContext)) {
+ return if (feature.addOverrideParams != null) {
+ // if specified, add an override for a method if it doesn't already exist in the class
+ InsertSuperOverrideClassVisitor(
+ api = api,
+ nextClassVisitor = nextVisitor,
+ feature = feature,
+ )
+ } else {
+ InstrumentationTargetClassVisitor(
+ api = api,
+ nextClassVisitor = nextVisitor,
+ feature = feature,
+ )
+ }
+ }
+ return nextVisitor
+ }
+
+ private fun BytecodeInstrumentationFeature.isEnabled(
+ params: BytecodeInstrumentationParams,
+ ctx: ClassContext,
+ ): Boolean {
+ val enabledViaDsl = when (name) {
+ "fcm_push_notifications" -> params.shouldInstrumentFirebaseMessaging.get()
+ "okhttp" -> params.shouldInstrumentOkHttp.get()
+ "webview_page_start" -> params.shouldInstrumentWebview.get()
+ "on_click" -> params.shouldInstrumentOnClick.get()
+ "on_long_click" -> params.shouldInstrumentOnLongClick.get()
+ else -> error("Unknown feature: $name. Please add a property that enables/disables it on EmbraceBytecodeInstrumentation.")
+ }
+ return enabledViaDsl && visitStrategy.shouldVisit(ctx)
+ }
+}
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/json/InstrumentationConfigAddOverride.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/json/InstrumentationConfigAddOverride.kt
new file mode 100644
index 0000000000..189a10983f
--- /dev/null
+++ b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/json/InstrumentationConfigAddOverride.kt
@@ -0,0 +1,10 @@
+package io.embrace.android.gradle.plugin.instrumentation.json
+
+import com.squareup.moshi.JsonClass
+
+@JsonClass(generateAdapter = true)
+internal data class InstrumentationConfigAddOverride(
+ val owner: String,
+ val name: String,
+ val descriptor: String,
+)
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/json/InstrumentationConfigFeature.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/json/InstrumentationConfigFeature.kt
new file mode 100644
index 0000000000..12c988945f
--- /dev/null
+++ b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/json/InstrumentationConfigFeature.kt
@@ -0,0 +1,12 @@
+package io.embrace.android.gradle.plugin.instrumentation.json
+
+import com.squareup.moshi.JsonClass
+
+@JsonClass(generateAdapter = true)
+internal data class InstrumentationConfigFeature(
+ val name: String,
+ val target: InstrumentationConfigTarget,
+ val insert: InstrumentationConfigInsert,
+ val visitStrategy: InstrumentationConfigVisitStrategy,
+ val addOverride: InstrumentationConfigAddOverride?,
+)
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/json/InstrumentationConfigFeatures.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/json/InstrumentationConfigFeatures.kt
new file mode 100644
index 0000000000..03e966643a
--- /dev/null
+++ b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/json/InstrumentationConfigFeatures.kt
@@ -0,0 +1,8 @@
+package io.embrace.android.gradle.plugin.instrumentation.json
+
+import com.squareup.moshi.JsonClass
+
+@JsonClass(generateAdapter = true)
+internal data class InstrumentationConfigFeatures(
+ val features: List,
+)
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/json/InstrumentationConfigFeaturesReader.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/json/InstrumentationConfigFeaturesReader.kt
new file mode 100644
index 0000000000..af59ec2dc2
--- /dev/null
+++ b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/json/InstrumentationConfigFeaturesReader.kt
@@ -0,0 +1,59 @@
+package io.embrace.android.gradle.plugin.instrumentation.json
+
+import com.squareup.moshi.Moshi
+import io.embrace.android.gradle.plugin.instrumentation.strategy.ClassVisitStrategy
+import io.embrace.android.gradle.plugin.instrumentation.visitor.BytecodeClassInsertionParams
+import io.embrace.android.gradle.plugin.instrumentation.visitor.BytecodeInstrumentationFeature
+import io.embrace.android.gradle.plugin.instrumentation.visitor.BytecodeMethodInsertionParams
+import io.embrace.android.gradle.plugin.instrumentation.visitor.BytecodeMethodOverrideParams
+import okio.buffer
+import okio.source
+
+fun readBytecodeInstrumentationFeatures(): List {
+ val configFeatures = readBytecodeInstrumentationConfig()
+ return configFeatures.features.map(InstrumentationConfigFeature::convertInstrumentationConfigFeature)
+}
+
+private fun readBytecodeInstrumentationConfig(): InstrumentationConfigFeatures {
+ val classLoader = InstrumentationConfigFeatures::class.java.classLoader
+ val stream = classLoader.getResourceAsStream("bytecode_instrumentation_features.json")
+ ?: error("Bytecode instrumentation config file not found")
+
+ return stream.use {
+ val moshi = Moshi.Builder().build()
+ val adapter = moshi.adapter(InstrumentationConfigFeatures::class.java)
+ adapter.fromJson(it.source().buffer())
+ } ?: error("Failed to parse bytecode instrumentation config file")
+}
+
+private fun InstrumentationConfigFeature.convertInstrumentationConfigFeature(): BytecodeInstrumentationFeature =
+ BytecodeInstrumentationFeature(
+ name = name,
+ targetParams = BytecodeClassInsertionParams(
+ name = target.name,
+ descriptor = target.descriptor
+ ),
+ insertionParams = BytecodeMethodInsertionParams(
+ owner = insert.owner,
+ name = insert.name,
+ descriptor = insert.descriptor,
+ operandStackIndices = insert.operandStackIndices,
+ ),
+ visitStrategy = convertVisitStrategy(),
+ addOverrideParams = addOverride?.let {
+ BytecodeMethodOverrideParams(
+ owner = it.owner,
+ name = it.name,
+ descriptor = it.descriptor,
+ )
+ }
+ )
+
+private fun InstrumentationConfigFeature.convertVisitStrategy(): ClassVisitStrategy {
+ return when (visitStrategy.type) {
+ "match_super_class_name" -> ClassVisitStrategy.MatchSuperClassName(checkNotNull(visitStrategy.value))
+ "match_class_name" -> ClassVisitStrategy.MatchClassName(checkNotNull(visitStrategy.value))
+ "exhaustive" -> ClassVisitStrategy.Exhaustive
+ else -> error("Unsupported visit strategy type: ${visitStrategy.type}")
+ }
+}
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/json/InstrumentationConfigInsert.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/json/InstrumentationConfigInsert.kt
new file mode 100644
index 0000000000..3f7c665641
--- /dev/null
+++ b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/json/InstrumentationConfigInsert.kt
@@ -0,0 +1,11 @@
+package io.embrace.android.gradle.plugin.instrumentation.json
+
+import com.squareup.moshi.JsonClass
+
+@JsonClass(generateAdapter = true)
+internal data class InstrumentationConfigInsert(
+ val owner: String,
+ val name: String,
+ val descriptor: String,
+ val operandStackIndices: List,
+)
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/json/InstrumentationConfigTarget.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/json/InstrumentationConfigTarget.kt
new file mode 100644
index 0000000000..51428e5170
--- /dev/null
+++ b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/json/InstrumentationConfigTarget.kt
@@ -0,0 +1,9 @@
+package io.embrace.android.gradle.plugin.instrumentation.json
+
+import com.squareup.moshi.JsonClass
+
+@JsonClass(generateAdapter = true)
+internal data class InstrumentationConfigTarget(
+ val name: String,
+ val descriptor: String,
+)
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/json/InstrumentationConfigVisitStrategy.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/json/InstrumentationConfigVisitStrategy.kt
new file mode 100644
index 0000000000..55b4a05ac6
--- /dev/null
+++ b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/json/InstrumentationConfigVisitStrategy.kt
@@ -0,0 +1,9 @@
+package io.embrace.android.gradle.plugin.instrumentation.json
+
+import com.squareup.moshi.JsonClass
+
+@JsonClass(generateAdapter = true)
+internal data class InstrumentationConfigVisitStrategy(
+ val type: String,
+ val value: String? = null,
+)
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/strategy/ClassVisitStrategy.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/strategy/ClassVisitStrategy.kt
new file mode 100644
index 0000000000..2e73ec27ff
--- /dev/null
+++ b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/strategy/ClassVisitStrategy.kt
@@ -0,0 +1,40 @@
+package io.embrace.android.gradle.plugin.instrumentation.strategy
+
+import com.android.build.api.instrumentation.ClassContext
+
+/**
+ * Defines all the potential strategies for deciding whether a class should be visited by a particular feature
+ * during bytecode instrumentation.
+ */
+sealed class ClassVisitStrategy {
+
+ /**
+ * Returns true if the class should be visited for _potential_ instrumentation.
+ */
+ abstract fun shouldVisit(ctx: ClassContext): Boolean
+
+ /**
+ * Visits every class.
+ */
+ internal object Exhaustive : ClassVisitStrategy() {
+ override fun shouldVisit(ctx: ClassContext): Boolean = true
+ }
+
+ /**
+ * Visits every class matching the given name.
+ */
+ internal class MatchClassName(private val name: String) : ClassVisitStrategy() {
+ override fun shouldVisit(ctx: ClassContext): Boolean {
+ return ctx.currentClassData.className == name
+ }
+ }
+
+ /**
+ * Visits every class that has a superclass matching the given name.
+ */
+ internal class MatchSuperClassName(private val name: String) : ClassVisitStrategy() {
+ override fun shouldVisit(ctx: ClassContext): Boolean {
+ return ctx.currentClassData.superClasses.contains(name)
+ }
+ }
+}
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/BytecodeClassInsertionParams.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/BytecodeClassInsertionParams.kt
new file mode 100644
index 0000000000..3a407806e7
--- /dev/null
+++ b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/BytecodeClassInsertionParams.kt
@@ -0,0 +1,17 @@
+package io.embrace.android.gradle.plugin.instrumentation.visitor
+
+/**
+ * Parameters used to detect that a method in a class is a target for bytecode instrumentation.
+ */
+data class BytecodeClassInsertionParams(
+
+ /**
+ * The function name that will be targeted for bytecode instrumentation.
+ */
+ val name: String,
+
+ /**
+ * The type signature of the function that will be targeted for bytecode instrumentation.
+ */
+ val descriptor: String,
+)
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/BytecodeInstrumentationFeature.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/BytecodeInstrumentationFeature.kt
new file mode 100644
index 0000000000..c85de519b2
--- /dev/null
+++ b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/BytecodeInstrumentationFeature.kt
@@ -0,0 +1,34 @@
+package io.embrace.android.gradle.plugin.instrumentation.visitor
+
+import io.embrace.android.gradle.plugin.instrumentation.strategy.ClassVisitStrategy
+
+/**
+ * Declares all the necessary information for performing bytecode instrumentation on a specific feature.
+ */
+data class BytecodeInstrumentationFeature(
+
+ /**
+ * The name of the feature.
+ */
+ val name: String,
+
+ /**
+ * Instructions for identifying a target method in the class that will be instrumented.
+ */
+ val targetParams: BytecodeClassInsertionParams,
+
+ /**
+ * Instructions for how to insert bytecode into the target method.
+ */
+ val insertionParams: BytecodeMethodInsertionParams,
+
+ /**
+ * Instructions for determining whether a class should be visited for instrumentation for this feature.
+ */
+ val visitStrategy: ClassVisitStrategy,
+
+ /**
+ * Instructions for how to insert an override into a class that calls to super.
+ */
+ val addOverrideParams: BytecodeMethodOverrideParams? = null,
+)
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/BytecodeMethodInsertionParams.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/BytecodeMethodInsertionParams.kt
new file mode 100644
index 0000000000..976e832da5
--- /dev/null
+++ b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/BytecodeMethodInsertionParams.kt
@@ -0,0 +1,34 @@
+package io.embrace.android.gradle.plugin.instrumentation.visitor
+
+/**
+ * The parameters that should be used to insert a function call into the body of a method.
+ */
+data class BytecodeMethodInsertionParams(
+
+ /**
+ * The fully qualified class name containing the method to be instrumented.
+ */
+ val owner: String,
+
+ /**
+ * The function name that will be instrumented.
+ */
+ val name: String,
+
+ /**
+ * The type signature of the function to be instrumented.
+ */
+ val descriptor: String,
+
+ /**
+ * Declares the indices of variables on the operand stack that should be added as part of the inserted call.
+ * This MUST be entered in ascending order.
+ *
+ * Virtual methods have an implicit reference as the 0th value on the stack, whereas static methods do not.
+ * After this point, the stack should contain the ordered arguments to the containing method.
+ *
+ * As an example, listOf(1, 3) should be supplied if we wanted to pass the String and Boolean parameters of this virtual method:
+ * foo(String, Int, Boolean)
+ */
+ val operandStackIndices: List,
+)
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/BytecodeMethodOverrideParams.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/BytecodeMethodOverrideParams.kt
new file mode 100644
index 0000000000..6f5571888a
--- /dev/null
+++ b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/BytecodeMethodOverrideParams.kt
@@ -0,0 +1,22 @@
+package io.embrace.android.gradle.plugin.instrumentation.visitor
+
+/**
+ * The parameters that should be used to insert an override into a class that calls to super.
+ */
+data class BytecodeMethodOverrideParams(
+
+ /**
+ * The fully qualified class name containing the method to be instrumented.
+ */
+ val owner: String,
+
+ /**
+ * The function name that will be instrumented.
+ */
+ val name: String,
+
+ /**
+ * The type signature of the function to be instrumented.
+ */
+ val descriptor: String,
+)
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/ClassVisitFilter.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/ClassVisitFilter.kt
deleted file mode 100644
index a4446ed1ed..0000000000
--- a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/ClassVisitFilter.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-package io.embrace.android.gradle.plugin.instrumentation.visitor
-
-import com.android.build.api.instrumentation.ClassContext
-
-@Suppress("UnstableApiUsage")
-interface ClassVisitFilter {
-
- /**
- * Returns true if a visitor wants to visit a given class context.
- */
- fun accept(classContext: ClassContext): Boolean
-}
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/FirebaseMessagingServiceClassAdapter.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/FirebaseMessagingServiceClassAdapter.kt
deleted file mode 100644
index a5b7b47d63..0000000000
--- a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/FirebaseMessagingServiceClassAdapter.kt
+++ /dev/null
@@ -1,46 +0,0 @@
-package io.embrace.android.gradle.plugin.instrumentation.visitor
-
-import com.android.build.api.instrumentation.ClassContext
-import org.objectweb.asm.ClassVisitor
-import org.objectweb.asm.MethodVisitor
-
-/**
- * Visits the [FirebaseMessagingService] class and returns a [FirebaseMessagingServiceMethodAdapter]
- * for the onMessageReceived method.
- */
-class FirebaseMessagingServiceClassAdapter(
- api: Int,
- internal val nextClassVisitor: ClassVisitor?,
- private val logger: (() -> String) -> Unit
-) : ClassVisitor(api, nextClassVisitor) {
-
- companion object : ClassVisitFilter {
- private const val CLASS_NAME = "com.google.firebase.messaging.FirebaseMessagingService"
- private const val METHOD_NAME = "onMessageReceived"
- private const val METHOD_DESC = "(Lcom/google/firebase/messaging/RemoteMessage;)V"
-
- @Suppress("UnstableApiUsage")
- override fun accept(classContext: ClassContext): Boolean {
- if (classContext.currentClassData.superClasses.contains(CLASS_NAME)) {
- return true
- }
- return false
- }
- }
- override fun visitMethod(
- access: Int,
- name: String,
- desc: String,
- signature: String?,
- exceptions: Array?
- ): MethodVisitor? {
- val nextMethodVisitor = super.visitMethod(access, name, desc, signature, exceptions)
-
- return if (METHOD_NAME == name && METHOD_DESC == desc) {
- logger { "FirebaseMessagingServiceClassAdapter: instrumented method $name $desc" }
- FirebaseMessagingServiceMethodAdapter(api, nextMethodVisitor)
- } else {
- nextMethodVisitor
- }
- }
-}
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/FirebaseMessagingServiceMethodAdapter.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/FirebaseMessagingServiceMethodAdapter.kt
deleted file mode 100644
index fde43f804d..0000000000
--- a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/FirebaseMessagingServiceMethodAdapter.kt
+++ /dev/null
@@ -1,29 +0,0 @@
-package io.embrace.android.gradle.plugin.instrumentation.visitor
-
-import org.objectweb.asm.MethodVisitor
-import org.objectweb.asm.Opcodes
-
-/**
- * Visits the onMessageReceived method and inserts a call to
- * FirebaseSwazzledHooks._onMessageReceived at the very start of the method.
- */
-class FirebaseMessagingServiceMethodAdapter(
- api: Int,
- methodVisitor: MethodVisitor?
-) : MethodVisitor(api, methodVisitor) {
-
- override fun visitCode() {
- // load local variable 'remoteMessage' and push it onto the operand stack
- visitVarInsn(Opcodes.ALOAD, 1)
- // invoke FirebaseSwazzledHooks._onMessageReceived()
- visitMethodInsn(
- Opcodes.INVOKESTATIC,
- "io/embrace/android/embracesdk/fcm/swazzle/callback/com/android/fcm/FirebaseSwazzledHooks",
- "_onMessageReceived",
- "(Lcom/google/firebase/messaging/RemoteMessage;)V",
- false
- )
- // call super last to reduce chance of interference with other bytecode instrumentation
- super.visitCode()
- }
-}
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/InsertSuperOverrideClassVisitor.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/InsertSuperOverrideClassVisitor.kt
new file mode 100644
index 0000000000..a51d4edd3a
--- /dev/null
+++ b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/InsertSuperOverrideClassVisitor.kt
@@ -0,0 +1,88 @@
+package io.embrace.android.gradle.plugin.instrumentation.visitor
+
+import org.objectweb.asm.ClassVisitor
+import org.objectweb.asm.MethodVisitor
+import org.objectweb.asm.Opcodes
+import org.objectweb.asm.Type
+
+/**
+ * Visits the class and adds an override that calls to the super class method, if no override is already specified.
+ */
+class InsertSuperOverrideClassVisitor(
+ api: Int,
+ nextClassVisitor: ClassVisitor?,
+ private val feature: BytecodeInstrumentationFeature,
+) : ClassVisitor(api, nextClassVisitor) {
+
+ private var hasOverride = false
+
+ override fun visitMethod(
+ access: Int,
+ name: String,
+ desc: String,
+ signature: String?,
+ exceptions: Array?,
+ ): MethodVisitor? {
+ val nextMethodVisitor = super.visitMethod(access, name, desc, signature, exceptions)
+
+ return if (feature.targetParams.name == name && feature.targetParams.descriptor == desc && !isStatic(access)) {
+ hasOverride = true
+ InstrumentationTargetMethodVisitor(
+ api = api,
+ methodVisitor = nextMethodVisitor,
+ params = feature.insertionParams
+ )
+ } else {
+ return nextMethodVisitor
+ }
+ }
+
+ override fun visitEnd() {
+ // add an override of onPageStarted if the class does not have one already.
+ if (!hasOverride) {
+ val nextMethodVisitor = super.visitMethod(
+ Opcodes.ACC_PUBLIC,
+ feature.targetParams.name,
+ feature.targetParams.descriptor,
+ null,
+ emptyArray()
+ )
+ nextMethodVisitor.addSuperCall()
+ }
+ super.visitEnd()
+ }
+
+ private fun MethodVisitor.addSuperCall() {
+ val count = Type.getType(feature.addOverrideParams?.descriptor).argumentCount + 1
+ repeat(count) {
+ visitVarInsn(Opcodes.ALOAD, it)
+ }
+
+ visitMethodInsn(
+ Opcodes.INVOKESPECIAL,
+ feature.addOverrideParams?.owner,
+ feature.addOverrideParams?.name,
+ feature.addOverrideParams?.descriptor,
+ false
+ )
+
+ // load local variables required for method call (if any) and push onto the operand stack
+ val params = feature.insertionParams
+ params.operandStackIndices.forEach {
+ visitVarInsn(Opcodes.ALOAD, it)
+ }
+
+ // invoke the target method
+ visitMethodInsn(
+ Opcodes.INVOKESTATIC,
+ params.owner,
+ params.name,
+ params.descriptor,
+ false
+ )
+
+ visitEnd()
+ visitInsn(Opcodes.RETURN)
+ visitMaxs(count, 0)
+ }
+}
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/InstrumentationTargetClassVisitor.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/InstrumentationTargetClassVisitor.kt
new file mode 100644
index 0000000000..2c612dcf8c
--- /dev/null
+++ b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/InstrumentationTargetClassVisitor.kt
@@ -0,0 +1,34 @@
+package io.embrace.android.gradle.plugin.instrumentation.visitor
+
+import org.objectweb.asm.ClassVisitor
+import org.objectweb.asm.MethodVisitor
+
+/**
+ * Visits a class and adds [InstrumentationTargetMethodVisitor] to any methods that require bytecode instrumentation.
+ */
+class InstrumentationTargetClassVisitor(
+ api: Int,
+ nextClassVisitor: ClassVisitor?,
+ private val feature: BytecodeInstrumentationFeature,
+) : ClassVisitor(api, nextClassVisitor) {
+
+ override fun visitMethod(
+ access: Int,
+ name: String,
+ desc: String,
+ signature: String?,
+ exceptions: Array?,
+ ): MethodVisitor? {
+ val nextMethodVisitor = super.visitMethod(access, name, desc, signature, exceptions)
+
+ return if (feature.targetParams.name == name && feature.targetParams.descriptor == desc && !isStatic(access)) {
+ InstrumentationTargetMethodVisitor(
+ api = api,
+ methodVisitor = nextMethodVisitor,
+ params = feature.insertionParams
+ )
+ } else {
+ nextMethodVisitor
+ }
+ }
+}
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/InstrumentationTargetMethodVisitor.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/InstrumentationTargetMethodVisitor.kt
new file mode 100644
index 0000000000..9804350932
--- /dev/null
+++ b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/InstrumentationTargetMethodVisitor.kt
@@ -0,0 +1,34 @@
+package io.embrace.android.gradle.plugin.instrumentation.visitor
+
+import org.objectweb.asm.MethodVisitor
+import org.objectweb.asm.Opcodes
+
+/**
+ * Visits a method that should be rewritten to include an API call to instrumentation
+ * and inserts a call to a static method at the very start.
+ */
+internal class InstrumentationTargetMethodVisitor(
+ api: Int,
+ methodVisitor: MethodVisitor?,
+ private val params: BytecodeMethodInsertionParams,
+) : MethodVisitor(api, methodVisitor) {
+
+ override fun visitCode() {
+ // load local variables required for method call (if any) and push onto the operand stack
+ params.operandStackIndices.forEach {
+ visitVarInsn(Opcodes.ALOAD, it)
+ }
+
+ // invoke the target method
+ visitMethodInsn(
+ Opcodes.INVOKESTATIC,
+ params.owner,
+ params.name,
+ params.descriptor,
+ false
+ )
+
+ // call super last to reduce chance of interference with other bytecode instrumentation
+ super.visitCode()
+ }
+}
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OkHttpClassAdapter.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OkHttpClassAdapter.kt
deleted file mode 100644
index 4aac92acce..0000000000
--- a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OkHttpClassAdapter.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-package io.embrace.android.gradle.plugin.instrumentation.visitor
-
-import com.android.build.api.instrumentation.ClassContext
-import org.objectweb.asm.ClassVisitor
-import org.objectweb.asm.MethodVisitor
-
-/**
- * Visits a class and returns an [OkHttpInitMethodAdapter] for OkHttp$Builder methods.
- */
-class OkHttpClassAdapter(
- api: Int,
- internal val nextClassVisitor: ClassVisitor?,
- private val logger: (() -> String) -> Unit
-) : ClassVisitor(api, nextClassVisitor) {
-
- companion object : ClassVisitFilter {
- private const val CLASS_NAME = "okhttp3.OkHttpClient\$Builder"
- private const val METHOD_NAME_BUILD = "build"
- private const val METHOD_DESC_BUILD = "()Lokhttp3/OkHttpClient;"
-
- override fun accept(classContext: ClassContext): Boolean {
- return classContext.currentClassData.className == CLASS_NAME
- }
- }
-
- override fun visitMethod(
- access: Int,
- name: String,
- desc: String,
- signature: String?,
- exceptions: Array?
- ): MethodVisitor? {
- val nextMethodVisitor = super.visitMethod(access, name, desc, signature, exceptions)
-
- return if (METHOD_NAME_BUILD == name && METHOD_DESC_BUILD == desc) {
- logger { "OkHttpClassAdapter: instrumented method $name $desc" }
- OkHttpMethodAdapter(api, nextMethodVisitor)
- } else {
- nextMethodVisitor
- }
- }
-}
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OkHttpMethodAdapter.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OkHttpMethodAdapter.kt
deleted file mode 100644
index 698468d1b5..0000000000
--- a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OkHttpMethodAdapter.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-package io.embrace.android.gradle.plugin.instrumentation.visitor
-
-import org.objectweb.asm.MethodVisitor
-import org.objectweb.asm.Opcodes
-
-/**
- * Visits OkHttp methods and inserts a call to OkHttpClient$Builder._preBuild at the very start
- * of the method.
- */
-class OkHttpMethodAdapter(
- api: Int,
- methodVisitor: MethodVisitor?
-) : MethodVisitor(api, methodVisitor) {
-
- override fun visitCode() {
- // load local variable 'this' and push it onto the operand stack
- visitVarInsn(Opcodes.ALOAD, 0)
-
- // invoke Builder._preBuild(this)
- visitMethodInsn(
- Opcodes.INVOKESTATIC,
- "io/embrace/android/embracesdk/okhttp3/swazzle/callback/okhttp3/OkHttpClient\$Builder",
- "_preBuild",
- "(Lokhttp3/OkHttpClient\$Builder;)V",
- false
- )
-
- // call super last to reduce chance of interference with other bytecode instrumentation
- super.visitCode()
- }
-}
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnClickClassAdapter.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnClickClassAdapter.kt
deleted file mode 100644
index 1b4ac8dec6..0000000000
--- a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnClickClassAdapter.kt
+++ /dev/null
@@ -1,43 +0,0 @@
-package io.embrace.android.gradle.plugin.instrumentation.visitor
-
-import com.android.build.api.instrumentation.ClassContext
-import org.objectweb.asm.ClassVisitor
-import org.objectweb.asm.MethodVisitor
-
-/**
- * Visits a class and returns an [OnClickMethodAdapter] for any onClick method which
- * conforms to the OnClickListener interface.
- */
-class OnClickClassAdapter(
- api: Int,
- internal val nextClassVisitor: ClassVisitor?,
- private val logger: (() -> String) -> Unit
-) : ClassVisitor(api, nextClassVisitor) {
-
- companion object : ClassVisitFilter {
- private const val METHOD_NAME = "onClick"
- private const val METHOD_DESC = "(Landroid/view/View;)V"
-
- override fun accept(classContext: ClassContext) = true
- }
-
- override fun visitMethod(
- access: Int,
- name: String,
- desc: String,
- signature: String?,
- exceptions: Array?
- ): MethodVisitor? {
- val nextMethodVisitor = super.visitMethod(access, name, desc, signature, exceptions)
-
- return if (METHOD_NAME == name && METHOD_DESC == desc && !isStatic(access)) {
- logger { "OnClickClassAdapter: instrumented method $name $desc" }
- OnClickMethodAdapter(api, nextMethodVisitor)
- } else if (METHOD_DESC == desc && isStatic(access) && isSynthetic(access)) {
- logger { "OnClickClassAdapter: instrumented synthetic method $name $desc" }
- OnClickStaticMethodAdapter(api, nextMethodVisitor)
- } else {
- nextMethodVisitor
- }
- }
-}
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnClickMethodAdapter.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnClickMethodAdapter.kt
deleted file mode 100644
index 63d220c91d..0000000000
--- a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnClickMethodAdapter.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-package io.embrace.android.gradle.plugin.instrumentation.visitor
-
-import org.objectweb.asm.MethodVisitor
-import org.objectweb.asm.Opcodes
-
-/**
- * Visits an onClick method and inserts a call to ViewSwazzledHooks._preOnClick at the very start
- * of the method.
- */
-class OnClickMethodAdapter(
- api: Int,
- methodVisitor: MethodVisitor?
-) : MethodVisitor(api, methodVisitor) {
-
- override fun visitCode() {
- // load local variable 'this' and push it onto the operand stack
- visitVarInsn(Opcodes.ALOAD, 0)
-
- // load local variable 'view' and push it onto the operand stack
- visitVarInsn(Opcodes.ALOAD, 1)
-
- // invoke ViewSwazzledHooks$OnClickListener._preOnClick()
- visitMethodInsn(
- Opcodes.INVOKESTATIC,
- "io/embrace/android/embracesdk/ViewSwazzledHooks\$OnClickListener",
- "_preOnClick",
- "(Landroid/view/View\$OnClickListener;Landroid/view/View;)V",
- false
- )
-
- // call super last to reduce chance of interference with other bytecode instrumentation
- super.visitCode()
- }
-}
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnClickStaticMethodAdapter.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnClickStaticMethodAdapter.kt
deleted file mode 100644
index f98f94480f..0000000000
--- a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnClickStaticMethodAdapter.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-package io.embrace.android.gradle.plugin.instrumentation.visitor
-
-import org.objectweb.asm.MethodVisitor
-import org.objectweb.asm.Opcodes
-
-/**
- * Visits a static onClick method and inserts a call to ViewSwazzledHooks._preOnClick at the very
- * start of the method.
- */
-class OnClickStaticMethodAdapter(
- api: Int,
- methodVisitor: MethodVisitor?,
-) : MethodVisitor(api, methodVisitor) {
-
- override fun visitCode() {
- // load the null reference and push it onto the operand stack.
- // null is ok here as _preOnClick doesn't use the listener,
- // and in a static context 'this' does not actually implement OnClickListener
- // in Java bytecode.
- visitInsn(Opcodes.ACONST_NULL)
-
- // load local variable 'view' and push it onto the operand stack
- visitVarInsn(Opcodes.ALOAD, 0)
-
- // invoke ViewSwazzledHooks$OnClickListener._preOnClick()
- visitMethodInsn(
- Opcodes.INVOKESTATIC,
- "io/embrace/android/embracesdk/ViewSwazzledHooks\$OnClickListener",
- "_preOnClick",
- "(Landroid/view/View\$OnClickListener;Landroid/view/View;)V",
- false
- )
-
- // call super last to reduce chance of interference with other bytecode instrumentation
- super.visitCode()
- }
-}
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnLongClickClassAdapter.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnLongClickClassAdapter.kt
deleted file mode 100644
index 69a494e9c7..0000000000
--- a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnLongClickClassAdapter.kt
+++ /dev/null
@@ -1,43 +0,0 @@
-package io.embrace.android.gradle.plugin.instrumentation.visitor
-
-import com.android.build.api.instrumentation.ClassContext
-import org.objectweb.asm.ClassVisitor
-import org.objectweb.asm.MethodVisitor
-
-/**
- * Visits a class and returns an [OnLongClickMethodAdapter] for any onLongClick method which
- * conforms to the OnLongClickListener interface.
- */
-class OnLongClickClassAdapter(
- api: Int,
- internal val nextClassVisitor: ClassVisitor?,
- private val logger: (() -> String) -> Unit
-) : ClassVisitor(api, nextClassVisitor) {
-
- companion object : ClassVisitFilter {
- private const val METHOD_NAME = "onLongClick"
- private const val METHOD_DESC = "(Landroid/view/View;)Z"
-
- override fun accept(classContext: ClassContext) = true
- }
-
- override fun visitMethod(
- access: Int,
- name: String,
- desc: String,
- signature: String?,
- exceptions: Array?
- ): MethodVisitor? {
- val nextMethodVisitor = super.visitMethod(access, name, desc, signature, exceptions)
-
- return if (METHOD_NAME == name && METHOD_DESC == desc && !isStatic(access)) {
- logger { "OnLongClickClassAdapter: instrumented method $name $desc" }
- OnLongClickMethodAdapter(api, nextMethodVisitor)
- } else if (METHOD_DESC == desc && isStatic(access) && isSynthetic(access)) {
- logger { "OnLongClickClassAdapter: instrumented synthetic method $name $desc" }
- OnLongClickStaticMethodAdapter(api, nextMethodVisitor)
- } else {
- nextMethodVisitor
- }
- }
-}
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnLongClickMethodAdapter.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnLongClickMethodAdapter.kt
deleted file mode 100644
index 48197e79cb..0000000000
--- a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnLongClickMethodAdapter.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-package io.embrace.android.gradle.plugin.instrumentation.visitor
-
-import org.objectweb.asm.MethodVisitor
-import org.objectweb.asm.Opcodes
-
-/**
- * Visits an onLongClick method and inserts a call to ViewSwazzledHooks._preOnLongClick at
- * the very start of the method.
- */
-class OnLongClickMethodAdapter(
- api: Int,
- methodVisitor: MethodVisitor?
-) : MethodVisitor(api, methodVisitor) {
-
- override fun visitCode() {
- // load local variable 'this' and push it onto the operand stack
- visitVarInsn(Opcodes.ALOAD, 0)
-
- // load local variable 'view' and push it onto the operand stack
- visitVarInsn(Opcodes.ALOAD, 1)
-
- // invoke ViewSwazzledHooks$OnLongClickListener._preOnLongClick()
- visitMethodInsn(
- Opcodes.INVOKESTATIC,
- "io/embrace/android/embracesdk/ViewSwazzledHooks\$OnLongClickListener",
- "_preOnLongClick",
- "(Landroid/view/View\$OnLongClickListener;Landroid/view/View;)V",
- false
- )
-
- // call super last to reduce chance of interference with other bytecode instrumentation
- super.visitCode()
- }
-}
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnLongClickStaticMethodAdapter.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnLongClickStaticMethodAdapter.kt
deleted file mode 100644
index dded713ade..0000000000
--- a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnLongClickStaticMethodAdapter.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-package io.embrace.android.gradle.plugin.instrumentation.visitor
-
-import org.objectweb.asm.MethodVisitor
-import org.objectweb.asm.Opcodes
-
-/**
- * Visits a static onLongClick method and inserts a call to ViewSwazzledHooks._preOnLongClick
- * at the very start of the method.
- */
-class OnLongClickStaticMethodAdapter(
- api: Int,
- methodVisitor: MethodVisitor?,
-) : MethodVisitor(api, methodVisitor) {
-
- override fun visitCode() {
- // load the null reference and push it onto the operand stack.
- // null is ok here as _preOnLongClick doesn't use the listener,
- // and in a static context 'this' does not actually implement OnLongClickListener
- // in Java bytecode.
- visitInsn(Opcodes.ACONST_NULL)
-
- // load local variable 'view' and push it onto the operand stack
- visitVarInsn(Opcodes.ALOAD, 0)
-
- // invoke ViewSwazzledHooks$OnLongClickListener._preOnLongClick()
- visitMethodInsn(
- Opcodes.INVOKESTATIC,
- "io/embrace/android/embracesdk/ViewSwazzledHooks\$OnLongClickListener",
- "_preOnLongClick",
- "(Landroid/view/View\$OnLongClickListener;Landroid/view/View;)V",
- false
- )
-
- // call super last to reduce chance of interference with other bytecode instrumentation
- super.visitCode()
- }
-}
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OpcodeExtensions.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OpcodeExtensions.kt
index eb69dc3ce6..8044ee85f2 100644
--- a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OpcodeExtensions.kt
+++ b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OpcodeExtensions.kt
@@ -6,8 +6,3 @@ import org.objectweb.asm.Opcodes
* Returns true if a method is static.
*/
internal fun isStatic(access: Int) = access.and(Opcodes.ACC_STATIC) != 0
-
-/**
- * Returns true if a method is synthetic (e.g. a Java lambda).
- */
-internal fun isSynthetic(access: Int) = access.and(Opcodes.ACC_SYNTHETIC) != 0
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/WebViewClientClassAdapter.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/WebViewClientClassAdapter.kt
deleted file mode 100644
index 1ed5cbab67..0000000000
--- a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/WebViewClientClassAdapter.kt
+++ /dev/null
@@ -1,68 +0,0 @@
-package io.embrace.android.gradle.plugin.instrumentation.visitor
-
-import com.android.build.api.instrumentation.ClassContext
-import org.objectweb.asm.ClassVisitor
-import org.objectweb.asm.MethodVisitor
-import org.objectweb.asm.Opcodes
-
-/**
- * Visits the [WebViewClient] class and returns a [WebViewClientMethodAdapter] for the
- * onPageStarted method.
- */
-class WebViewClientClassAdapter(
- api: Int,
- internal val nextClassVisitor: ClassVisitor?,
- private val logger: (() -> String) -> Unit
-) : ClassVisitor(api, nextClassVisitor) {
-
- companion object : ClassVisitFilter {
- private const val CLASS_NAME = "android.webkit.WebViewClient"
- private const val METHOD_NAME = "onPageStarted"
- private const val METHOD_DESC =
- "(Landroid/webkit/WebView;Ljava/lang/String;Landroid/graphics/Bitmap;)V"
-
- override fun accept(classContext: ClassContext): Boolean {
- if (classContext.currentClassData.superClasses.contains(CLASS_NAME)) {
- return true
- }
- return false
- }
- }
-
- var hasOverride = false
-
- override fun visitMethod(
- access: Int,
- name: String,
- desc: String,
- signature: String?,
- exceptions: Array?
- ): MethodVisitor? {
- val nextMethodVisitor = super.visitMethod(access, name, desc, signature, exceptions)
-
- return if (METHOD_NAME == name && METHOD_DESC == desc) {
- logger { "WebViewClientClassAdapter: instrumented method $name $desc" }
- hasOverride = true
- WebViewClientMethodAdapter(api, nextMethodVisitor)
- } else {
- nextMethodVisitor
- }
- }
-
- override fun visitEnd() {
- // add an override of onPageStarted if the class does not have one already.
- if (!hasOverride) {
- logger { "WebViewClientClassAdapter: instrumented method $METHOD_NAME $METHOD_DESC (added override)" }
-
- val nextMethodVisitor = super.visitMethod(
- Opcodes.ACC_PUBLIC,
- METHOD_NAME,
- METHOD_DESC,
- null,
- emptyArray()
- )
- WebViewClientOverrideMethodAdapter(api, nextMethodVisitor).visitEnd()
- }
- super.visitEnd()
- }
-}
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/WebViewClientMethodAdapter.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/WebViewClientMethodAdapter.kt
deleted file mode 100644
index 6bc13b6ec2..0000000000
--- a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/WebViewClientMethodAdapter.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-package io.embrace.android.gradle.plugin.instrumentation.visitor
-
-import org.objectweb.asm.MethodVisitor
-import org.objectweb.asm.Opcodes
-
-/**
- * Visits the onPageStarted method and inserts a call to ViewSwazzledHooks._preOnPageStarted
- * at the very start of the method.
- */
-open class WebViewClientMethodAdapter(
- api: Int,
- methodVisitor: MethodVisitor?
-) : MethodVisitor(api, methodVisitor) {
-
- override fun visitCode() {
- instrumentOnPageStarted()
- // call super last to reduce chance of interference with other bytecode instrumentation
- super.visitCode()
- }
-
- internal fun instrumentOnPageStarted() {
- // load local variable 'view' and push it onto the operand stack
- visitVarInsn(Opcodes.ALOAD, 1)
-
- // load local variable 'url' and push it onto the operand stack
- visitVarInsn(Opcodes.ALOAD, 2)
-
- // load local variable 'favicon' and push it onto the operand stack
- visitVarInsn(Opcodes.ALOAD, 3)
-
- // invoke WebViewClientSwazzledHooks._preOnPageStarted()
- visitMethodInsn(
- Opcodes.INVOKESTATIC,
- "io/embrace/android/embracesdk/WebViewClientSwazzledHooks",
- "_preOnPageStarted",
- "(Landroid/webkit/WebView;Ljava/lang/String;Landroid/graphics/Bitmap;)V",
- false
- )
- }
-}
diff --git a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/WebViewClientOverrideMethodAdapter.kt b/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/WebViewClientOverrideMethodAdapter.kt
deleted file mode 100644
index be929c63fe..0000000000
--- a/embrace-gradle-plugin/src/main/java/io/embrace/android/gradle/plugin/instrumentation/visitor/WebViewClientOverrideMethodAdapter.kt
+++ /dev/null
@@ -1,44 +0,0 @@
-package io.embrace.android.gradle.plugin.instrumentation.visitor
-
-import org.objectweb.asm.MethodVisitor
-import org.objectweb.asm.Opcodes
-
-/**
- * Creates an onPageStarted method override and inserts a call to
- * ViewSwazzledHooks._preOnPageStarted at the very start of the method.
- */
-class WebViewClientOverrideMethodAdapter(
- api: Int,
- methodVisitor: MethodVisitor?
-) : WebViewClientMethodAdapter(api, methodVisitor) {
-
- override fun visitEnd() {
- instrumentOnPageStarted()
- addSuperCall()
- super.visitEnd()
- visitInsn(Opcodes.RETURN)
- visitMaxs(4, 0)
- }
-
- private fun addSuperCall() {
- // load local variable 'this' and push it onto the operand stack
- visitVarInsn(Opcodes.ALOAD, 0)
-
- // load local variable 'view' and push it onto the operand stack
- visitVarInsn(Opcodes.ALOAD, 1)
-
- // load local variable 'url' and push it onto the operand stack
- visitVarInsn(Opcodes.ALOAD, 2)
-
- // load local variable 'favicon' and push it onto the operand stack
- visitVarInsn(Opcodes.ALOAD, 3)
-
- visitMethodInsn(
- Opcodes.INVOKESPECIAL,
- "android/webkit/WebViewClient",
- "onPageStarted",
- "(Landroid/webkit/WebView;Ljava/lang/String;Landroid/graphics/Bitmap;)V",
- false
- )
- }
-}
diff --git a/embrace-gradle-plugin/src/main/resources/bytecode_instrumentation_features.json b/embrace-gradle-plugin/src/main/resources/bytecode_instrumentation_features.json
new file mode 100644
index 0000000000..3c1db11342
--- /dev/null
+++ b/embrace-gradle-plugin/src/main/resources/bytecode_instrumentation_features.json
@@ -0,0 +1,102 @@
+{
+ "features": [
+ {
+ "name": "fcm_push_notifications",
+ "target": {
+ "name": "onMessageReceived",
+ "descriptor": "(Lcom/google/firebase/messaging/RemoteMessage;)V"
+ },
+ "insert": {
+ "owner": "io/embrace/android/embracesdk/internal/instrumentation/bytecode/FcmBytecodeEntrypoint",
+ "name": "onMessageReceived",
+ "descriptor": "(Lcom/google/firebase/messaging/RemoteMessage;)V",
+ "operandStackIndices": [
+ 1
+ ]
+ },
+ "visitStrategy": {
+ "type": "match_super_class_name",
+ "value": "com.google.firebase.messaging.FirebaseMessagingService"
+ }
+ },
+ {
+ "name": "webview_page_start",
+ "target": {
+ "name": "onPageStarted",
+ "descriptor": "(Landroid/webkit/WebView;Ljava/lang/String;Landroid/graphics/Bitmap;)V"
+ },
+ "insert": {
+ "owner": "io/embrace/android/embracesdk/internal/instrumentation/bytecode/WebViewClientBytecodeEntrypoint",
+ "name": "onPageStarted",
+ "descriptor": "(Ljava/lang/String;)V",
+ "operandStackIndices": [
+ 2
+ ]
+ },
+ "addOverride": {
+ "owner": "android/webkit/WebViewClient",
+ "name": "onPageStarted",
+ "descriptor": "(Landroid/webkit/WebView;Ljava/lang/String;Landroid/graphics/Bitmap;)V"
+ },
+ "visitStrategy": {
+ "type": "match_super_class_name",
+ "value": "android.webkit.WebViewClient"
+ }
+ },
+ {
+ "name": "okhttp",
+ "target": {
+ "name": "build",
+ "descriptor": "()Lokhttp3/OkHttpClient;"
+ },
+ "insert": {
+ "owner": "io/embrace/android/embracesdk/internal/instrumentation/bytecode/OkHttpBytecodeEntrypoint",
+ "name": "build",
+ "descriptor": "(Lokhttp3/OkHttpClient$Builder;)V",
+ "operandStackIndices": [
+ 0
+ ]
+ },
+ "visitStrategy": {
+ "type": "match_class_name",
+ "value": "okhttp3.OkHttpClient$Builder"
+ }
+ },
+ {
+ "name": "on_click",
+ "target": {
+ "name": "onClick",
+ "descriptor": "(Landroid/view/View;)V"
+ },
+ "insert": {
+ "owner": "io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnClickBytecodeEntrypoint",
+ "name": "onClick",
+ "descriptor": "(Landroid/view/View;)V",
+ "operandStackIndices": [
+ 1
+ ]
+ },
+ "visitStrategy": {
+ "type": "exhaustive"
+ }
+ },
+ {
+ "name": "on_long_click",
+ "target": {
+ "name": "onLongClick",
+ "descriptor": "(Landroid/view/View;)Z"
+ },
+ "insert": {
+ "owner": "io/embrace/android/embracesdk/internal/instrumentation/bytecode/OnLongClickBytecodeEntrypoint",
+ "name": "onLongClick",
+ "descriptor": "(Landroid/view/View;)V",
+ "operandStackIndices": [
+ 1
+ ]
+ },
+ "visitStrategy": {
+ "type": "exhaustive"
+ }
+ }
+ ]
+}
diff --git a/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/EmbraceClassVisitorFactoryTest.kt b/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/EmbraceClassVisitorFactoryTest.kt
index 42de077e4f..fd305b9ee7 100644
--- a/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/EmbraceClassVisitorFactoryTest.kt
+++ b/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/EmbraceClassVisitorFactoryTest.kt
@@ -1,17 +1,10 @@
package io.embrace.android.gradle.plugin.instrumentation
import com.android.build.api.instrumentation.ClassContext
-import io.embrace.android.gradle.plugin.instrumentation.config.visitor.ConfigInstrumentationClassVisitor
import io.embrace.android.gradle.plugin.instrumentation.fakes.TestBytecodeInstrumentationParams
-import io.embrace.android.gradle.plugin.instrumentation.fakes.TestClassContext
import io.embrace.android.gradle.plugin.instrumentation.fakes.TestClassData
import io.embrace.android.gradle.plugin.instrumentation.fakes.TestClassVisitor
import io.embrace.android.gradle.plugin.instrumentation.fakes.TestVisitorFactoryImpl
-import io.embrace.android.gradle.plugin.instrumentation.visitor.FirebaseMessagingServiceClassAdapter
-import io.embrace.android.gradle.plugin.instrumentation.visitor.OkHttpClassAdapter
-import io.embrace.android.gradle.plugin.instrumentation.visitor.OnClickClassAdapter
-import io.embrace.android.gradle.plugin.instrumentation.visitor.OnLongClickClassAdapter
-import io.embrace.android.gradle.plugin.instrumentation.visitor.WebViewClientClassAdapter
import io.mockk.every
import io.mockk.mockk
import org.junit.Assert.assertFalse
@@ -24,67 +17,6 @@ class EmbraceClassVisitorFactoryTest {
private val clzDataString = TestClassData(checkNotNull(String::class.qualifiedName))
private val clzDataBool = TestClassData(checkNotNull(Boolean::class.qualifiedName))
- /**
- * Verifies that the OnClick visitor should be returned if there is nothing to instrument,
- * and that it should chain the original visitor.
- */
- @Test
- fun testDefaultClassVisitorReturned() {
- val visitor = TestClassVisitor()
- val ctx = TestClassContext(clzDataString)
- val returningVisitor = TestVisitorFactoryImpl().createClassVisitor(ctx, visitor)
- check(returningVisitor is OnClickClassAdapter)
- check(returningVisitor.nextClassVisitor is OnLongClickClassAdapter)
- assertSame(visitor, returningVisitor.nextClassVisitor.nextClassVisitor)
- }
-
- @Test
- fun testWebViewClassVisitorReturned() {
- val visitor = TestClassVisitor()
- val ctx = createMockClassContext("android.webkit.WebViewClient")
- val returningVisitor = TestVisitorFactoryImpl().createClassVisitor(ctx, visitor)
- check(returningVisitor is OnClickClassAdapter)
- check(returningVisitor.nextClassVisitor is OnLongClickClassAdapter)
- check(returningVisitor.nextClassVisitor.nextClassVisitor is WebViewClientClassAdapter)
- assertSame(visitor, returningVisitor.nextClassVisitor.nextClassVisitor.nextClassVisitor)
- }
-
- @Test
- fun testConfigClassVisitorReturned() {
- val visitor = TestClassVisitor()
- val ctx =
- createMockClassContext(
- "io.embrace.android.embracesdk.internal.config.instrumented.EnabledFeatureConfigImpl"
- )
- val returningVisitor = TestVisitorFactoryImpl().createClassVisitor(ctx, visitor)
- check(returningVisitor is OnClickClassAdapter)
- check(returningVisitor.nextClassVisitor is OnLongClickClassAdapter)
- check(returningVisitor.nextClassVisitor.nextClassVisitor is ConfigInstrumentationClassVisitor)
- }
-
- @Test
- fun testOkHttpClassVisitorReturned() {
- val visitor = TestClassVisitor()
- val ctx = createMockClassContext("okhttp3.OkHttpClient\$Builder")
- val returningVisitor = TestVisitorFactoryImpl().createClassVisitor(ctx, visitor)
- check(returningVisitor is OnClickClassAdapter)
- check(returningVisitor.nextClassVisitor is OnLongClickClassAdapter)
- check(returningVisitor.nextClassVisitor.nextClassVisitor is OkHttpClassAdapter)
- assertSame(visitor, returningVisitor.nextClassVisitor.nextClassVisitor.nextClassVisitor)
- }
-
- @Test
- fun testFCMClassVisitorReturned() {
- val visitor = TestClassVisitor()
- val ctx = createMockClassContext("com.google.firebase.messaging.FirebaseMessagingService")
- val params = TestBytecodeInstrumentationParams(instrumentFirebaseMessaging = true)
- val returningVisitor = TestVisitorFactoryImpl(params = params).createClassVisitor(ctx, visitor)
- check(returningVisitor is OnClickClassAdapter)
- check(returningVisitor.nextClassVisitor is OnLongClickClassAdapter)
- check(returningVisitor.nextClassVisitor.nextClassVisitor is FirebaseMessagingServiceClassAdapter)
- assertSame(visitor, returningVisitor.nextClassVisitor.nextClassVisitor.nextClassVisitor)
- }
-
@Test
fun testAsmApiEnabled() {
val factory = TestVisitorFactoryImpl(params = TestBytecodeInstrumentationParams(disabled = false))
@@ -111,25 +43,6 @@ class EmbraceClassVisitorFactoryTest {
assertFalse(factory.isInstrumentable(clzDataBool))
}
- @Test
- fun testOnClickVisitorDisabled() {
- val visitor = TestClassVisitor()
- val ctx = TestClassContext(clzDataString)
- val config = createInstrumentationConfig(instrumentOnClick = false)
- val observed = fetchClassVisitor(config, ctx, visitor)
- assertTrue(observed is OnLongClickClassAdapter)
- }
-
- @Test
- fun testOnLongClickVisitorDisabled() {
- val visitor = TestClassVisitor()
- val ctx = TestClassContext(clzDataString)
- val config = createInstrumentationConfig(instrumentOnLongClick = false)
- val observed = fetchClassVisitor(config, ctx, visitor)
- check(observed is OnClickClassAdapter)
- check(observed.nextClassVisitor is TestClassVisitor)
- }
-
@Test
fun testWebViewClassVisitorDisabled() {
val visitor = TestClassVisitor()
diff --git a/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/config/arch/InstrumentedConfigClassTest.kt b/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/config/arch/InstrumentedConfigClassTest.kt
index ee782dc179..1f9ef7b26d 100644
--- a/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/config/arch/InstrumentedConfigClassTest.kt
+++ b/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/config/arch/InstrumentedConfigClassTest.kt
@@ -5,7 +5,6 @@ import io.embrace.android.gradle.plugin.instrumentation.config.BooleanReturnValu
import io.embrace.android.gradle.plugin.instrumentation.config.IntReturnValueMethodVisitor
import io.embrace.android.gradle.plugin.instrumentation.config.LongReturnValueMethodVisitor
import io.embrace.android.gradle.plugin.instrumentation.config.MapReturnValueMethodVisitor
-import io.embrace.android.gradle.plugin.instrumentation.config.StringListReturnValueMethodVisitor
import io.embrace.android.gradle.plugin.instrumentation.config.StringReturnValueMethodVisitor
import io.mockk.mockk
import org.junit.Assert.assertEquals
diff --git a/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OkHttpClassAdapterTest.kt b/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OkHttpClassAdapterTest.kt
deleted file mode 100644
index 2dca27dd4e..0000000000
--- a/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OkHttpClassAdapterTest.kt
+++ /dev/null
@@ -1,51 +0,0 @@
-package io.embrace.android.gradle.plugin.instrumentation.visitor
-
-import io.embrace.android.gradle.plugin.instrumentation.ASM_API_VERSION
-import org.junit.Assert.assertFalse
-import org.junit.Assert.assertTrue
-import org.junit.Test
-import org.objectweb.asm.Opcodes
-
-class OkHttpClassAdapterTest {
-
- private val adapter = OkHttpClassAdapter(ASM_API_VERSION, null) {}
-
- @Test
- fun testCtorVisited() {
- val visitor = adapter.visitMethod(Opcodes.ACC_PUBLIC, "", "()V", null, emptyArray())
- assertFalse(visitor is OkHttpMethodAdapter)
- }
-
- @Test
- fun testBuildVisited() {
- val visitor = adapter.visitMethod(
- Opcodes.ACC_PUBLIC,
- "build",
- "()Lokhttp3/OkHttpClient;",
- null,
- emptyArray()
- )
- assertTrue(visitor is OkHttpMethodAdapter)
- }
-
- @Test
- fun testMethodNotVisited() {
- var visitor = adapter.visitMethod(
- Opcodes.ACC_PUBLIC,
- "foo",
- "()Lokhttp3/OkHttpClient;",
- null,
- emptyArray()
- )
- assertFalse(visitor is OkHttpMethodAdapter)
-
- visitor = adapter.visitMethod(
- Opcodes.ACC_PUBLIC,
- "build",
- "()Lokhttp3/OkHttpClient\$Builder;",
- null,
- emptyArray()
- )
- assertFalse(visitor is OkHttpMethodAdapter)
- }
-}
diff --git a/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OkHttpConfigMethodAdapterTest.kt b/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OkHttpConfigMethodAdapterTest.kt
deleted file mode 100644
index 1476a14a59..0000000000
--- a/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OkHttpConfigMethodAdapterTest.kt
+++ /dev/null
@@ -1,29 +0,0 @@
-package io.embrace.android.gradle.plugin.instrumentation.visitor
-
-import io.mockk.mockk
-import io.mockk.verify
-import org.junit.Test
-import org.objectweb.asm.MethodVisitor
-import org.objectweb.asm.Opcodes
-
-class OkHttpConfigMethodAdapterTest {
-
- @Test
- fun visitCode() {
- val visitor = mockk(relaxed = true)
- OkHttpMethodAdapter(Opcodes.ASM6, visitor).visitCode()
- verify(exactly = 1) {
- with(visitor) {
- visitVarInsn(Opcodes.ALOAD, 0)
- visitMethodInsn(
- Opcodes.INVOKESTATIC,
- "io/embrace/android/embracesdk/okhttp3/swazzle/callback/okhttp3/OkHttpClient\$Builder",
- "_preBuild",
- "(Lokhttp3/OkHttpClient\$Builder;)V",
- false
- )
- visitCode()
- }
- }
- }
-}
diff --git a/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnClickClassAdapterTest.kt b/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnClickClassAdapterTest.kt
deleted file mode 100644
index 0104a2b9e6..0000000000
--- a/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnClickClassAdapterTest.kt
+++ /dev/null
@@ -1,47 +0,0 @@
-package io.embrace.android.gradle.plugin.instrumentation.visitor
-
-import io.embrace.android.gradle.plugin.instrumentation.ASM_API_VERSION
-import org.junit.Assert.assertFalse
-import org.junit.Assert.assertTrue
-import org.junit.Test
-import org.objectweb.asm.Opcodes
-
-class OnClickClassAdapterTest {
-
- private val adapter = OnClickClassAdapter(ASM_API_VERSION, null) {}
-
- @Test
- fun testOnClickVisited() {
- val visitor = adapter.visitMethod(
- Opcodes.ACC_PUBLIC,
- "onClick",
- "(Landroid/view/View;)V",
- null,
- emptyArray()
- )
- assertTrue(visitor is OnClickMethodAdapter)
- }
-
- @Test
- fun testStaticOnClickVisited() {
- val access = Opcodes.ACC_STATIC.plus(Opcodes.ACC_SYNTHETIC)
- val visitor =
- adapter.visitMethod(access, "onClick", "(Landroid/view/View;)V", null, emptyArray())
- assertTrue(visitor is OnClickStaticMethodAdapter)
- }
-
- @Test
- fun testMethodNotVisited() {
- var visitor = adapter.visitMethod(Opcodes.ACC_PUBLIC, "onClick", "()V", null, emptyArray())
- assertFalse(visitor is OnClickMethodAdapter)
-
- visitor = adapter.visitMethod(
- Opcodes.ACC_PUBLIC,
- "foo",
- "(Landroid/view/View;)V",
- null,
- emptyArray()
- )
- assertFalse(visitor is OnClickMethodAdapter)
- }
-}
diff --git a/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnClickConfigMethodAdapterTest.kt b/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnClickConfigMethodAdapterTest.kt
deleted file mode 100644
index 9dd6a7608e..0000000000
--- a/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnClickConfigMethodAdapterTest.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-package io.embrace.android.gradle.plugin.instrumentation.visitor
-
-import io.mockk.mockk
-import io.mockk.verify
-import org.junit.Test
-import org.objectweb.asm.MethodVisitor
-import org.objectweb.asm.Opcodes
-
-class OnClickConfigMethodAdapterTest {
-
- @Test
- fun visitCode() {
- val visitor = mockk(relaxed = true)
- OnClickMethodAdapter(Opcodes.ASM6, visitor).visitCode()
- verify(exactly = 1) {
- with(visitor) {
- visitVarInsn(Opcodes.ALOAD, 0)
- visitVarInsn(Opcodes.ALOAD, 1)
- visitMethodInsn(
- Opcodes.INVOKESTATIC,
- "io/embrace/android/embracesdk/ViewSwazzledHooks\$OnClickListener",
- "_preOnClick",
- "(Landroid/view/View\$OnClickListener;Landroid/view/View;)V",
- false
- )
- visitCode()
- }
- }
- }
-}
diff --git a/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnClickStaticConfigMethodAdapterTest.kt b/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnClickStaticConfigMethodAdapterTest.kt
deleted file mode 100644
index 35163cec65..0000000000
--- a/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnClickStaticConfigMethodAdapterTest.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-package io.embrace.android.gradle.plugin.instrumentation.visitor
-
-import io.mockk.mockk
-import io.mockk.verify
-import org.junit.Test
-import org.objectweb.asm.MethodVisitor
-import org.objectweb.asm.Opcodes
-
-class OnClickStaticConfigMethodAdapterTest {
-
- @Test
- fun visitCode() {
- val visitor = mockk(relaxed = true)
- OnClickStaticMethodAdapter(Opcodes.ASM6, visitor).visitCode()
- verify(exactly = 1) {
- with(visitor) {
- visitInsn(Opcodes.ACONST_NULL)
- visitVarInsn(Opcodes.ALOAD, 0)
- visitMethodInsn(
- Opcodes.INVOKESTATIC,
- "io/embrace/android/embracesdk/ViewSwazzledHooks\$OnClickListener",
- "_preOnClick",
- "(Landroid/view/View\$OnClickListener;Landroid/view/View;)V",
- false
- )
- visitCode()
- }
- }
- }
-}
diff --git a/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnLongClickClassAdapterTest.kt b/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnLongClickClassAdapterTest.kt
deleted file mode 100644
index e77d961808..0000000000
--- a/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnLongClickClassAdapterTest.kt
+++ /dev/null
@@ -1,48 +0,0 @@
-package io.embrace.android.gradle.plugin.instrumentation.visitor
-
-import io.embrace.android.gradle.plugin.instrumentation.ASM_API_VERSION
-import org.junit.Assert.assertFalse
-import org.junit.Assert.assertTrue
-import org.junit.Test
-import org.objectweb.asm.Opcodes
-
-class OnLongClickClassAdapterTest {
-
- private val adapter = OnLongClickClassAdapter(ASM_API_VERSION, null) {}
-
- @Test
- fun testOnLongClickVisited() {
- val visitor = adapter.visitMethod(
- Opcodes.ACC_PUBLIC,
- "onLongClick",
- "(Landroid/view/View;)Z",
- null,
- emptyArray()
- )
- assertTrue(visitor is OnLongClickMethodAdapter)
- }
-
- @Test
- fun testStaticOnLongClickVisited() {
- val access = Opcodes.ACC_STATIC.plus(Opcodes.ACC_SYNTHETIC)
- val visitor =
- adapter.visitMethod(access, "onLongClick", "(Landroid/view/View;)Z", null, emptyArray())
- assertTrue(visitor is OnLongClickStaticMethodAdapter)
- }
-
- @Test
- fun testMethodNotVisited() {
- var visitor =
- adapter.visitMethod(Opcodes.ACC_PUBLIC, "onLongClick", "()V", null, emptyArray())
- assertFalse(visitor is OnLongClickMethodAdapter)
-
- visitor = adapter.visitMethod(
- Opcodes.ACC_PUBLIC,
- "foo",
- "(Landroid/view/View;)Z",
- null,
- emptyArray()
- )
- assertFalse(visitor is OnLongClickMethodAdapter)
- }
-}
diff --git a/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnLongClickConfigMethodAdapterTest.kt b/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnLongClickConfigMethodAdapterTest.kt
deleted file mode 100644
index 1392360173..0000000000
--- a/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnLongClickConfigMethodAdapterTest.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-package io.embrace.android.gradle.plugin.instrumentation.visitor
-
-import io.mockk.mockk
-import io.mockk.verify
-import org.junit.Test
-import org.objectweb.asm.MethodVisitor
-import org.objectweb.asm.Opcodes
-
-class OnLongClickConfigMethodAdapterTest {
-
- @Test
- fun visitCode() {
- val visitor = mockk(relaxed = true)
- OnLongClickMethodAdapter(Opcodes.ASM6, visitor).visitCode()
- verify(exactly = 1) {
- with(visitor) {
- visitVarInsn(Opcodes.ALOAD, 0)
- visitVarInsn(Opcodes.ALOAD, 1)
- visitMethodInsn(
- Opcodes.INVOKESTATIC,
- "io/embrace/android/embracesdk/ViewSwazzledHooks\$OnLongClickListener",
- "_preOnLongClick",
- "(Landroid/view/View\$OnLongClickListener;Landroid/view/View;)V",
- false
- )
- visitCode()
- }
- }
- }
-}
diff --git a/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnLongClickStaticConfigMethodAdapterTest.kt b/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnLongClickStaticConfigMethodAdapterTest.kt
deleted file mode 100644
index 75d814367c..0000000000
--- a/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/OnLongClickStaticConfigMethodAdapterTest.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-package io.embrace.android.gradle.plugin.instrumentation.visitor
-
-import io.mockk.mockk
-import io.mockk.verify
-import org.junit.Test
-import org.objectweb.asm.MethodVisitor
-import org.objectweb.asm.Opcodes
-
-class OnLongClickStaticConfigMethodAdapterTest {
-
- @Test
- fun visitCode() {
- val visitor = mockk(relaxed = true)
- OnLongClickStaticMethodAdapter(Opcodes.ASM6, visitor).visitCode()
- verify(exactly = 1) {
- with(visitor) {
- visitInsn(Opcodes.ACONST_NULL)
- visitVarInsn(Opcodes.ALOAD, 0)
- visitMethodInsn(
- Opcodes.INVOKESTATIC,
- "io/embrace/android/embracesdk/ViewSwazzledHooks\$OnLongClickListener",
- "_preOnLongClick",
- "(Landroid/view/View\$OnLongClickListener;Landroid/view/View;)V",
- false
- )
- visitCode()
- }
- }
- }
-}
diff --git a/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/WebViewClientClassAdapterTest.kt b/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/WebViewClientClassAdapterTest.kt
deleted file mode 100644
index 4d4a2a6996..0000000000
--- a/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/WebViewClientClassAdapterTest.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-package io.embrace.android.gradle.plugin.instrumentation.visitor
-
-import io.embrace.android.gradle.plugin.instrumentation.ASM_API_VERSION
-import org.junit.Assert.assertFalse
-import org.junit.Assert.assertTrue
-import org.junit.Test
-import org.objectweb.asm.Opcodes
-
-class WebViewClientClassAdapterTest {
-
- private val adapter = WebViewClientClassAdapter(ASM_API_VERSION, null) {}
-
- @Test
- fun testOnPageStartedVisited() {
- val visitor = adapter.visitMethod(
- Opcodes.ACC_PUBLIC,
- "onPageStarted",
- "(Landroid/webkit/WebView;Ljava/lang/String;Landroid/graphics/Bitmap;)V",
- null,
- emptyArray()
- )
- assertTrue(visitor is WebViewClientMethodAdapter)
- }
-
- @Test
- fun testMethodNotVisited() {
- var visitor = adapter.visitMethod(
- Opcodes.ACC_PUBLIC,
- "onPageStarted",
- "(Landroid/webkit/WebView;Ljava/lang/Boolean;Landroid/graphics/Bitmap;)V",
- null,
- emptyArray()
- )
- assertFalse(visitor is WebViewClientMethodAdapter)
-
- visitor = adapter.visitMethod(
- Opcodes.ACC_PUBLIC,
- "onPageStart",
- "(Landroid/webkit/WebView;Ljava/lang/String;Landroid/graphics/Bitmap;)V",
- null,
- emptyArray()
- )
- assertFalse(visitor is WebViewClientMethodAdapter)
- }
-}
diff --git a/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/WebViewClientMethodAdapterTest.kt b/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/WebViewClientMethodAdapterTest.kt
deleted file mode 100644
index c532d0ddc8..0000000000
--- a/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/WebViewClientMethodAdapterTest.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-package io.embrace.android.gradle.plugin.instrumentation.visitor
-
-import io.mockk.mockk
-import io.mockk.verify
-import org.junit.Test
-import org.objectweb.asm.MethodVisitor
-import org.objectweb.asm.Opcodes
-
-class WebViewClientMethodAdapterTest {
-
- @Test
- fun visitCode() {
- val visitor = mockk(relaxed = true)
- WebViewClientMethodAdapter(Opcodes.ASM6, visitor).visitCode()
- verify(exactly = 1) {
- with(visitor) {
- visitVarInsn(Opcodes.ALOAD, 1)
- visitVarInsn(Opcodes.ALOAD, 2)
- visitVarInsn(Opcodes.ALOAD, 3)
- visitMethodInsn(
- Opcodes.INVOKESTATIC,
- "io/embrace/android/embracesdk/WebViewClientSwazzledHooks",
- "_preOnPageStarted",
- "(Landroid/webkit/WebView;Ljava/lang/String;Landroid/graphics/Bitmap;)V",
- false
- )
- }
- }
- }
-}
diff --git a/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/WebViewClientOverrideConfigMethodAdapterTest.kt b/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/WebViewClientOverrideConfigMethodAdapterTest.kt
deleted file mode 100644
index 78abae800c..0000000000
--- a/embrace-gradle-plugin/src/test/java/io/embrace/android/gradle/plugin/instrumentation/visitor/WebViewClientOverrideConfigMethodAdapterTest.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-package io.embrace.android.gradle.plugin.instrumentation.visitor
-
-import io.mockk.mockk
-import io.mockk.verify
-import org.junit.Test
-import org.objectweb.asm.MethodVisitor
-import org.objectweb.asm.Opcodes
-
-class WebViewClientOverrideConfigMethodAdapterTest {
-
- @Test
- fun visitCode() {
- val visitor = mockk(relaxed = true)
- WebViewClientOverrideMethodAdapter(Opcodes.ASM6, visitor).visitCode()
- verify(exactly = 1) {
- with(visitor) {
- visitVarInsn(Opcodes.ALOAD, 1)
- visitVarInsn(Opcodes.ALOAD, 2)
- visitVarInsn(Opcodes.ALOAD, 3)
- visitMethodInsn(
- Opcodes.INVOKESTATIC,
- "io/embrace/android/embracesdk/WebViewClientSwazzledHooks",
- "_preOnPageStarted",
- "(Landroid/webkit/WebView;Ljava/lang/String;Landroid/graphics/Bitmap;)V",
- false
- )
- }
- }
- }
-}
diff --git a/embrace-test-fakes/lint-baseline.xml b/embrace-test-fakes/lint-baseline.xml
index 333f47a062..f4b541243b 100644
--- a/embrace-test-fakes/lint-baseline.xml
+++ b/embrace-test-fakes/lint-baseline.xml
@@ -1,5 +1,5 @@
-
+
@@ -19,7 +19,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -30,7 +30,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">