From b954f7a7a8faca1442f3ab8c5c3dffb418e4fd2e Mon Sep 17 00:00:00 2001 From: Roman Zavarnitsyn Date: Tue, 22 Apr 2025 10:23:33 +0200 Subject: [PATCH 1/2] perf(user-interactions): Make user interaction tracing faster and allocate less --- .../io/sentry/android/core/internal/gestures/ViewUtils.java | 5 ++++- sentry-compose/proguard-rules.pro | 2 +- .../kotlin/io/sentry/compose/SentryComposeHelper.kt | 6 +++--- .../sentry/compose/gestures/ComposeGestureTargetLocator.kt | 5 +++-- 4 files changed, 11 insertions(+), 7 deletions(-) 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 ) { From 43fb28fc18675e8e6218772074bd28b12ecdb264 Mon Sep 17 00:00:00 2001 From: Roman Zavarnitsyn Date: Tue, 22 Apr 2025 11:07:57 +0200 Subject: [PATCH 2/2] Changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index addd4746fe2..1f89909611a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,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