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