From fc5990d1466d7995e799f4e3e4cc679f572a1bec Mon Sep 17 00:00:00 2001 From: Roman Zavarnitsyn Date: Mon, 2 Mar 2026 11:59:42 +0100 Subject: [PATCH 1/2] fix(gestures): Use peekDecorView to not force view hierarchy construction --- .../gestures/SentryGestureListener.java | 2 +- .../SentryGestureListenerPeekDecorViewTest.kt | 48 +++++++++++++++++++ .../core/internal/gestures/ViewHelpers.kt | 2 +- 3 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerPeekDecorViewTest.kt diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/internal/gestures/SentryGestureListener.java b/sentry-android-core/src/main/java/io/sentry/android/core/internal/gestures/SentryGestureListener.java index cd89db72f5..8caffedad9 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/internal/gestures/SentryGestureListener.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/internal/gestures/SentryGestureListener.java @@ -347,7 +347,7 @@ void applyScope(final @NotNull IScope scope, final @NotNull ITransaction transac return null; } - final View decorView = window.getDecorView(); + final View decorView = window.peekDecorView(); if (decorView == null) { options .getLogger() diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerPeekDecorViewTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerPeekDecorViewTest.kt new file mode 100644 index 0000000000..7b26aa55c7 --- /dev/null +++ b/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerPeekDecorViewTest.kt @@ -0,0 +1,48 @@ +package io.sentry.android.core.internal.gestures + +import android.app.Activity +import android.view.MotionEvent +import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.sentry.Breadcrumb +import io.sentry.IScopes +import io.sentry.android.core.SentryAndroidOptions +import io.sentry.util.LazyEvaluator +import kotlin.test.Test +import kotlin.test.assertNull +import org.junit.runner.RunWith +import org.mockito.kotlin.any +import org.mockito.kotlin.anyOrNull +import org.mockito.kotlin.mock +import org.mockito.kotlin.never +import org.mockito.kotlin.verify +import org.robolectric.Robolectric.buildActivity + +@RunWith(AndroidJUnit4::class) +class SentryGestureListenerPeekDecorViewTest { + + @Test + fun `does not force decor view creation when peekDecorView returns null`() { + // A plain Activity that never calls setContentView — peekDecorView() should return null + val activity = buildActivity(Activity::class.java).create().get() + + // Sanity check: decor view has not been created yet + assertNull(activity.window.peekDecorView()) + + val scopes = mock() + val options = + SentryAndroidOptions().apply { + isEnableUserInteractionBreadcrumbs = true + gestureTargetLocators = listOf(AndroidViewGestureTargetLocator(LazyEvaluator { true })) + dsn = "https://key@sentry.io/proj" + } + + val sut = SentryGestureListener(activity, scopes, options) + sut.onSingleTapUp(mock()) + + // The key assertion: peekDecorView is still null — we did not force view hierarchy creation + assertNull(activity.window.peekDecorView()) + + // And no breadcrumb was captured + verify(scopes, never()).addBreadcrumb(any(), anyOrNull()) + } +} diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/ViewHelpers.kt b/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/ViewHelpers.kt index 86123d0a3a..1a4f28bbe3 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/ViewHelpers.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/ViewHelpers.kt @@ -22,7 +22,7 @@ internal inline fun Window.mockDecorView( finalize: (T) -> Unit = {}, ): T { val view = mockView(id, event, touchWithinBounds, clickable, visible, context, finalize) - whenever(decorView).doReturn(view) + whenever(peekDecorView()).doReturn(view) return view } From 92de08284cde06af1a4551318d4a88312391743b Mon Sep 17 00:00:00 2001 From: Roman Zavarnitsyn Date: Mon, 2 Mar 2026 12:06:12 +0100 Subject: [PATCH 2/2] fix(gestures): Add changelog entry for peekDecorView fix Co-Authored-By: Claude Opus 4.6 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf481f1cca..1cfe00b354 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ ### Fixes - Fix crash when unregistering `SystemEventsBroadcastReceiver` with try-catch block. ([#5106](https://github.com/getsentry/sentry-java/pull/5106)) +- Use `peekDecorView` instead of `getDecorView` in `SentryGestureListener` to avoid forcing view hierarchy construction ([#5134](https://github.com/getsentry/sentry-java/pull/5134)) ## 8.33.0