Commit d50699dd authored by ekager's avatar ekager
Browse files

For #7132 - Update to new Autocomplete API

parent d21bcf74
......@@ -6,7 +6,7 @@ internal object GeckoVersions {
/**
* GeckoView Nightly Version.
*/
const val nightly_version = "78.0.20200525093440"
const val nightly_version = "78.0.20200526023857"
/**
* GeckoView Beta Version.
......
......@@ -88,7 +88,7 @@ internal class GeckoPromptDelegate(private val geckoEngineSession: GeckoEngineSe
geckoEngineSession.notifyObservers {
onPromptRequest(
PromptRequest.LoginPrompt(
PromptRequest.SaveLoginPrompt(
hint = prompt.hint,
logins = prompt.logins.map { it.toLogin() },
onConfirm = onConfirmSave,
......
......@@ -10,7 +10,7 @@ import kotlinx.coroutines.launch
import mozilla.components.concept.storage.Login
import mozilla.components.concept.storage.LoginStorageDelegate
import org.mozilla.geckoview.GeckoResult
import org.mozilla.geckoview.LoginStorage
import org.mozilla.geckoview.Autocomplete
/**
* This class exists only to convert incoming [LoginEntry] arguments into [Login]s, then forward
......@@ -18,14 +18,14 @@ import org.mozilla.geckoview.LoginStorage
* between different versions of GeckoView, by duplicating this wrapper instead.
*/
class GeckoLoginDelegateWrapper(private val storageDelegate: LoginStorageDelegate) :
LoginStorage.Delegate {
Autocomplete.LoginStorageDelegate {
override fun onLoginSave(login: LoginStorage.LoginEntry) {
override fun onLoginSave(login: Autocomplete.LoginEntry) {
storageDelegate.onLoginSave(login.toLogin())
}
override fun onLoginFetch(domain: String): GeckoResult<Array<LoginStorage.LoginEntry>>? {
val result = GeckoResult<Array<LoginStorage.LoginEntry>>()
override fun onLoginFetch(domain: String): GeckoResult<Array<Autocomplete.LoginEntry>>? {
val result = GeckoResult<Array<Autocomplete.LoginEntry>>()
GlobalScope.launch(IO) {
val storedLogins = storageDelegate.onLoginFetch(domain)
......@@ -39,20 +39,12 @@ class GeckoLoginDelegateWrapper(private val storageDelegate: LoginStorageDelegat
return result
}
/**
* This method has not yet been implemented in GV. Once it has, we should add an override to it
* here.
*/
fun onLoginUsed(login: LoginStorage.LoginEntry) {
storageDelegate.onLoginUsed(login.toLogin())
}
}
/**
* Converts a GeckoView [LoginStorage.LoginEntry] to an Android Components [Login]
*/
private fun LoginStorage.LoginEntry.toLogin() = Login(
private fun Autocomplete.LoginEntry.toLogin() = Login(
guid = guid,
origin = origin,
formActionOrigin = formActionOrigin,
......@@ -64,7 +56,7 @@ private fun LoginStorage.LoginEntry.toLogin() = Login(
/**
* Converts an Android Components [Login] to a GeckoView [LoginStorage.LoginEntry]
*/
private fun Login.toLoginEntry() = LoginStorage.LoginEntry.Builder()
private fun Login.toLoginEntry() = Autocomplete.LoginEntry.Builder()
.guid(guid)
.origin(origin)
.formActionOrigin(formActionOrigin)
......
......@@ -29,7 +29,7 @@ import org.mozilla.geckoview.GeckoSession.PromptDelegate.DateTimePrompt.Type.MON
import org.mozilla.geckoview.GeckoSession.PromptDelegate.DateTimePrompt.Type.TIME
import org.mozilla.geckoview.GeckoSession.PromptDelegate.DateTimePrompt.Type.WEEK
import org.mozilla.geckoview.GeckoSession.PromptDelegate.PromptResponse
import org.mozilla.geckoview.LoginStorage
import org.mozilla.geckoview.Autocomplete
import java.io.FileOutputStream
import java.io.IOException
import java.security.InvalidParameterException
......@@ -56,31 +56,56 @@ typealias AC_FILE_FACING_MODE = PromptRequest.File.FacingMode
internal class GeckoPromptDelegate(private val geckoEngineSession: GeckoEngineSession) :
PromptDelegate {
override fun onLoginStoragePrompt(
private fun Autocomplete.LoginEntry.toLogin() = Login(
guid = guid,
origin = origin,
formActionOrigin = formActionOrigin,
httpRealm = httpRealm,
username = username,
password = password
)
private fun Login.toLoginEntry() = Autocomplete.LoginEntry.Builder()
.guid(guid)
.origin(origin)
.formActionOrigin(formActionOrigin)
.httpRealm(httpRealm)
.username(username)
.password(password)
.build()
override fun onLoginSave(
session: GeckoSession,
prompt: PromptDelegate.LoginStoragePrompt
prompt: PromptDelegate.AutocompleteRequest<Autocomplete.LoginSaveOption>
): GeckoResult<PromptResponse>? {
fun LoginStorage.LoginEntry.toLogin() = Login(
guid = guid,
origin = origin,
formActionOrigin = formActionOrigin,
httpRealm = httpRealm,
username = username,
password = password
)
val geckoResult = GeckoResult<PromptResponse>()
val onConfirmSave: (Login) -> Unit = { login ->
geckoResult.complete(prompt.confirm(Autocomplete.LoginSelectOption(login.toLoginEntry())))
}
val onDismiss: () -> Unit = {
geckoResult.complete(prompt.dismiss())
}
fun Login.toLoginEntry() = LoginStorage.LoginEntry.Builder()
.guid(guid)
.origin(origin)
.formActionOrigin(formActionOrigin)
.httpRealm(httpRealm)
.username(username)
.password(password)
.build()
geckoEngineSession.notifyObservers {
onPromptRequest(
PromptRequest.SaveLoginPrompt(
hint = prompt.options[0].hint,
logins = prompt.options.map { it.value.toLogin() },
onConfirm = onConfirmSave,
onDismiss = onDismiss
)
)
}
return geckoResult
}
override fun onLoginSelect(
session: GeckoSession,
prompt: PromptDelegate.AutocompleteRequest<Autocomplete.LoginSelectOption>
): GeckoResult<PromptResponse>? {
val geckoResult = GeckoResult<PromptResponse>()
val onConfirmSave: (Login) -> Unit = { login ->
geckoResult.complete(prompt.confirm(login.toLoginEntry()))
geckoResult.complete(prompt.confirm(Autocomplete.LoginSelectOption(login.toLoginEntry())))
}
val onDismiss: () -> Unit = {
geckoResult.complete(prompt.dismiss())
......@@ -88,9 +113,8 @@ internal class GeckoPromptDelegate(private val geckoEngineSession: GeckoEngineSe
geckoEngineSession.notifyObservers {
onPromptRequest(
PromptRequest.LoginPrompt(
hint = prompt.hint,
logins = prompt.logins.map { it.toLogin() },
PromptRequest.SelectLoginPrompt(
logins = prompt.options.map { it.value.toLogin() },
onConfirm = onConfirmSave,
onDismiss = onDismiss
)
......
......@@ -88,7 +88,7 @@ internal class GeckoPromptDelegate(private val geckoEngineSession: GeckoEngineSe
geckoEngineSession.notifyObservers {
onPromptRequest(
PromptRequest.LoginPrompt(
PromptRequest.SaveLoginPrompt(
hint = prompt.hint,
logins = prompt.logins.map { it.toLogin() },
onConfirm = onConfirmSave,
......
......@@ -54,19 +54,31 @@ sealed class PromptRequest {
) : PromptRequest(), Dismissible
/**
* Value type that represents a request for an login prompt.
* Value type that represents a request for a save login prompt.
* @property hint a value that helps to determine the appropriate prompting behavior.
* @property logins a list of logins that are associated with the current domain.
* @property onDismiss callback to let the page know the user dismissed the dialog.
* @property onConfirm callback that is called when the user wants to save the login.
*/
data class LoginPrompt(
data class SaveLoginPrompt(
val hint: Int,
val logins: List<Login>,
override val onDismiss: () -> Unit,
val onConfirm: (Login) -> Unit
) : PromptRequest(), Dismissible
/**
* Value type that represents a request for a select login prompt.
* @property logins a list of logins that are associated with the current domain.
* @property onDismiss callback to let the page know the user dismissed the dialog.
* @property onConfirm callback that is called when the user wants to save the login.
*/
data class SelectLoginPrompt(
val logins: List<Login>,
override val onDismiss: () -> Unit,
val onConfirm: (Login) -> Unit
) : PromptRequest(), Dismissible
/**
* Value type that represents a request for an alert prompt to enter a message.
* @property title title of the dialog.
......
......@@ -9,6 +9,7 @@ import mozilla.components.concept.engine.prompt.PromptRequest.MenuChoice
import mozilla.components.concept.engine.prompt.PromptRequest.MultipleChoice
import mozilla.components.concept.engine.prompt.PromptRequest.SingleChoice
import mozilla.components.concept.engine.prompt.PromptRequest.TimeSelection.Type
import mozilla.components.concept.storage.Login
import mozilla.components.support.test.mock
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
......@@ -159,5 +160,20 @@ class PromptRequestTest {
confirmRequest.onConfirmPositiveButton(true)
confirmRequest.onConfirmNegativeButton(true)
confirmRequest.onConfirmNeutralButton(true)
val onConfirmLogin: () -> Unit = {}
val onDismissLogin: (Login) -> Unit = {}
val login = Login(null, "origin", username = "username", password = "password")
val loginSaveRequest = PromptRequest.SaveLoginPrompt(0, listOf(login), onConfirmLogin, onDismissLogin)
assertEquals(loginSaveRequest.logins, listOf(login))
assertEquals(loginSaveRequest.hint, 0)
loginSaveRequest.onConfirm(login)
loginSaveRequest.onDismiss()
val loginSelectRequest = PromptRequest.SelectLoginPrompt(listOf(login), onConfirmLogin, onDismissLogin)
assertEquals(loginSelectRequest.logins, listOf(login))
loginSelectRequest.onConfirm(login)
loginSelectRequest.onDismiss()
}
}
......@@ -27,10 +27,14 @@ import mozilla.components.concept.engine.prompt.PromptRequest
import mozilla.components.concept.engine.prompt.PromptRequest.Alert
import mozilla.components.concept.engine.prompt.PromptRequest.Authentication
import mozilla.components.concept.engine.prompt.PromptRequest.Color
import mozilla.components.concept.engine.prompt.PromptRequest.Confirm
import mozilla.components.concept.engine.prompt.PromptRequest.Dismissible
import mozilla.components.concept.engine.prompt.PromptRequest.File
import mozilla.components.concept.engine.prompt.PromptRequest.LoginPrompt
import mozilla.components.concept.engine.prompt.PromptRequest.MenuChoice
import mozilla.components.concept.engine.prompt.PromptRequest.MultipleChoice
import mozilla.components.concept.engine.prompt.PromptRequest.Popup
import mozilla.components.concept.engine.prompt.PromptRequest.SaveLoginPrompt
import mozilla.components.concept.engine.prompt.PromptRequest.SelectLoginPrompt
import mozilla.components.concept.engine.prompt.PromptRequest.Share
import mozilla.components.concept.engine.prompt.PromptRequest.SingleChoice
import mozilla.components.concept.engine.prompt.PromptRequest.TextPrompt
......@@ -296,8 +300,8 @@ class PromptFeature private constructor(
override fun onCancel(sessionId: String) {
store.consumePromptFrom(sessionId, activePrompt) {
when (it) {
is PromptRequest.Dismissible -> it.onDismiss()
is PromptRequest.Popup -> it.onDeny()
is Dismissible -> it.onDismiss()
is Popup -> it.onDeny()
}
}
}
......@@ -323,7 +327,7 @@ class PromptFeature private constructor(
}
is SingleChoice -> it.onConfirm(value as Choice)
is MenuChoice -> it.onConfirm(value as Choice)
is PromptRequest.Popup -> it.onAllow()
is Popup -> it.onAllow()
is MultipleChoice -> it.onConfirm(value as Array<Choice>)
is Authentication -> {
......@@ -340,9 +344,9 @@ class PromptFeature private constructor(
is Share -> it.onSuccess()
is LoginPrompt -> it.onConfirm(value as Login)
is SaveLoginPrompt -> it.onConfirm(value as Login)
is PromptRequest.Confirm -> {
is Confirm -> {
val (isCheckBoxChecked, buttonType) =
value as Pair<Boolean, MultiButtonDialogFragment.ButtonType>
promptAbuserDetector.userWantsMoreDialogs(!isCheckBoxChecked)
......@@ -410,12 +414,12 @@ class PromptFeature private constructor(
// Requests that are handled with dialogs
val dialog = when (promptRequest) {
is LoginPrompt -> {
is SaveLoginPrompt -> {
if (!isSaveLoginEnabled.invoke()) return
if (loginValidationDelegate == null) {
logger.debug(
"Ignoring received LoginPrompt because PromptFeature." +
"Ignoring received SaveLoginPrompt because PromptFeature." +
"loginValidationDelegate is null. If you are trying to autofill logins, " +
"try attaching a LoginValidationDelegate to PromptFeature"
)
......@@ -430,6 +434,12 @@ class PromptFeature private constructor(
)
}
/**
* This feature isn't implemented yet
* see https://github.com/mozilla-mobile/android-components/issues/7134
*/
is SelectLoginPrompt -> return
is SingleChoice -> ChoiceDialogFragment.newInstance(
promptRequest.choices,
session.id, SINGLE_CHOICE_DIALOG_TYPE
......@@ -505,7 +515,7 @@ class PromptFeature private constructor(
promptRequest.defaultColor
)
is PromptRequest.Popup -> {
is Popup -> {
val title = container.getString(R.string.mozac_feature_prompts_popup_dialog_title)
val positiveLabel = container.getString(R.string.mozac_feature_prompts_allow)
......@@ -520,7 +530,7 @@ class PromptFeature private constructor(
)
}
is PromptRequest.Confirm -> {
is Confirm -> {
with(promptRequest) {
val positiveButton = if (positiveButtonTitle.isEmpty()) {
container.getString(R.string.mozac_feature_prompts_ok)
......@@ -555,7 +565,7 @@ class PromptFeature private constructor(
dialog.show(fragmentManager, FRAGMENT_TAG)
activePrompt = WeakReference(dialog)
} else {
(promptRequest as PromptRequest.Dismissible).onDismiss()
(promptRequest as Dismissible).onDismiss()
store.dispatch(ContentAction.ConsumePromptRequestAction(session.id))
}
promptAbuserDetector.updateJSDialogAbusedState()
......@@ -570,10 +580,11 @@ class PromptFeature private constructor(
is File,
is Color,
is Authentication,
is PromptRequest.Popup,
is LoginPrompt,
is Popup,
is SaveLoginPrompt,
is SelectLoginPrompt,
is Share -> true
is Alert, is TextPrompt, is PromptRequest.Confirm -> promptAbuserDetector.shouldShowMoreDialogs
is Alert, is TextPrompt, is Confirm -> promptAbuserDetector.shouldShowMoreDialogs
}
}
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment