diff --git a/CHANGELOG.md b/CHANGELOG.md index 51196c3384..42dba12947 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +### Breaking Changes + +- `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 - Report the number of dropped spans in client reports when a batched span envelope item is discarded, instead of a quantity of 1 (e.g. for Flutter span streaming) ([#6265](https://github.com/getsentry/sentry-java/pull/6265)) diff --git a/sentry-android-core/api/sentry-android-core.api b/sentry-android-core/api/sentry-android-core.api index ae28130248..7c19bfe50a 100644 --- a/sentry-android-core/api/sentry-android-core.api +++ b/sentry-android-core/api/sentry-android-core.api @@ -603,7 +603,7 @@ public class io/sentry/android/core/SentryUserFeedbackDialog$Builder : io/sentry public abstract interface class io/sentry/android/core/SentryUserFeedbackDialog$OptionsConfiguration : io/sentry/android/core/SentryUserFeedbackForm$OptionsConfiguration { } -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