diff --git a/CHANGELOG.md b/CHANGELOG.md index b317c287b61..2df43f37042 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ - Fix unregister `SystemEventsBroadcastReceiver` when entering background ([#4338](https://github.com/getsentry/sentry-java/pull/4338)) - This should reduce ANRs seen with this class in the stack trace for Android 14 and above +### Improvements + +- Make user interaction tracing faster and do fewer allocations ([#4347](https://github.com/getsentry/sentry-java/pull/4347)) + ## 8.8.0 ### Features diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/internal/gestures/ViewUtils.java b/sentry-android-core/src/main/java/io/sentry/android/core/internal/gestures/ViewUtils.java index 8aa8e89d694..501a05a5007 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/internal/gestures/ViewUtils.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/internal/gestures/ViewUtils.java @@ -8,6 +8,7 @@ import io.sentry.internal.gestures.GestureTargetLocator; import io.sentry.internal.gestures.UiElement; import java.util.LinkedList; +import java.util.List; import java.util.Queue; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -60,6 +61,7 @@ private static boolean touchWithinBounds( final float y, final UiElement.Type targetType) { + final List locators = options.getGestureTargetLocators(); final Queue queue = new LinkedList<>(); queue.add(decorView); @@ -79,7 +81,8 @@ private static boolean touchWithinBounds( } } - for (GestureTargetLocator locator : options.getGestureTargetLocators()) { + for (int i = 0; i < locators.size(); i++) { + final GestureTargetLocator locator = locators.get(i); final @Nullable UiElement newTarget = locator.locate(view, x, y, targetType); if (newTarget != null) { if (targetType == UiElement.Type.CLICKABLE) { diff --git a/sentry-compose/proguard-rules.pro b/sentry-compose/proguard-rules.pro index 666251ddda0..e6f6b1c8b25 100644 --- a/sentry-compose/proguard-rules.pro +++ b/sentry-compose/proguard-rules.pro @@ -13,7 +13,7 @@ -keepnames class androidx.compose.foundation.CombinedClickableElement -keepnames class androidx.compose.foundation.ScrollingLayoutElement -keepnames class androidx.compose.ui.platform.TestTagElement { *; } --keepnames class io.sentry.compose.SentryModifier.SentryTagModifierNodeElement { *; } +-keepnames class io.sentry.compose.SentryModifier$SentryTagModifierNodeElement { *; } # R8 will warn about missing classes if people don't have androidx.compose-navigation on their # classpath, but this is fine, these classes are used in an internal class which is only used when diff --git a/sentry-compose/src/androidMain/kotlin/io/sentry/compose/SentryComposeHelper.kt b/sentry-compose/src/androidMain/kotlin/io/sentry/compose/SentryComposeHelper.kt index c22ef056752..9064d821fc5 100644 --- a/sentry-compose/src/androidMain/kotlin/io/sentry/compose/SentryComposeHelper.kt +++ b/sentry-compose/src/androidMain/kotlin/io/sentry/compose/SentryComposeHelper.kt @@ -18,10 +18,10 @@ internal class SentryComposeHelper(logger: ILogger) { loadField(logger, "androidx.compose.ui.platform.TestTagElement", "tag") private val sentryTagElementField: Field? = - loadField(logger, "io.sentry.compose.SentryModifier.SentryTagModifierNodeElement", "tag") + loadField(logger, "io.sentry.compose.SentryModifier${'$'}SentryTagModifierNodeElement", "tag") fun extractTag(modifier: Modifier): String? { - val type = modifier.javaClass.canonicalName + val type = modifier.javaClass.name // Newer Jetpack Compose uses TestTagElement as node elements // See // https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/TestTag.kt;l=34;drc=dcaa116fbfda77e64a319e1668056ce3b032469f @@ -31,7 +31,7 @@ internal class SentryComposeHelper(logger: ILogger) { ) { val value = testTagElementField.get(modifier) return value as String? - } else if ("io.sentry.compose.SentryModifier.SentryTagModifierNodeElement" == type && + } else if ("io.sentry.compose.SentryModifier${'$'}SentryTagModifierNodeElement" == type && sentryTagElementField != null ) { val value = sentryTagElementField.get(modifier) diff --git a/sentry-compose/src/androidMain/kotlin/io/sentry/compose/gestures/ComposeGestureTargetLocator.kt b/sentry-compose/src/androidMain/kotlin/io/sentry/compose/gestures/ComposeGestureTargetLocator.kt index d630bf6ed3b..81e711a8ded 100644 --- a/sentry-compose/src/androidMain/kotlin/io/sentry/compose/gestures/ComposeGestureTargetLocator.kt +++ b/sentry-compose/src/androidMain/kotlin/io/sentry/compose/gestures/ComposeGestureTargetLocator.kt @@ -70,7 +70,8 @@ public class ComposeGestureTargetLocator(private val logger: ILogger) : GestureT var isScrollable = false val modifiers = node.getModifierInfo() - for (modifierInfo in modifiers) { + for (index in modifiers.indices) { + val modifierInfo = modifiers[index] val tag = composeHelper!!.extractTag(modifierInfo.modifier) if (tag != null) { lastKnownTag = tag @@ -93,7 +94,7 @@ public class ComposeGestureTargetLocator(private val logger: ILogger) : GestureT } else { val modifier = modifierInfo.modifier // Newer Jetpack Compose 1.5 uses Node modifiers for clicks/scrolls - val type = modifier.javaClass.canonicalName + val type = modifier.javaClass.name if ("androidx.compose.foundation.ClickableElement" == type || "androidx.compose.foundation.CombinedClickableElement" == type ) {