Commit d1bad9a6 authored by Stephane Zermatten's avatar Stephane Zermatten Committed by Commit Bot

[Autofill Assistant] Map the cancel/close button to a direct action.

This change makes cancel/close available on the UI, available as a
direct action with the same behavior when the UI is up.

When the UI is not up, "cancel" is only available if it exists in
UserAction as a direct action. When the UI is up, "cancel" is executed
through the UIController instead of being run directly as a UserAction.

This allows closing the UI or showing the undoable snackbar as a result
of the "cancel" direct action being executed.

Bug: b/134742442
Change-Id: Ia43275a090a0ad2a440447b175fdcf15dd893430
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1699675
Commit-Queue: Stephane Zermatten <szermatt@chromium.org>
Reviewed-by: default avatarJordan Demeulenaere <jdemeulenaere@chromium.org>
Cr-Commit-Position: refs/heads/master@{#680429}
parent 518a4b6a
......@@ -52,6 +52,10 @@ namespace {
const char* const kDefaultAutofillAssistantServerUrl =
"https://automate-pa.googleapis.com";
// A direct action that corresponds to pressing the close or cancel button on
// the UI.
const char* const kCancelActionName = "cancel";
// Fills a map from two Java arrays of strings of the same length.
void FillStringMapFromJava(JNIEnv* env,
const JavaRef<jobjectArray>& names,
......@@ -228,6 +232,10 @@ void ClientAndroid::OnListDirectActions(
}
}
// Cancel is always available when the UI is up.
if (ui_controller_android_)
names.insert(kCancelActionName);
JNIEnv* env = AttachCurrentThread();
Java_AutofillAssistantClient_sendDirectActionList(
env, java_object_, jcallback,
......@@ -243,13 +251,36 @@ bool ClientAndroid::PerformDirectAction(
const base::android::JavaParamRef<jobjectArray>& jargument_names,
const base::android::JavaParamRef<jobjectArray>& jargument_values,
const base::android::JavaParamRef<jobject>& joverlay_coordinator) {
std::string action_name =
base::android::ConvertJavaStringToUTF8(env, jaction_name);
int action_index = FindDirectAction(action_name);
// Cancel through the UI if it is up. This allows the user to undo. This is
// always available, even if no action was found and action_index == -1.
if (action_name == kCancelActionName && ui_controller_android_) {
ui_controller_android_->CloseOrCancel(action_index);
return true;
}
if (action_index == -1)
return false;
// If an overlay is already shown, then show the rest of the UI immediately.
if (joverlay_coordinator) {
AttachUI(joverlay_coordinator);
}
return controller_->PerformUserActionWithContext(
action_index, CreateTriggerContext(env, jexperiment_ids, jargument_names,
jargument_values));
}
int ClientAndroid::FindDirectAction(const std::string& action_name) {
// It's too late to create a controller. This should have been done in
// ListDirectActions.
if (!controller_)
return false;
std::string action_name =
base::android::ConvertJavaStringToUTF8(env, jaction_name);
return -1;
const std::vector<UserAction>& user_actions = controller_->GetUserActions();
int user_action_count = user_actions.size();
......@@ -260,19 +291,11 @@ bool ClientAndroid::PerformDirectAction(
const std::set<std::string>& action_names =
user_action.direct_action().names;
if (action_names.count(action_name) != 0) {
// If an overlay is already shown, then show the rest of the UI
// immediately.
if (joverlay_coordinator) {
AttachUI(joverlay_coordinator);
}
return controller_->PerformUserActionWithContext(
i, CreateTriggerContext(env, jexperiment_ids, jargument_names,
jargument_values));
}
if (action_names.count(action_name) != 0)
return i;
}
return false;
return -1;
}
void ClientAndroid::AttachUI() {
......
......@@ -106,6 +106,10 @@ class ClientAndroid : public Client,
bool NeedsUI();
void OnListDirectActions(const base::android::JavaRef<jobject>& jcallback);
// Returns the index of a direct action with that name, to pass to
// UiDelegate::PerformUserAction() or -1 if not found.
int FindDirectAction(const std::string& action_name);
WEB_CONTENTS_USER_DATA_KEY_DECL();
content::WebContents* web_contents_;
......
......@@ -538,32 +538,43 @@ void UiControllerAndroid::OnCancelButtonClicked(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& jcaller,
jint index) {
OnCancelButtonWithActionIndexClicked(index);
CloseOrCancel(index);
}
void UiControllerAndroid::OnCancelButtonClicked() {
OnCancelButtonWithActionIndexClicked(-1);
void UiControllerAndroid::OnCloseButtonClicked(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& jcaller) {
DestroySelf();
}
void UiControllerAndroid::OnCancelButtonWithActionIndexClicked(
int action_index) {
void UiControllerAndroid::CloseOrCancel(int action_index) {
// Close immediately.
if (!ui_delegate_ ||
ui_delegate_->GetState() == AutofillAssistantState::STOPPED) {
DestroySelf();
return;
}
// Close, with an action.
const std::vector<UserAction>& user_actions = ui_delegate_->GetUserActions();
if (action_index >= 0 &&
static_cast<size_t>(action_index) < user_actions.size() &&
user_actions[action_index].chip().type == CLOSE_ACTION &&
ui_delegate_->PerformUserAction(action_index)) {
return;
}
// Cancel, with a snackbar to allow UNDO.
ShowSnackbar(l10n_util::GetStringUTF8(IDS_AUTOFILL_ASSISTANT_STOPPED),
base::BindOnce(&UiControllerAndroid::OnCancel,
weak_ptr_factory_.GetWeakPtr(), action_index));
}
void UiControllerAndroid::OnCancel(int action_index) {
if (action_index == -1 || !ui_delegate_) {
if (action_index == -1 || !ui_delegate_ ||
!ui_delegate_->PerformUserAction(action_index)) {
Shutdown(Metrics::DropOutReason::SHEET_CLOSED);
return;
}
ui_delegate_->PerformUserAction(action_index);
}
void UiControllerAndroid::OnCloseButtonClicked(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& jcaller) {
DestroySelf();
}
// Overlay related methods.
......
......@@ -71,6 +71,12 @@ class UiControllerAndroid : public ControllerObserver {
// Returns true if the UI is attached to a delegate.
bool IsAttached() { return ui_delegate_; }
// Have the UI react as if a close or cancel button was pressed.
//
// If action_index != -1, execute that action as close/cancel. Otherwise
// execute the default close or cancel action.
void CloseOrCancel(int action_index);
// Overrides UiController:
void OnStateChanged(AutofillAssistantState new_state) override;
void OnStatusMessageChanged(const std::string& message) override;
......@@ -184,8 +190,7 @@ class UiControllerAndroid : public ControllerObserver {
// action after a short delay unless the user taps the undo button.
void ShowSnackbar(const std::string& message,
base::OnceCallback<void()> action);
void OnCancelButtonClicked();
void OnCancelButtonWithActionIndexClicked(int action_index);
void OnCancel(int action_index);
// Updates the state of the UI to reflect the UIDelegate's state.
......
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