From 9fd251c994e788d458d512601c53b952d5431322 Mon Sep 17 00:00:00 2001 From: Roger Yang Date: Fri, 15 May 2020 13:11:24 -0400 Subject: [PATCH] For #6687: Add crash reporting information for ClassCastException in PromptFeature --- .../feature/prompts/PromptFeature.kt | 77 ++++++++++--------- .../feature/prompts/PromptFeatureTest.kt | 24 ++++++ 2 files changed, 65 insertions(+), 36 deletions(-) diff --git a/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/PromptFeature.kt b/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/PromptFeature.kt index b0e6714ba68..e4cc0e208bb 100644 --- a/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/PromptFeature.kt +++ b/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/PromptFeature.kt @@ -312,47 +312,52 @@ class PromptFeature private constructor( @Suppress("UNCHECKED_CAST", "ComplexMethod") override fun onConfirm(sessionId: String, value: Any?) { store.consumePromptFrom(sessionId, activePrompt) { - when (it) { - is TimeSelection -> it.onConfirm(value as Date) - is Color -> it.onConfirm(value as String) - is Alert -> { - val shouldNotShowMoreDialogs = value as Boolean - promptAbuserDetector.userWantsMoreDialogs(!shouldNotShowMoreDialogs) - it.onConfirm(!shouldNotShowMoreDialogs) - } - is SingleChoice -> it.onConfirm(value as Choice) - is MenuChoice -> it.onConfirm(value as Choice) - is PromptRequest.Popup -> it.onAllow() - is MultipleChoice -> it.onConfirm(value as Array) - - is Authentication -> { - val (user, password) = value as Pair - it.onConfirm(user, password) - } - - is TextPrompt -> { - val (shouldNotShowMoreDialogs, text) = value as Pair - - promptAbuserDetector.userWantsMoreDialogs(!shouldNotShowMoreDialogs) - it.onConfirm(!shouldNotShowMoreDialogs, text) - } + try { + when (it) { + is TimeSelection -> it.onConfirm(value as Date) + is Color -> it.onConfirm(value as String) + is Alert -> { + val shouldNotShowMoreDialogs = value as Boolean + promptAbuserDetector.userWantsMoreDialogs(!shouldNotShowMoreDialogs) + it.onConfirm(!shouldNotShowMoreDialogs) + } + is SingleChoice -> it.onConfirm(value as Choice) + is MenuChoice -> it.onConfirm(value as Choice) + is PromptRequest.Popup -> it.onAllow() + is MultipleChoice -> it.onConfirm(value as Array) + + is Authentication -> { + val (user, password) = value as Pair + it.onConfirm(user, password) + } - is Share -> it.onSuccess() + is TextPrompt -> { + val (shouldNotShowMoreDialogs, text) = value as Pair - is LoginPrompt -> it.onConfirm(value as Login) + promptAbuserDetector.userWantsMoreDialogs(!shouldNotShowMoreDialogs) + it.onConfirm(!shouldNotShowMoreDialogs, text) + } - is PromptRequest.Confirm -> { - val (isCheckBoxChecked, buttonType) = value as Pair - promptAbuserDetector.userWantsMoreDialogs(!isCheckBoxChecked) - when (buttonType) { - MultiButtonDialogFragment.ButtonType.POSITIVE -> - it.onConfirmPositiveButton(!isCheckBoxChecked) - MultiButtonDialogFragment.ButtonType.NEGATIVE -> - it.onConfirmNegativeButton(!isCheckBoxChecked) - MultiButtonDialogFragment.ButtonType.NEUTRAL -> - it.onConfirmNeutralButton(!isCheckBoxChecked) + is Share -> it.onSuccess() + + is LoginPrompt -> it.onConfirm(value as Login) + + is PromptRequest.Confirm -> { + val (isCheckBoxChecked, buttonType) = + value as Pair + promptAbuserDetector.userWantsMoreDialogs(!isCheckBoxChecked) + when (buttonType) { + MultiButtonDialogFragment.ButtonType.POSITIVE -> + it.onConfirmPositiveButton(!isCheckBoxChecked) + MultiButtonDialogFragment.ButtonType.NEGATIVE -> + it.onConfirmNegativeButton(!isCheckBoxChecked) + MultiButtonDialogFragment.ButtonType.NEUTRAL -> + it.onConfirmNeutralButton(!isCheckBoxChecked) + } } } + } catch (e: ClassCastException) { + throw IllegalArgumentException("PromptFeature onConsume cast failed with ${it.javaClass}", e) } } } diff --git a/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/PromptFeatureTest.kt b/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/PromptFeatureTest.kt index 773b6318f7f..8999c7db320 100644 --- a/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/PromptFeatureTest.kt +++ b/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/PromptFeatureTest.kt @@ -961,6 +961,30 @@ class PromptFeatureTest { assertFalse(prompt!!.shouldDismissOnLoad()) } + @Test + fun `PromptFeature throws IllegalArgumentException when ClassCastException is triggered`() { + val feature = PromptFeature( + activity = mock(), + store = store, + fragmentManager = fragmentManager + ) { } + feature.start() + + val singleChoiceRequest = SingleChoice(arrayOf()) {} + var illegalArgumentExceptionThrown = false + store.dispatch(ContentAction.UpdatePromptRequestAction(tabId, singleChoiceRequest)).joinBlocking() + + try { + feature.onConfirm(tabId, "wrong") + } catch (e: IllegalArgumentException) { + illegalArgumentExceptionThrown = true + assertEquals("PromptFeature onConsume cast failed with class mozilla.components.concept.engine.prompt.PromptRequest\$SingleChoice", e.message) + } + + store.waitUntilIdle() + assert(illegalArgumentExceptionThrown) + } + private fun mockFragmentManager(): FragmentManager { val fragmentManager: FragmentManager = mock() val transaction: FragmentTransaction = mock()