Skip to content

Commit 73afd16

Browse files
committed
Cache internal fields
1 parent aeed04d commit 73afd16

File tree

4 files changed

+42
-22
lines changed

4 files changed

+42
-22
lines changed

sentry-compose-helper/api/sentry-compose-helper.api

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
public class io/sentry/compose/SentryComposeHelper {
22
public fun <init> (Lio/sentry/ILogger;)V
3-
public static fun extractTag (Landroidx/compose/ui/Modifier;)Ljava/lang/String;
3+
public fun extractTag (Landroidx/compose/ui/Modifier;)Ljava/lang/String;
44
public fun getLayoutNodeBoundsInWindow (Landroidx/compose/ui/node/LayoutNode;)Landroidx/compose/ui/geometry/Rect;
55
}
66

sentry-compose-helper/src/jvmMain/java/io/sentry/compose/SentryComposeHelper.java

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.sentry.compose;
22

3+
import androidx.annotation.NonNull;
34
import androidx.compose.ui.Modifier;
45
import androidx.compose.ui.geometry.Rect;
56
import androidx.compose.ui.layout.LayoutCoordinatesKt;
@@ -15,27 +16,32 @@
1516
import org.jetbrains.annotations.NotNull;
1617
import org.jetbrains.annotations.Nullable;
1718

19+
@SuppressWarnings("KotlinInternalInJava")
1820
public class SentryComposeHelper {
1921

2022
private final @NotNull ILogger logger;
21-
private Field layoutDelegateField = null;
23+
private final @Nullable Field layoutDelegateField;
24+
private final @Nullable Field testTagElementField;
25+
private final @Nullable Field sentryTagElementField;
2226

2327
@Nullable
24-
public static String extractTag(final @NotNull Modifier modifier) {
28+
public String extractTag(final @NotNull Modifier modifier) {
2529
final @Nullable String type = modifier.getClass().getCanonicalName();
2630
// Newer Jetpack Compose uses TestTagElement as node elements
2731
// See
2832
// 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
29-
if ("androidx.compose.ui.platform.TestTagElement".equals(type)
30-
|| "io.sentry.compose.SentryModifier.SentryTagModifierNodeElement".equals(type)) {
31-
try {
32-
final Field tagField = modifier.getClass().getDeclaredField("tag");
33-
tagField.setAccessible(true);
34-
final @Nullable Object value = tagField.get(modifier);
33+
try {
34+
if ("androidx.compose.ui.platform.TestTagElement".equals(type)
35+
&& testTagElementField != null) {
36+
final @Nullable Object value = testTagElementField.get(modifier);
37+
return (String) value;
38+
} else if ("io.sentry.compose.SentryModifier.SentryTagModifierNodeElement".equals(type)
39+
&& sentryTagElementField != null) {
40+
final @Nullable Object value = sentryTagElementField.get(modifier);
3541
return (String) value;
36-
} catch (Throwable e) {
37-
// ignored
3842
}
43+
} catch (Throwable e) {
44+
// ignored
3945
}
4046

4147
// Older versions use SemanticsModifier
@@ -56,13 +62,11 @@ public static String extractTag(final @NotNull Modifier modifier) {
5662

5763
public SentryComposeHelper(final @NotNull ILogger logger) {
5864
this.logger = logger;
59-
try {
60-
final Class<?> clazz = Class.forName("androidx.compose.ui.node.LayoutNode");
61-
layoutDelegateField = clazz.getDeclaredField("layoutDelegate");
62-
layoutDelegateField.setAccessible(true);
63-
} catch (Exception e) {
64-
logger.log(SentryLevel.WARNING, "Could not find LayoutNode.layoutDelegate field");
65-
}
65+
layoutDelegateField =
66+
loadField(logger, "androidx.compose.ui.node.LayoutNode", "layoutDelegate");
67+
testTagElementField = loadField(logger, "androidx.compose.ui.platform.TestTagElement", "tag");
68+
sentryTagElementField =
69+
loadField(logger, "io.sentry.compose.SentryModifier.SentryTagModifierNodeElement", "tag");
6670
}
6771

6872
public @Nullable Rect getLayoutNodeBoundsInWindow(@NotNull final LayoutNode node) {
@@ -77,4 +81,18 @@ public SentryComposeHelper(final @NotNull ILogger logger) {
7781
}
7882
return null;
7983
}
84+
85+
@Nullable
86+
private static Field loadField(
87+
@NonNull ILogger logger, final @NotNull String className, final @NotNull String fieldName) {
88+
try {
89+
final Class<?> clazz = Class.forName(className);
90+
final @Nullable Field field = clazz.getDeclaredField(fieldName);
91+
field.setAccessible(true);
92+
return field;
93+
} catch (Exception e) {
94+
logger.log(SentryLevel.WARNING, "Could not load " + className + "." + fieldName + " field");
95+
}
96+
return null;
97+
}
8098
}

sentry-compose-helper/src/jvmMain/java/io/sentry/compose/gestures/ComposeGestureTargetLocator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public ComposeGestureTargetLocator(final @NotNull ILogger logger) {
7676

7777
final List<ModifierInfo> modifiers = node.getModifierInfo();
7878
for (ModifierInfo modifierInfo : modifiers) {
79-
final @Nullable String tag = SentryComposeHelper.extractTag(modifierInfo.getModifier());
79+
final @Nullable String tag = composeHelper.extractTag(modifierInfo.getModifier());
8080
if (tag != null) {
8181
lastKnownTag = tag;
8282
}

sentry-compose-helper/src/jvmMain/java/io/sentry/compose/viewhierarchy/ComposeViewHierarchyExporter.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ private static void addChild(
5555
@NotNull final LayoutNode node) {
5656
if (node.isPlaced()) {
5757
final ViewHierarchyNode vhNode = new ViewHierarchyNode();
58-
setTag(node, vhNode);
58+
setTag(composeHelper, node, vhNode);
5959
setBounds(composeHelper, node, parentNode, vhNode);
6060

6161
if (vhNode.getTag() != null) {
@@ -79,11 +79,13 @@ private static void addChild(
7979
}
8080

8181
private static void setTag(
82-
final @NotNull LayoutNode node, final @NotNull ViewHierarchyNode vhNode) {
82+
final @NotNull SentryComposeHelper helper,
83+
final @NotNull LayoutNode node,
84+
final @NotNull ViewHierarchyNode vhNode) {
8385
// needs to be in-sync with ComposeGestureTargetLocator
8486
final List<ModifierInfo> modifiers = node.getModifierInfo();
8587
for (ModifierInfo modifierInfo : modifiers) {
86-
final @Nullable String tag = SentryComposeHelper.extractTag(modifierInfo.getModifier());
88+
final @Nullable String tag = helper.extractTag(modifierInfo.getModifier());
8789
if (tag != null) {
8890
vhNode.setTag(tag);
8991
}

0 commit comments

Comments
 (0)