Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

- Remove `AndroidRuntimeManager` StrictMode relaxation to prevent ANRs during SDK init ([#5127](https://github.com/getsentry/sentry-java/pull/5127))
- 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))
- Log an actionable error message when Relay returns HTTP 413 (Content Too Large) ([#5115](https://github.com/getsentry/sentry-java/pull/5115))
- Also switch the client report discard reason for all HTTP 4xx/5xx errors (except 429) from `network_error` to `send_error`
- Trim DSN string before parsing to avoid `URISyntaxException` caused by trailing whitespace ([#5113](https://github.com/getsentry/sentry-java/pull/5113))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
Original file line number Diff line number Diff line change
@@ -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<IScopes>()
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<MotionEvent>())

// 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<Breadcrumb>(), anyOrNull())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ internal inline fun <reified T : View> 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
}

Expand Down
Loading