1 // Copyright 2018 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_SCRIPT_EXECUTOR_H_ 6 #define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_SCRIPT_EXECUTOR_H_ 7 8 #include <deque> 9 #include <map> 10 #include <memory> 11 #include <ostream> 12 #include <set> 13 #include <string> 14 #include <vector> 15 16 #include "base/callback_forward.h" 17 #include "base/memory/weak_ptr.h" 18 #include "components/autofill_assistant/browser/actions/action.h" 19 #include "components/autofill_assistant/browser/actions/action_delegate.h" 20 #include "components/autofill_assistant/browser/actions/click_action.h" 21 #include "components/autofill_assistant/browser/client_settings.h" 22 #include "components/autofill_assistant/browser/details.h" 23 #include "components/autofill_assistant/browser/info_box.h" 24 #include "components/autofill_assistant/browser/retry_timer.h" 25 #include "components/autofill_assistant/browser/script.h" 26 #include "components/autofill_assistant/browser/script_executor_delegate.h" 27 #include "components/autofill_assistant/browser/service.pb.h" 28 #include "components/autofill_assistant/browser/top_padding.h" 29 30 namespace autofill_assistant { 31 class UserModel; 32 33 // Class to execute an assistant script. 34 class ScriptExecutor : public ActionDelegate, 35 public ScriptExecutorDelegate::Listener { 36 public: 37 // Listens to events on ScriptExecutor. 38 // TODO(b/806868): Make global_payload a part of callback instead of the 39 // listener. 40 class Listener { 41 public: 42 virtual ~Listener() = default; 43 44 // Called when new server payloads are available. 45 // 46 // TODO(b/806868): Stop reporting the script payload once the server has 47 // transitioned to global payloads. 48 virtual void OnServerPayloadChanged(const std::string& global_payload, 49 const std::string& script_payload) = 0; 50 51 // Called when an update list of scripts is available. 52 virtual void OnScriptListChanged( 53 std::vector<std::unique_ptr<Script>> scripts) = 0; 54 }; 55 56 // |delegate|, |listener|, |script_state| and |ordered_interrupts| should 57 // outlive this object and should not be nullptr. 58 ScriptExecutor(const std::string& script_path, 59 std::unique_ptr<TriggerContext> additional_context, 60 const std::string& global_payload, 61 const std::string& script_payload, 62 ScriptExecutor::Listener* listener, 63 std::map<std::string, ScriptStatusProto>* scripts_state, 64 const std::vector<std::unique_ptr<Script>>* ordered_interrupts, 65 ScriptExecutorDelegate* delegate); 66 ~ScriptExecutor() override; 67 68 // What should happen after the script has run. 69 enum AtEnd { 70 // Continue normally. 71 CONTINUE = 0, 72 73 // Shut down Autofill Assistant. 74 SHUTDOWN, 75 76 // Shut down Autofill Assistant after a delay. 77 SHUTDOWN_GRACEFULLY, 78 79 // Shut down Autofill Assistant and CCT. 80 CLOSE_CUSTOM_TAB, 81 }; 82 83 // Contains the result of the Run operation. 84 struct Result { 85 bool success = false; 86 AtEnd at_end = AtEnd::CONTINUE; 87 std::unique_ptr<ElementAreaProto> touchable_element_area; 88 89 Result(); 90 ~Result(); 91 92 friend std::ostream& operator<<(std::ostream& out, const Result& result); 93 }; 94 95 using RunScriptCallback = base::OnceCallback<void(const Result&)>; 96 void Run(const UserData* user_data, RunScriptCallback callback); 97 98 const UserData* GetUserData() const override; 99 100 // Override ScriptExecutorDelegate::Listener 101 void OnNavigationStateChanged() override; 102 103 // Override ActionDelegate: 104 void RunElementChecks(BatchElementChecker* checker) override; 105 void ShortWaitForElement( 106 const Selector& selector, 107 base::OnceCallback<void(const ClientStatus&)> callback) override; 108 void WaitForDom( 109 base::TimeDelta max_wait_time, 110 bool allow_interrupt, 111 base::RepeatingCallback< 112 void(BatchElementChecker*, 113 base::OnceCallback<void(const ClientStatus&)>)> check_elements, 114 base::OnceCallback<void(const ClientStatus&)> callback) override; 115 void SetStatusMessage(const std::string& message) override; 116 std::string GetStatusMessage() override; 117 void SetBubbleMessage(const std::string& message) override; 118 std::string GetBubbleMessage() override; 119 void ClickOrTapElement( 120 const Selector& selector, 121 ClickAction::ClickType click_type, 122 base::OnceCallback<void(const ClientStatus&)> callback) override; 123 void CollectUserData( 124 CollectUserDataOptions* collect_user_data_options) override; 125 void WriteUserData( 126 base::OnceCallback<void(UserData*, UserData::FieldChange*)>) override; 127 void GetFullCard(GetFullCardCallback callback) override; 128 void Prompt(std::unique_ptr<std::vector<UserAction>> user_actions, 129 bool disable_force_expand_sheet, 130 bool browse_mode) override; 131 void CleanUpAfterPrompt() override; 132 void SetBrowseDomainsWhitelist(std::vector<std::string> domains) override; 133 void FillAddressForm( 134 const autofill::AutofillProfile* profile, 135 const Selector& selector, 136 base::OnceCallback<void(const ClientStatus&)> callback) override; 137 void FillCardForm( 138 std::unique_ptr<autofill::CreditCard> card, 139 const base::string16& cvc, 140 const Selector& selector, 141 base::OnceCallback<void(const ClientStatus&)> callback) override; 142 void RetrieveElementFormAndFieldData( 143 const Selector& selector, 144 base::OnceCallback<void(const ClientStatus&, 145 const autofill::FormData& form_data, 146 const autofill::FormFieldData& field_data)> 147 callback) override; 148 void SelectOption( 149 const Selector& selector, 150 const std::string& value, 151 DropdownSelectStrategy select_strategy, 152 base::OnceCallback<void(const ClientStatus&)> callback) override; 153 void HighlightElement( 154 const Selector& selector, 155 base::OnceCallback<void(const ClientStatus&)> callback) override; 156 void FocusElement( 157 const Selector& selector, 158 const TopPadding& top_padding, 159 base::OnceCallback<void(const ClientStatus&)> callback) override; 160 void SetTouchableElementArea( 161 const ElementAreaProto& touchable_element_area) override; 162 void GetFieldValue( 163 const Selector& selector, 164 base::OnceCallback<void(const ClientStatus&, const std::string&)> 165 callback) override; 166 void SetFieldValue( 167 const Selector& selector, 168 const std::string& value, 169 KeyboardValueFillStrategy fill_strategy, 170 int key_press_delay_in_millisecond, 171 base::OnceCallback<void(const ClientStatus&)> callback) override; 172 void SetAttribute( 173 const Selector& selector, 174 const std::vector<std::string>& attribute, 175 const std::string& value, 176 base::OnceCallback<void(const ClientStatus&)> callback) override; 177 void SendKeyboardInput( 178 const Selector& selector, 179 const std::vector<UChar32>& codepoints, 180 int key_press_delay_in_millisecond, 181 base::OnceCallback<void(const ClientStatus&)> callback) override; 182 void GetOuterHtml( 183 const Selector& selector, 184 base::OnceCallback<void(const ClientStatus&, const std::string&)> 185 callback) override; 186 void GetElementTag( 187 const Selector& selector, 188 base::OnceCallback<void(const ClientStatus&, const std::string&)> 189 callback) override; 190 void ExpectNavigation() override; 191 bool ExpectedNavigationHasStarted() override; 192 bool WaitForNavigation(base::OnceCallback<void(bool)> callback) override; 193 void GetDocumentReadyState( 194 const Selector& optional_frame, 195 base::OnceCallback<void(const ClientStatus&, DocumentReadyState)> 196 callback) override; 197 void WaitForDocumentReadyState( 198 const Selector& optional_frame, 199 DocumentReadyState min_ready_state, 200 base::OnceCallback<void(const ClientStatus&, DocumentReadyState)> 201 callback) override; 202 203 void LoadURL(const GURL& url) override; 204 void Shutdown() override; 205 void Close() override; 206 autofill::PersonalDataManager* GetPersonalDataManager() override; 207 WebsiteLoginFetcher* GetWebsiteLoginFetcher() override; 208 content::WebContents* GetWebContents() override; 209 std::string GetAccountEmailAddress() override; 210 std::string GetLocale() override; 211 void SetDetails(std::unique_ptr<Details> details) override; 212 void ClearInfoBox() override; 213 void SetInfoBox(const InfoBox& info_box) override; 214 void SetProgress(int progress) override; 215 void SetProgressVisible(bool visible) override; 216 void SetViewportMode(ViewportMode mode) override; 217 ViewportMode GetViewportMode() override; 218 void SetPeekMode(ConfigureBottomSheetProto::PeekMode peek_mode) override; 219 ConfigureBottomSheetProto::PeekMode GetPeekMode() override; 220 void ExpandBottomSheet() override; 221 void CollapseBottomSheet() override; 222 void WaitForWindowHeightChange( 223 base::OnceCallback<void(const ClientStatus&)> callback) override; 224 const ClientSettings& GetSettings() override; 225 bool SetForm( 226 std::unique_ptr<FormProto> form, 227 base::RepeatingCallback<void(const FormProto::Result*)> changed_callback, 228 base::OnceCallback<void(const ClientStatus&)> cancel_callback) override; 229 void RequireUI() override; 230 void SetGenericUi( 231 std::unique_ptr<GenericUserInterfaceProto> generic_ui, 232 base::OnceCallback<void(bool, 233 ProcessedActionStatusProto, 234 const UserModel*)> end_action_callback) override; 235 void ClearGenericUi() override; 236 237 private: 238 // Helper for WaitForElementVisible that keeps track of the state required to 239 // run interrupts while waiting for a specific element. 240 class WaitForDomOperation : public ScriptExecutor::Listener, 241 ScriptExecutorDelegate::Listener { 242 public: 243 // Let the caller know about either the result of looking for the element or 244 // of an abnormal result from an interrupt. 245 // 246 // If the given result is non-null, it should be forwarded as the result of 247 // the main script. 248 using Callback = base::OnceCallback<void(const ClientStatus&, 249 const ScriptExecutor::Result*)>; 250 251 // |main_script_| must not be null and outlive this instance. 252 WaitForDomOperation( 253 ScriptExecutor* main_script, 254 ScriptExecutorDelegate* delegate, 255 base::TimeDelta max_wait_time, 256 bool allow_interrupt, 257 base::RepeatingCallback< 258 void(BatchElementChecker*, 259 base::OnceCallback<void(const ClientStatus&)>)> check_elements, 260 WaitForDomOperation::Callback callback); 261 ~WaitForDomOperation() override; 262 263 void Run(); 264 void Terminate(); 265 266 private: 267 void Start(); 268 void Pause(); 269 void Continue(); 270 271 // Implements ScriptExecutorDelegate::Listener 272 void OnNavigationStateChanged() override; 273 274 // Implements ScriptExecutor::Listener 275 void OnServerPayloadChanged(const std::string& global_payload, 276 const std::string& script_payload) override; 277 void OnScriptListChanged( 278 std::vector<std::unique_ptr<Script>> scripts) override; 279 280 void RunChecks( 281 base::OnceCallback<void(const ClientStatus&)> report_attempt_result); 282 void OnPreconditionCheckDone(const std::string& interrupt_path, 283 bool precondition_match); 284 void OnElementCheckDone(const ClientStatus&); 285 void OnAllChecksDone( 286 base::OnceCallback<void(const ClientStatus&)> report_attempt_result); 287 void RunInterrupt(const std::string& path); 288 void OnInterruptDone(const ScriptExecutor::Result& result); 289 void RunCallback(const ClientStatus& element_status); 290 void RunCallbackWithResult(const ClientStatus& element_status, 291 const ScriptExecutor::Result* result); 292 293 // Saves the current state and sets save_pre_interrupt_state_. 294 void SavePreInterruptState(); 295 296 // Restores the UI states as found by SavePreInterruptState. 297 void RestoreStatusMessage(); 298 299 // if save_pre_interrupt_state_ is set, attempt to scroll the page back to 300 // the original area. 301 void RestorePreInterruptScroll(); 302 303 ScriptExecutor* main_script_; 304 ScriptExecutorDelegate* delegate_; 305 const base::TimeDelta max_wait_time_; 306 const bool allow_interrupt_; 307 base::RepeatingCallback<void(BatchElementChecker*, 308 base::OnceCallback<void(const ClientStatus&)>)> 309 check_elements_; 310 WaitForDomOperation::Callback callback_; 311 312 std::unique_ptr<BatchElementChecker> batch_element_checker_; 313 314 // Path of interrupts from |ordered_interrupts_| that have been found 315 // runnable. 316 std::set<std::string> runnable_interrupts_; 317 ClientStatus element_check_result_; 318 319 // An empty vector of interrupts that can be passed to interrupt_executor_ 320 // and outlives it. Interrupts must not run interrupts. 321 const std::vector<std::unique_ptr<Script>> no_interrupts_; 322 323 // The interrupt that's currently running. 324 std::unique_ptr<ScriptExecutor> interrupt_executor_; 325 326 // If true, pre-interrupt state was saved already. This happens just before 327 // the first interrupt. 328 bool saved_pre_interrupt_state_ = false; 329 330 // The status message that was displayed when the interrupt started. 331 std::string pre_interrupt_status_; 332 333 // Paths of the interrupts that were just run. These interrupts are 334 // prevented from firing for one round. 335 std::set<std::string> ran_interrupts_; 336 337 RetryTimer retry_timer_; 338 339 base::WeakPtrFactory<WaitForDomOperation> weak_ptr_factory_{this}; 340 341 DISALLOW_COPY_AND_ASSIGN(WaitForDomOperation); 342 }; 343 344 void OnGetActions(bool result, const std::string& response); 345 bool ProcessNextActionResponse(const std::string& response); 346 void ReportPayloadsToListener(); 347 void ReportScriptsUpdateToListener( 348 std::vector<std::unique_ptr<Script>> scripts); 349 void RunCallback(bool success); 350 void RunCallbackWithResult(const Result& result); 351 void ProcessNextAction(); 352 void ProcessAction(Action* action); 353 void GetNextActions(); 354 void OnProcessedAction(base::TimeTicks start_time, 355 std::unique_ptr<ProcessedActionProto> action); 356 void CheckElementMatches( 357 const Selector& selector, 358 BatchElementChecker* checker, 359 base::OnceCallback<void(const ClientStatus&)> callback); 360 void OnShortWaitForElement( 361 base::OnceCallback<void(const ClientStatus&)> callback, 362 const ClientStatus& element_status, 363 const Result* interrupt_result); 364 void OnWaitForElementVisibleWithInterrupts( 365 base::OnceCallback<void(const ClientStatus&)> callback, 366 const ClientStatus& element_status, 367 const Result* interrupt_result); 368 void OnGetUserData( 369 base::OnceCallback<void(UserData*, const UserModel*)> callback, 370 UserData* user_data, 371 const UserModel* user_model); 372 void OnAdditionalActionTriggered(base::OnceCallback<void(int)> callback, 373 int index); 374 void OnTermsAndConditionsLinkClicked(base::OnceCallback<void(int)> callback, 375 int link); 376 void OnGetFullCard(GetFullCardCallback callback, 377 std::unique_ptr<autofill::CreditCard> card, 378 const base::string16& cvc); 379 void OnChosen(UserAction::Callback callback, 380 std::unique_ptr<TriggerContext> context); 381 382 const std::string script_path_; 383 std::unique_ptr<TriggerContext> additional_context_; 384 std::string last_global_payload_; 385 const std::string initial_script_payload_; 386 std::string last_script_payload_; 387 ScriptExecutor::Listener* const listener_; 388 ScriptExecutorDelegate* const delegate_; 389 // Set of interrupts that might run during wait for dom or prompt action with 390 // allow_interrupt. Sorted by priority; an interrupt that appears on the 391 // vector first should run first. Note that the content of this vector can 392 // change while the script is running, as a result of OnScriptListChanged 393 // being called. 394 const std::vector<std::unique_ptr<Script>>* const ordered_interrupts_; 395 std::map<std::string, ScriptStatusProto>* const scripts_state_; 396 RunScriptCallback callback_; 397 std::vector<std::unique_ptr<Action>> actions_; 398 std::vector<ProcessedActionProto> processed_actions_; 399 AtEnd at_end_ = CONTINUE; 400 bool should_stop_script_ = false; 401 bool should_clean_contextual_ui_on_finish_ = false; 402 ActionProto::ActionInfoCase previous_action_type_ = 403 ActionProto::ACTION_INFO_NOT_SET; 404 Selector last_focused_element_selector_; 405 TopPadding last_focused_element_top_padding_; 406 std::unique_ptr<ElementAreaProto> touchable_element_area_; 407 408 // Steps towards the requirements for calling |on_expected_navigation_done_| 409 // to be fulfilled. 410 enum class ExpectedNavigationStep { 411 // No navigation is expected. 412 UNEXPECTED = 0, 413 // Navigation start is expected. 414 EXPECTED, 415 // Navigation has started, end is expected. 416 STARTED, 417 // Expected navigation has ended. 418 DONE 419 }; 420 ExpectedNavigationStep expected_navigation_step_ = 421 ExpectedNavigationStep::UNEXPECTED; 422 423 // Callback called the next time |expected_navigation_step_| becomes DONE. 424 base::OnceCallback<void(bool)> on_expected_navigation_done_; 425 426 // Data only relevant to the currently running action. It is cleared before an 427 // action is run. 428 struct CurrentActionData { 429 CurrentActionData(); 430 ~CurrentActionData(); 431 CurrentActionData& operator=(CurrentActionData&& other); 432 433 // Navigation information relevant to the current action. 434 NavigationInfoProto navigation_info; 435 436 std::unique_ptr<WaitForDomOperation> wait_for_dom; 437 438 // Set to true when a direct action was used to trigger a UserAction within 439 // a prompt. This is reported to the backend. 440 bool direct_action = false; 441 }; 442 CurrentActionData current_action_data_; 443 444 const UserData* user_data_ = nullptr; 445 446 base::WeakPtrFactory<ScriptExecutor> weak_ptr_factory_{this}; 447 DISALLOW_COPY_AND_ASSIGN(ScriptExecutor); 448 }; 449 } // namespace autofill_assistant 450 451 #endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_SCRIPT_EXECUTOR_H_ 452