Commit 1826f005 authored by Lukasz Suder's avatar Lukasz Suder Committed by Commit Bot

[Autofill Assistant] Hides the keyboard during execution.

When Autofill Assistant is running the keyboard shouldn't be shown.
The only exceptions from this rule are:
* Focus action
* Asking for CVC
* During Payment Request

The current solution is imperfect. We only detect once the keyboard
was shown and hide it. We should find eventually better solution to
disable it permanently.

Bug: 806868
Change-Id: I85641652f8c43ec6d3ddb59742510ff793f7f901
Reviewed-on: https://chromium-review.googlesource.com/c/1371814
Commit-Queue: Lukasz Suder <lsuder@chromium.org>
Reviewed-by: default avatarStephane Zermatten <szermatt@chromium.org>
Cr-Commit-Position: refs/heads/master@{#615897}
parent 2468bf0f
......@@ -169,6 +169,12 @@ public class AutofillAssistantUiController extends AbstractAutofillAssistantUiCo
if (mUiControllerAndroid != 0) nativeDestroy(mUiControllerAndroid);
}
@CalledByNative
private void onAllowShowingSoftKeyboard(boolean allowed) {
this.mUiDelegateHolder.performUiOperation(
uiDelegate -> uiDelegate.allowShowingSoftKeyboard(allowed));
}
@CalledByNative
private void onShowStatusMessage(String message) {
mStatusMessage = message;
......
......@@ -54,6 +54,8 @@ import org.chromium.chrome.browser.snackbar.Snackbar;
import org.chromium.chrome.browser.snackbar.SnackbarManager;
import org.chromium.content_public.browser.WebContents;
import org.chromium.payments.mojom.PaymentOptions;
import org.chromium.ui.KeyboardVisibilityDelegate.KeyboardVisibilityListener;
import org.chromium.ui.base.ActivityKeyboardVisibilityDelegate;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
......@@ -115,6 +117,14 @@ class AutofillAssistantUiDelegate {
private AutofillAssistantPaymentRequest mPaymentRequest;
/**
* If set to true soft keyboard will be disabled.
*/
private boolean mAllowShowingSoftKeyboard = true;
private final ActivityKeyboardVisibilityDelegate mKeyboardDelegate;
private final KeyboardVisibilityListener mKeyboardVisibilityListener =
this::onKeyboardVisibilityChanged;
/**
* This is a client interface that relays interactions from the UI.
*/
......@@ -300,9 +310,28 @@ class AutofillAssistantUiDelegate {
mTouchEventFilter.setGrayOutColor(overlayColor);
}
mKeyboardDelegate = activity.getWindowAndroid().getKeyboardDelegate();
// TODO(crbug.com/806868): Listen for contextual search shown so as to hide this UI.
}
/**
* Allows enabling/disabling the software keyboard.
*/
void allowShowingSoftKeyboard(boolean allowed) {
this.mAllowShowingSoftKeyboard = allowed;
if (!allowed) {
mKeyboardDelegate.hideKeyboard(mActivity.getCompositorViewHolder());
}
}
// TODO(crbug.com/806868): Current solution only hides the keyboard once it has been already
// shown. We should improve it and prevent from the showing in the first place.
private void onKeyboardVisibilityChanged(boolean isShowing) {
if (isShowing && !mAllowShowingSoftKeyboard) {
mKeyboardDelegate.hideKeyboard(mActivity.getCompositorViewHolder());
}
}
/**
* Shows a message in the status bar.
*
......@@ -441,11 +470,14 @@ class AutofillAssistantUiDelegate {
// Set the initial progress. It is OK to make multiple calls to this method as it will
// have an effect only on the first one.
mProgressBar.maybeIncreaseProgress(PROGRESS_BAR_INITIAL_PROGRESS);
mKeyboardDelegate.addKeyboardVisibilityListener(mKeyboardVisibilityListener);
}
}
public void hide() {
mTouchEventFilter.deInit();
mKeyboardDelegate.removeKeyboardVisibilityListener(mKeyboardVisibilityListener);
mFullContainer.setVisibility(View.GONE);
}
......
......@@ -144,6 +144,11 @@ void UiControllerAndroid::HideOverlay() {
AttachCurrentThread(), java_autofill_assistant_ui_controller_);
}
void UiControllerAndroid::AllowShowingSoftKeyboard(bool enabled) {
Java_AutofillAssistantUiController_onAllowShowingSoftKeyboard(
AttachCurrentThread(), java_autofill_assistant_ui_controller_, enabled);
}
void UiControllerAndroid::Shutdown() {
Java_AutofillAssistantUiController_onShutdown(
AttachCurrentThread(), java_autofill_assistant_ui_controller_);
......
......@@ -41,6 +41,7 @@ class UiControllerAndroid : public UiController,
std::string GetStatusMessage() override;
void ShowOverlay() override;
void HideOverlay() override;
void AllowShowingSoftKeyboard(bool enabled) override;
void Shutdown() override;
void ShutdownGracefully() override;
void Close() override;
......
......@@ -213,6 +213,9 @@ class ActionDelegate {
// Hide the overlay.
virtual void HideOverlay() = 0;
// Allows disabling/enabling the soft keyboard.
virtual void AllowShowingSoftKeyboard(bool enabled) = 0;
protected:
ActionDelegate() = default;
};
......
......@@ -228,6 +228,8 @@ void AutofillAction::OnWaitForElement(ActionDelegate* delegate,
// TODO(crbug.com/806868): Consider refactoring SelfDeleteFullCardRequester
// so as to unit test it.
DCHECK(delegate->GetClientMemory()->selected_card());
// User might be asked to provide the cvc, enable the keyboard.
delegate->AllowShowingSoftKeyboard(true);
(new SelfDeleteFullCardRequester())
->GetFullCard(delegate->GetWebContents(),
delegate->GetClientMemory()->selected_card(),
......@@ -248,6 +250,7 @@ void AutofillAction::OnWaitForElement(ActionDelegate* delegate,
void AutofillAction::OnGetFullCard(ActionDelegate* delegate,
std::unique_ptr<autofill::CreditCard> card,
const base::string16& cvc) {
delegate->AllowShowingSoftKeyboard(false);
if (!card) {
// Gracefully shutdown the script. The empty message forces the use of the
// default message.
......
......@@ -52,6 +52,8 @@ void GetPaymentInformationAction::InternalProcessAction(
payment_options->request_shipping =
!get_payment_information.shipping_address_name().empty();
// During payment request user might need to modify the data. Enable keyboard.
delegate->AllowShowingSoftKeyboard(true);
delegate->GetPaymentInformation(
std::move(payment_options),
base::BindOnce(&GetPaymentInformationAction::OnGetPaymentInformation,
......@@ -68,6 +70,7 @@ void GetPaymentInformationAction::OnGetPaymentInformation(
const GetPaymentInformationProto& get_payment_information,
ProcessActionCallback callback,
std::unique_ptr<PaymentInformation> payment_information) {
delegate->AllowShowingSoftKeyboard(false);
bool succeed = payment_information->succeed;
if (succeed) {
if (get_payment_information.ask_for_payment()) {
......
......@@ -164,6 +164,7 @@ class MockActionDelegate : public ActionDelegate {
MOCK_METHOD0(HideProgressBar, void());
MOCK_METHOD0(ShowOverlay, void());
MOCK_METHOD0(HideOverlay, void());
MOCK_METHOD1(AllowShowingSoftKeyboard, void(bool));
};
} // namespace autofill_assistant
......
......@@ -227,6 +227,7 @@ void Controller::ExecuteScript(const std::string& script_path) {
GetUiController()->ShowOverlay();
touchable_element_area_.ClearElements();
GetUiController()->AllowShowingSoftKeyboard(false);
StopPeriodicScriptChecks();
// Runnable scripts will be checked and reported if necessary after executing
......@@ -253,6 +254,7 @@ void Controller::OnScriptExecuted(const std::string& script_path,
return;
}
touchable_element_area_.SetElements(result.touchable_elements);
GetUiController()->AllowShowingSoftKeyboard(true);
switch (result.at_end) {
case ScriptExecutor::SHUTDOWN:
GetUiController()->Shutdown(); // indirectly deletes this
......
......@@ -26,6 +26,7 @@ class MockUiController : public UiController {
MOCK_METHOD0(GetStatusMessage, std::string());
MOCK_METHOD0(ShowOverlay, void());
MOCK_METHOD0(HideOverlay, void());
MOCK_METHOD1(AllowShowingSoftKeyboard, void(bool));
MOCK_METHOD0(Shutdown, void());
MOCK_METHOD0(ShutdownGracefully, void());
MOCK_METHOD0(Close, void());
......
......@@ -134,6 +134,7 @@ void ScriptExecutor::Choose(
// through a previous call to the focus action with touchable_elements set.
delegate_->SetTouchableElementArea(touchable_elements_);
delegate_->GetUiController()->HideOverlay();
AllowShowingSoftKeyboard(true);
// The touchable_elements_ currently set in the script is reset, so that it
// won't affect the real end of the script.
......@@ -217,6 +218,10 @@ void ScriptExecutor::HideOverlay() {
delegate_->GetUiController()->HideOverlay();
}
void ScriptExecutor::AllowShowingSoftKeyboard(bool enabled) {
delegate_->GetUiController()->AllowShowingSoftKeyboard(enabled);
}
void ScriptExecutor::SetFieldValue(const Selector& selector,
const std::string& value,
bool simulate_key_presses,
......@@ -645,6 +650,7 @@ void ScriptExecutor::OnChosen(
base::OnceCallback<void(const std::string&)> callback,
const std::string& payload) {
delegate_->GetUiController()->ShowOverlay();
AllowShowingSoftKeyboard(false);
delegate_->ClearTouchableElementArea();
std::move(callback).Run(payload);
}
......
......@@ -155,6 +155,7 @@ class ScriptExecutor : public ActionDelegate {
void HideProgressBar() override;
void ShowOverlay() override;
void HideOverlay() override;
void AllowShowingSoftKeyboard(bool enabled) override;
private:
// Helper for WaitForElementVisible that keeps track of the state required to
......
......@@ -52,6 +52,9 @@ class UiController {
// Hide the overlay.
virtual void HideOverlay() = 0;
// Allows disabling/enabling the soft keyboard.
virtual void AllowShowingSoftKeyboard(bool enabled) = 0;
// Shuts down Autofill Assistant: hide the UI and frees any associated state.
//
// Warning: this indirectly deletes the caller.
......
Markdown is supported
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