Skip to content
This repository was archived by the owner on Jun 17, 2024. It is now read-only.
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
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ typealias GECKO_AUTH_LEVEL = PromptDelegate.AuthPrompt.AuthOptions.Level
typealias GECKO_PROMPT_FILE_TYPE = PromptDelegate.FilePrompt.Type
typealias GECKO_PROMPT_PROVIDER_SELECTOR = ProviderSelectorPrompt.Provider
typealias GECKO_PROMPT_ACCOUNT_SELECTOR = AccountSelectorPrompt.Account
typealias GECKO_PROMPT_ACCOUNT_SELECTOR_PROVIDER = AccountSelectorPrompt.Provider
typealias GECKO_PROMPT_CHOICE_TYPE = PromptDelegate.ChoicePrompt.Type
typealias GECKO_PROMPT_FILE_CAPTURE = PromptDelegate.FilePrompt.Capture
typealias GECKO_PROMPT_SHARE_RESULT = PromptDelegate.SharePrompt.Result
Expand Down Expand Up @@ -132,6 +133,7 @@ internal class GeckoPromptDelegate(private val geckoEngineSession: GeckoEngineSe
onPromptRequest(
PromptRequest.IdentityCredential.SelectAccount(
accounts = prompt.accounts.map { it.toAccount() },
provider = prompt.provider.let { it.toProvider() },
onConfirm = onConfirm,
onDismiss = onDismiss,
),
Expand Down Expand Up @@ -912,10 +914,15 @@ internal fun PromptDelegate.BasePrompt.dismissSafely(geckoResult: GeckoResult<Pr

@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
internal fun GECKO_PROMPT_PROVIDER_SELECTOR.toProvider(): Provider {
return Provider(id, icon, name)
return Provider(id, icon, name, domain)
}

@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
internal fun GECKO_PROMPT_ACCOUNT_SELECTOR.toAccount(): Account {
return Account(id, email, name, icon)
}

@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
internal fun GECKO_PROMPT_ACCOUNT_SELECTOR_PROVIDER.toProvider(): Provider {
return Provider(0, icon, name, domain)
}
Original file line number Diff line number Diff line change
Expand Up @@ -1254,8 +1254,9 @@ class GeckoPromptDelegateTest {
)

val geckoAccount = GECKO_PROMPT_ACCOUNT_SELECTOR(0, "foo@mozilla.org", "foo", "icon")
val provider = GECKO_PROMPT_ACCOUNT_SELECTOR_PROVIDER("name", "domain", "favicon")
val acAccount = geckoAccount.toAccount()
val geckoPrompt = geckoAccountSelectorPrompt(listOf(geckoAccount))
val geckoPrompt = geckoAccountSelectorPrompt(listOf(geckoAccount), provider)
var geckoResult = promptDelegate.onSelectIdentityCredentialAccount(mock(), geckoPrompt)

geckoResult.accept {
Expand All @@ -1280,7 +1281,7 @@ class GeckoPromptDelegateTest {
}

// Verifying we are handling the dismiss correctly.
geckoResult = promptDelegate.onSelectIdentityCredentialAccount(mock(), geckoAccountSelectorPrompt(listOf(geckoAccount)))
geckoResult = promptDelegate.onSelectIdentityCredentialAccount(mock(), geckoAccountSelectorPrompt(listOf(geckoAccount), provider))
geckoResult.accept {
onDismissWasCalled = true
}
Expand Down Expand Up @@ -2012,9 +2013,11 @@ class GeckoPromptDelegateTest {

private fun geckoAccountSelectorPrompt(
accounts: List<GECKO_PROMPT_ACCOUNT_SELECTOR> = emptyList(),
provider: GECKO_PROMPT_ACCOUNT_SELECTOR_PROVIDER,
): GeckoSession.PromptDelegate.IdentityCredential.AccountSelectorPrompt {
val prompt: GeckoSession.PromptDelegate.IdentityCredential.AccountSelectorPrompt = mock()
ReflectionUtils.setField(prompt, "accounts", accounts.toTypedArray())
ReflectionUtils.setField(prompt, "provider", provider)
return prompt
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,13 @@ sealed class PromptRequest(
/**
* Value type that represents Identity Credential request for selecting an [Account] prompt.
* @property accounts A list of accounts which the user could select from.
* @property providerName The name of the provider that will be used for the login
* @property onConfirm callback to let the page know the user selected an account.
* @property onDismiss callback to let the page know the user dismissed the dialog.
*/
data class SelectAccount(
val accounts: List<Account>,
val provider: Provider,
val onConfirm: (Account) -> Unit,
override val onDismiss: () -> Unit,
) : IdentityCredential(onDismiss), Dismissible
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ data class Provider(
val id: Int,
val icon: String?,
val name: String,
val domain: String,
) : Parcelable
17 changes: 17 additions & 0 deletions android-components/components/feature/prompts/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ android {
}
}

composeOptions {
kotlinCompilerExtensionVersion = Versions.compose_compiler
}

buildFeatures {
compose true
}

namespace 'mozilla.components.feature.prompts'
}

Expand All @@ -39,11 +47,20 @@ dependencies {
implementation project(':support-utils')
implementation project(':ui-icons')
implementation project(':ui-widgets')
implementation project(':ui-colors')

implementation ComponentsDependencies.androidx_constraintlayout
implementation ComponentsDependencies.androidx_core_ktx
implementation ComponentsDependencies.google_material

implementation ComponentsDependencies.androidx_core_ktx
implementation ComponentsDependencies.androidx_compose_ui
implementation ComponentsDependencies.androidx_compose_ui_tooling_preview
implementation ComponentsDependencies.androidx_compose_foundation
implementation ComponentsDependencies.androidx_compose_material

debugImplementation ComponentsDependencies.androidx_compose_ui_tooling

testImplementation ComponentsDependencies.androidx_test_core
testImplementation ComponentsDependencies.androidx_test_junit
testImplementation ComponentsDependencies.testing_coroutines
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ import mozilla.components.feature.prompts.facts.emitPromptDisplayedFact
import mozilla.components.feature.prompts.facts.emitSuccessfulAddressAutofillFormDetectedFact
import mozilla.components.feature.prompts.facts.emitSuccessfulCreditCardAutofillFormDetectedFact
import mozilla.components.feature.prompts.file.FilePicker
import mozilla.components.feature.prompts.identitycredential.DialogColors
import mozilla.components.feature.prompts.identitycredential.DialogColorsProvider
import mozilla.components.feature.prompts.identitycredential.PrivacyPolicyDialogFragment
import mozilla.components.feature.prompts.identitycredential.SelectAccountDialogFragment
import mozilla.components.feature.prompts.identitycredential.SelectProviderDialogFragment
Expand Down Expand Up @@ -154,6 +156,9 @@ class PromptFeature private constructor(
private val store: BrowserStore,
private var customTabId: String?,
private val fragmentManager: FragmentManager,
private val identityCredentialColorsProvider: DialogColorsProvider = DialogColorsProvider {
DialogColors.default()
},
private val tabsUseCases: TabsUseCases,
private val shareDelegate: ShareDelegate,
private val exitFullscreenUsecase: ExitFullScreenUseCase = SessionUseCases(store).exitFullscreen,
Expand Down Expand Up @@ -197,6 +202,7 @@ class PromptFeature private constructor(
customTabId: String? = null,
fragmentManager: FragmentManager,
tabsUseCases: TabsUseCases,
identityCredentialColorsProvider: DialogColorsProvider = DialogColorsProvider { DialogColors.default() },
shareDelegate: ShareDelegate = DefaultShareDelegate(),
exitFullscreenUsecase: ExitFullScreenUseCase = SessionUseCases(store).exitFullscreen,
creditCardValidationDelegate: CreditCardValidationDelegate? = null,
Expand All @@ -215,6 +221,7 @@ class PromptFeature private constructor(
customTabId = customTabId,
fragmentManager = fragmentManager,
tabsUseCases = tabsUseCases,
identityCredentialColorsProvider = identityCredentialColorsProvider,
shareDelegate = shareDelegate,
exitFullscreenUsecase = exitFullscreenUsecase,
creditCardValidationDelegate = creditCardValidationDelegate,
Expand Down Expand Up @@ -335,22 +342,27 @@ class PromptFeature private constructor(
is SelectLoginPrompt -> {
loginPicker?.dismissCurrentLoginSelect(activePromptRequest as SelectLoginPrompt)
}

is SaveLoginPrompt -> {
(activePrompt?.get() as? SaveLoginDialogFragment)?.dismissAllowingStateLoss()
}

is SaveCreditCard -> {
(activePrompt?.get() as? CreditCardSaveDialogFragment)?.dismissAllowingStateLoss()
}

is SelectCreditCard -> {
creditCardPicker?.dismissSelectCreditCardRequest(
activePromptRequest as SelectCreditCard,
)
}

is SelectAddress -> {
addressPicker?.dismissSelectAddressRequest(
activePromptRequest as SelectAddress,
)
}

is SingleChoice,
is MultipleChoice,
is MenuChoice,
Expand All @@ -364,6 +376,7 @@ class PromptFeature private constructor(
}
}
}

else -> {
// no-op
}
Expand Down Expand Up @@ -493,25 +506,29 @@ class PromptFeature private constructor(
emitPromptDisplayedFact(promptName = "FilePrompt")
filePicker.handleFileRequest(promptRequest)
}

is Share -> handleShareRequest(promptRequest, session)
is SelectCreditCard -> {
emitSuccessfulCreditCardAutofillFormDetectedFact()
if (isCreditCardAutofillEnabled() && promptRequest.creditCards.isNotEmpty()) {
creditCardPicker?.handleSelectCreditCardRequest(promptRequest)
}
}

is SelectLoginPrompt -> {
emitPromptDisplayedFact(promptName = "SelectLoginPrompt")
if (promptRequest.logins.isNotEmpty()) {
loginPicker?.handleSelectLoginRequest(promptRequest)
}
}

is SelectAddress -> {
emitSuccessfulAddressAutofillFormDetectedFact()
if (isAddressAutofillEnabled() && promptRequest.addresses.isNotEmpty()) {
addressPicker?.handleSelectAddressRequest(promptRequest)
}
}

else -> handleDialogsRequest(promptRequest, session)
}
}
Expand All @@ -535,6 +552,7 @@ class PromptFeature private constructor(
promptAbuserDetector.userWantsMoreDialogs(!shouldNotShowMoreDialogs)
it.onDeny()
}

is Dismissible -> it.onDismiss()
else -> {
// no-op
Expand Down Expand Up @@ -562,6 +580,7 @@ class PromptFeature private constructor(
promptAbuserDetector.userWantsMoreDialogs(!shouldNotShowMoreDialogs)
it.onConfirm(!shouldNotShowMoreDialogs)
}

is SingleChoice -> it.onConfirm(value as Choice)
is MenuChoice -> it.onConfirm(value as Choice)
is BeforeUnload -> it.onLeave()
Expand All @@ -570,6 +589,7 @@ class PromptFeature private constructor(
promptAbuserDetector.userWantsMoreDialogs(!shouldNotShowMoreDialogs)
it.onAllow()
}

is MultipleChoice -> it.onConfirm(value as Array<Choice>)

is Authentication -> {
Expand All @@ -596,8 +616,10 @@ class PromptFeature private constructor(
when (buttonType) {
MultiButtonDialogFragment.ButtonType.POSITIVE ->
it.onConfirmPositiveButton(!isCheckBoxChecked)

MultiButtonDialogFragment.ButtonType.NEGATIVE ->
it.onConfirmNegativeButton(!isCheckBoxChecked)

MultiButtonDialogFragment.ButtonType.NEUTRAL ->
it.onConfirmNeutralButton(!isCheckBoxChecked)
}
Expand Down Expand Up @@ -838,6 +860,7 @@ class PromptFeature private constructor(
shouldDismissOnLoad = true,
)
}

is BeforeUnload -> {
val title =
container.getString(R.string.mozac_feature_prompt_before_unload_dialog_title)
Expand Down Expand Up @@ -912,6 +935,7 @@ class PromptFeature private constructor(
promptRequestUID = promptRequest.uid,
shouldDismissOnLoad = true,
providers = promptRequest.providers,
colorsProvider = identityCredentialColorsProvider,
)
}

Expand All @@ -921,6 +945,8 @@ class PromptFeature private constructor(
promptRequestUID = promptRequest.uid,
shouldDismissOnLoad = true,
accounts = promptRequest.accounts,
provider = promptRequest.provider,
colorsProvider = identityCredentialColorsProvider,
)
}

Expand Down Expand Up @@ -1014,6 +1040,7 @@ class PromptFeature private constructor(
is PromptRequest.IdentityCredential.SelectAccount,
is PromptRequest.IdentityCredential.PrivacyPolicy,
-> true

is Alert, is TextPrompt, is Confirm, is Repost, is Popup -> promptAbuserDetector.shouldShowMoreDialogs
}
}
Expand Down

This file was deleted.

Loading