diff options
Diffstat (limited to 'chromium/components/autofill_assistant/browser/controller.cc')
-rw-r--r-- | chromium/components/autofill_assistant/browser/controller.cc | 151 |
1 files changed, 124 insertions, 27 deletions
diff --git a/chromium/components/autofill_assistant/browser/controller.cc b/chromium/components/autofill_assistant/browser/controller.cc index f980f810704..db966cfd225 100644 --- a/chromium/components/autofill_assistant/browser/controller.cc +++ b/chromium/components/autofill_assistant/browser/controller.cc @@ -12,7 +12,6 @@ #include "base/no_destructor.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" -#include "base/task/post_task.h" #include "base/time/tick_clock.h" #include "base/values.h" #include "components/autofill_assistant/browser/actions/collect_user_data_action.h" @@ -23,6 +22,7 @@ #include "components/autofill_assistant/browser/service_impl.h" #include "components/autofill_assistant/browser/trigger_context.h" #include "components/autofill_assistant/browser/user_data.h" +#include "components/autofill_assistant/browser/view_layout.pb.h" #include "components/google/core/common/google_util.h" #include "components/password_manager/core/browser/password_manager_client.h" #include "components/strings/grit/components_strings.h" @@ -43,14 +43,16 @@ namespace { static constexpr int kAutostartInitialProgress = 5; // Parameter that allows setting the color of the overlay. -static const char* const kOverlayColorParameterName = "OVERLAY_COLORS"; +const char kOverlayColorParameterName[] = "OVERLAY_COLORS"; // Parameter that contains the current session username. Should be synced with // |SESSION_USERNAME_PARAMETER| from // .../password_manager/PasswordChangeLauncher.java // TODO(b/151401974): Eliminate duplicate parameter definitions. -static const char* const kPasswordChangeUsernameParameterName = - "PASSWORD_CHANGE_USERNAME"; +const char kPasswordChangeUsernameParameterName[] = "PASSWORD_CHANGE_USERNAME"; + +// Experiment for toggling the new progress bar. +const char kProgressBarExperiment[] = "4400697"; // Returns true if the state requires a UI to be shown. // @@ -241,6 +243,15 @@ int Controller::GetProgress() const { return progress_; } +base::Optional<int> Controller::GetProgressActiveStep() const { + return progress_active_step_; +} + +base::Optional<ShowProgressBarProto::StepProgressBarConfiguration> +Controller::GetStepProgressBarConfiguration() const { + return step_progress_bar_configuration_; +} + void Controller::SetInfoBox(const InfoBox& info_box) { if (!info_box_) { info_box_ = std::make_unique<InfoBox>(); @@ -273,6 +284,18 @@ void Controller::SetProgress(int progress) { } } +void Controller::SetProgressActiveStep(int active_step) { + // Step can only increase. + if (progress_active_step_ >= active_step) { + return; + } + + progress_active_step_ = active_step; + for (ControllerObserver& observer : observers_) { + observer.OnProgressActiveStepChanged(active_step); + } +} + void Controller::SetProgressVisible(bool visible) { if (progress_visible_ == visible) return; @@ -287,6 +310,38 @@ bool Controller::GetProgressVisible() const { return progress_visible_; } +void Controller::SetStepProgressBarConfiguration( + const ShowProgressBarProto::StepProgressBarConfiguration& configuration) { + step_progress_bar_configuration_ = configuration; + if (!configuration.step_icons().empty() && + progress_active_step_.has_value() && + configuration.step_icons().size() < *progress_active_step_) { + progress_active_step_ = configuration.step_icons().size(); + } + for (ControllerObserver& observer : observers_) { + observer.OnStepProgressBarConfigurationChanged(configuration); + if (progress_active_step_.has_value()) { + observer.OnProgressActiveStepChanged(*progress_active_step_); + } + observer.OnProgressBarErrorStateChanged(progress_bar_error_state_); + } +} + +void Controller::SetProgressBarErrorState(bool error) { + if (progress_bar_error_state_ == error) { + return; + } + + progress_bar_error_state_ = error; + for (ControllerObserver& observer : observers_) { + observer.OnProgressBarErrorStateChanged(error); + } +} + +bool Controller::GetProgressBarErrorState() const { + return progress_bar_error_state_; +} + const std::vector<UserAction>& Controller::GetUserActions() const { static const base::NoDestructor<std::vector<UserAction>> no_user_actions_; return user_actions_ ? *user_actions_ : *no_user_actions_; @@ -321,10 +376,13 @@ void Controller::RequireUI() { void Controller::SetGenericUi( std::unique_ptr<GenericUserInterfaceProto> generic_ui, - base::OnceCallback<void(bool, ProcessedActionStatusProto, const UserModel*)> - end_action_callback) { + base::OnceCallback<void(const ClientStatus&)> end_action_callback, + base::OnceCallback<void(const ClientStatus&)> + view_inflation_finished_callback) { generic_user_interface_ = std::move(generic_ui); basic_interactions_.SetEndActionCallback(std::move(end_action_callback)); + basic_interactions_.SetViewInflationFinishedCallback( + std::move(view_inflation_finished_callback)); for (ControllerObserver& observer : observers_) { observer.OnGenericUserInterfaceChanged(generic_user_interface_.get()); } @@ -332,7 +390,7 @@ void Controller::SetGenericUi( void Controller::ClearGenericUi() { generic_user_interface_.reset(); - basic_interactions_.ClearEndActionCallback(); + basic_interactions_.ClearCallbacks(); for (ControllerObserver& observer : observers_) { observer.OnGenericUserInterfaceChanged(nullptr); } @@ -699,10 +757,11 @@ void Controller::StartPeriodicScriptChecks() { if (periodic_script_check_scheduled_) return; periodic_script_check_scheduled_ = true; - base::PostDelayedTask(FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(&Controller::OnPeriodicScriptCheck, - weak_ptr_factory_.GetWeakPtr()), - settings_.periodic_script_check_interval); + content::GetUIThreadTaskRunner({})->PostDelayedTask( + FROM_HERE, + base::BindOnce(&Controller::OnPeriodicScriptCheck, + weak_ptr_factory_.GetWeakPtr()), + settings_.periodic_script_check_interval); } void Controller::StopPeriodicScriptChecks() { @@ -732,10 +791,11 @@ void Controller::OnPeriodicScriptCheck() { } script_tracker()->CheckScripts(); - base::PostDelayedTask(FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(&Controller::OnPeriodicScriptCheck, - weak_ptr_factory_.GetWeakPtr()), - settings_.periodic_script_check_interval); + content::GetUIThreadTaskRunner({})->PostDelayedTask( + FROM_HERE, + base::BindOnce(&Controller::OnPeriodicScriptCheck, + weak_ptr_factory_.GetWeakPtr()), + settings_.periodic_script_check_interval); } void Controller::OnGetScripts(const GURL& url, @@ -980,6 +1040,12 @@ void Controller::InitFromParameters() { user_data_->selected_login_.emplace(web_contents()->GetLastCommittedURL(), *password_change_username); } + + if (trigger_context_->HasExperimentId(kProgressBarExperiment)) { + ShowProgressBarProto::StepProgressBarConfiguration mock_configuration; + mock_configuration.set_use_step_progress_bar(true); + SetStepProgressBarConfiguration(mock_configuration); + } } void Controller::Track(std::unique_ptr<TriggerContext> trigger_context, @@ -1043,7 +1109,12 @@ void Controller::ShowFirstMessageAndStart() { SetStatusMessage( l10n_util::GetStringFUTF8(IDS_AUTOFILL_ASSISTANT_LOADING, base::UTF8ToUTF16(GetCurrentURL().host()))); - SetProgress(kAutostartInitialProgress); + if (step_progress_bar_configuration_.has_value() && + step_progress_bar_configuration_->use_step_progress_bar()) { + SetProgressActiveStep(0); + } else { + SetProgress(kAutostartInitialProgress); + } EnterState(AutofillAssistantState::STARTING); } @@ -1051,6 +1122,10 @@ AutofillAssistantState Controller::GetState() { return state_; } +int64_t Controller::GetErrorCausingNavigationId() const { + return error_causing_navigation_id_; +} + void Controller::OnScriptSelected(const ScriptHandle& handle, std::unique_ptr<TriggerContext> context) { ExecuteScript(handle.path, handle.start_message, handle.needs_ui, @@ -1435,6 +1510,7 @@ void Controller::OnScriptError(const std::string& error_message, RequireUI(); SetStatusMessage(error_message); + SetProgressBarErrorState(true); EnterStoppedState(); if (tracking_) { @@ -1454,6 +1530,7 @@ void Controller::OnFatalError(const std::string& error_message, return; SetStatusMessage(error_message); + SetProgressBarErrorState(true); EnterStoppedState(); // If we haven't managed to check the set of scripts yet at this point, we @@ -1588,10 +1665,6 @@ void Controller::OnRunnableScriptsChanged( SetUserActions(std::move(user_actions)); } -void Controller::DidAttachInterstitialPage() { - client_->Shutdown(Metrics::DropOutReason::INTERSTITIAL_PAGE); -} - void Controller::DidFinishLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url) { // validated_url might not be the page URL. Ignore it and always check the @@ -1599,6 +1672,10 @@ void Controller::DidFinishLoad(content::RenderFrameHost* render_frame_host, OnUrlChange(); } +void Controller::ExpectNavigation() { + expect_navigation_ = true; +} + void Controller::DidStartNavigation( content::NavigationHandle* navigation_handle) { if (!navigation_handle->IsInMainFrame() || @@ -1611,6 +1688,12 @@ void Controller::DidStartNavigation( ReportNavigationStateChanged(); } + // The navigation is expected, do not check for errors below. + if (expect_navigation_) { + expect_navigation_ = false; + return; + } + // The following types of navigations are allowed for the main frame, when // in PROMPT state: // - first-time URL load @@ -1627,19 +1710,38 @@ void Controller::DidStartNavigation( // Everything else, such as going back to a previous page, or refreshing the // page is considered an end condition. If going back to a previous page is // required, consider using the BROWSE state instead. - // Note that BROWSE state end conditions are in DidFinishNavigation, in order - // to be able to properly evaluate the committed url. if (state_ == AutofillAssistantState::PROMPT && web_contents()->GetLastCommittedURL().is_valid() && !navigation_handle->WasServerRedirect() && !navigation_handle->IsRendererInitiated()) { + error_causing_navigation_id_ = navigation_handle->GetNavigationId(); OnScriptError(l10n_util::GetStringUTF8(IDS_AUTOFILL_ASSISTANT_GIVE_UP), Metrics::DropOutReason::NAVIGATION); + return; } + + if (base::FeatureList::IsEnabled( + features::kAutofillAssistantBreakOnRunningNavigation)) { + // When in RUNNING state, all renderer initiated navigation is allowed, + // user initiated navigation will cause an error. + if (state_ == AutofillAssistantState::RUNNING && + !navigation_handle->WasServerRedirect() && + !navigation_handle->IsRendererInitiated()) { + error_causing_navigation_id_ = navigation_handle->GetNavigationId(); + OnScriptError(l10n_util::GetStringUTF8(IDS_AUTOFILL_ASSISTANT_GIVE_UP), + Metrics::DropOutReason::NAVIGATION_WHILE_RUNNING); + return; + } + } + + // Note that BROWSE state end conditions are in DidFinishNavigation, in order + // to be able to properly evaluate the committed url. } void Controller::DidFinishNavigation( content::NavigationHandle* navigation_handle) { + // TODO(b/159871774): Rethink how we handle navigation events. The early + // return here may prevent us from updating |navigating_to_new_document_|. if (!navigation_handle->IsInMainFrame() || navigation_handle->IsSameDocument() || !navigation_handle->HasCommitted() || !IsNavigatingToNewDocument()) { @@ -1758,11 +1860,6 @@ void Controller::WriteUserData( } } -void Controller::WriteUserModel( - base::OnceCallback<void(UserModel*)> write_callback) { - std::move(write_callback).Run(&user_model_); -} - ElementArea* Controller::touchable_element_area() { if (!touchable_element_area_) { touchable_element_area_ = std::make_unique<ElementArea>(this); |