From df1f6df2bd0b0a36228393a7d06b80cb855b18b3 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Wed, 21 Oct 2026 09:35:59 +0200 Subject: [PATCH 1/2] ref(feedback): Extend Dialog instead of AlertDialog in SentryUserFeedbackForm The form never used AlertDialog's title, message, buttons or custom view; it replaces the content with its own layout in onCreate. Dialog falls back to dialogTheme for theme 0, while AlertDialog uses alertDialogTheme, so the form now resolves alertDialogTheme itself to keep the default look unchanged. The FLAG_ALT_FOCUSABLE_IM workaround goes away because only AlertDialog set that flag. Resolves JAVA-494 Co-Authored-By: Claude Opus 5.5 --- .../api/sentry-android-core.api | 2 +- .../android/core/SentryUserFeedbackForm.java | 26 ++++++++++++------- .../core/SentryUserFeedbackFormTest.kt | 17 ++++++++++++ 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/sentry-android-core/api/sentry-android-core.api b/sentry-android-core/api/sentry-android-core.api index 3e37f1fc39..5be86ecdda 100644 --- a/sentry-android-core/api/sentry-android-core.api +++ b/sentry-android-core/api/sentry-android-core.api @@ -576,7 +576,7 @@ public abstract interface class io/sentry/android/core/SentryShakeDetector$Liste public abstract fun onShake ()V } -public class io/sentry/android/core/SentryUserFeedbackForm : android/app/AlertDialog { +public class io/sentry/android/core/SentryUserFeedbackForm : android/app/Dialog { protected fun onCreate (Landroid/os/Bundle;)V public fun onDetachedFromWindow ()V protected fun onStart ()V diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/SentryUserFeedbackForm.java b/sentry-android-core/src/main/java/io/sentry/android/core/SentryUserFeedbackForm.java index 7da33575de..b3e012020d 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/SentryUserFeedbackForm.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/SentryUserFeedbackForm.java @@ -1,8 +1,8 @@ package io.sentry.android.core; import android.app.Activity; -import android.app.AlertDialog; import android.app.Application; +import android.app.Dialog; import android.content.ContentResolver; import android.content.Context; import android.content.ContextWrapper; @@ -10,9 +10,8 @@ import android.net.Uri; import android.os.Bundle; import android.provider.OpenableColumns; +import android.util.TypedValue; import android.view.View; -import android.view.Window; -import android.view.WindowManager; import android.webkit.MimeTypeMap; import android.widget.Button; import android.widget.EditText; @@ -39,7 +38,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class SentryUserFeedbackForm extends AlertDialog { +public class SentryUserFeedbackForm extends Dialog { private boolean isCancelable = false; private @Nullable SentryId currentReplayId; @@ -60,7 +59,7 @@ public class SentryUserFeedbackForm extends AlertDialog { final @Nullable SentryId associatedEventId, final @Nullable OptionsConfiguration configuration, final @Nullable SentryFeedbackOptions.OptionsConfigurator configurator) { - super(context, themeResId); + super(context, resolveTheme(context, themeResId)); this.associatedEventId = associatedEventId; final @NotNull SentryOptions options = Sentry.getCurrentScopes().getOptions(); @NotNull @@ -211,6 +210,19 @@ public void onActivitySaveInstanceState( final @NotNull Activity activity, final @NotNull Bundle outState) {} } + /** + * {@link Dialog} falls back to {@link android.R.attr#dialogTheme} for {@code 0}, but the form has + * always defaulted to {@link android.R.attr#alertDialogTheme}, as {@code AlertDialog} does. + */ + static int resolveTheme(final @NotNull Context context, final int themeResId) { + if (themeResId != 0) { + return themeResId; + } + final @NotNull TypedValue outValue = new TypedValue(); + context.getTheme().resolveAttribute(android.R.attr.alertDialogTheme, outValue, true); + return outValue.resourceId; + } + @Override public void setCancelable(boolean cancelable) { super.setCancelable(cancelable); @@ -222,10 +234,6 @@ public void setCancelable(boolean cancelable) { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.sentry_dialog_user_feedback); - final @Nullable Window window = getWindow(); - if (window != null) { - window.clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); - } setCancelable(isCancelable); final @NotNull SentryFeedbackOptions feedbackOptions = resolvedFeedbackOptions; diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/SentryUserFeedbackFormTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/SentryUserFeedbackFormTest.kt index 19414515b8..86e7367bd7 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/SentryUserFeedbackFormTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/SentryUserFeedbackFormTest.kt @@ -10,6 +10,7 @@ import android.database.Cursor import android.net.Uri import android.os.Looper import android.provider.OpenableColumns +import android.view.ContextThemeWrapper import android.view.View import android.view.WindowManager import android.widget.Button @@ -244,6 +245,22 @@ class SentryUserFeedbackFormTest { assertEquals(0, flags and WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM) } + @Test + fun `default theme resolves to the context's alert dialog theme`() { + val context = ContextThemeWrapper(fixture.application, android.R.style.Theme_Material_Light) + + assertThat(SentryUserFeedbackForm.resolveTheme(context, 0)) + .isEqualTo(android.R.style.Theme_Material_Light_Dialog_Alert) + } + + @Test + fun `explicit theme is used as is`() { + val context = ContextThemeWrapper(fixture.application, android.R.style.Theme_Material_Light) + + assertThat(SentryUserFeedbackForm.resolveTheme(context, android.R.style.Theme_Material_Dialog)) + .isEqualTo(android.R.style.Theme_Material_Dialog) + } + @Test fun `a crashing onFormClose callback does not crash the app when the dialog is closed`() { fixture.options.isEnabled = true From 0eb768539b32b30dc70c2ccfcab3bba6573db691 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Wed, 21 Oct 2026 09:36:11 +0200 Subject: [PATCH 2/2] changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4db4ef4c06..52e6caf065 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ - `Sentry.showUserFeedbackDialog(...)`: use `Sentry.feedback().show(...)` instead - Android: `SentryUserFeedbackDialog`: use `SentryUserFeedbackForm` instead - Android: the `SentryUserFeedbackButton` view and composable: call `Sentry.feedback().show()` from your own button instead +- `SentryUserFeedbackForm` now extends `android.app.Dialog` instead of `android.app.AlertDialog` ([#6338](https://github.com/getsentry/sentry-java/pull/6338)) + - The form never used `AlertDialog` features. Code that calls `AlertDialog`-only methods on it, such as `setButton` or `setMessage`, no longer compiles. ### Fixes