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 CHROME_BROWSER_ANDROID_AUTOFILL_ASSISTANT_UI_CONTROLLER_ANDROID_H_
6 #define CHROME_BROWSER_ANDROID_AUTOFILL_ASSISTANT_UI_CONTROLLER_ANDROID_H_
7 
8 #include <memory>
9 #include <string>
10 #include <vector>
11 
12 #include "base/android/scoped_java_ref.h"
13 #include "base/macros.h"
14 #include "chrome/browser/android/autofill_assistant/assistant_bottom_bar_delegate.h"
15 #include "chrome/browser/android/autofill_assistant/assistant_collect_user_data_delegate.h"
16 #include "chrome/browser/android/autofill_assistant/assistant_form_delegate.h"
17 #include "chrome/browser/android/autofill_assistant/assistant_generic_ui_delegate.h"
18 #include "chrome/browser/android/autofill_assistant/assistant_header_delegate.h"
19 #include "chrome/browser/android/autofill_assistant/assistant_header_model.h"
20 #include "chrome/browser/android/autofill_assistant/assistant_overlay_delegate.h"
21 #include "components/autofill_assistant/browser/chip.h"
22 #include "components/autofill_assistant/browser/controller_observer.h"
23 #include "components/autofill_assistant/browser/details.h"
24 #include "components/autofill_assistant/browser/info_box.h"
25 #include "components/autofill_assistant/browser/metrics.h"
26 #include "components/autofill_assistant/browser/overlay_state.h"
27 #include "components/autofill_assistant/browser/trigger_context.h"
28 #include "components/autofill_assistant/browser/user_action.h"
29 
30 namespace autofill_assistant {
31 struct ClientSettings;
32 class GenericUiRootControllerAndroid;
33 class ClientAndroid;
34 
35 // Starts and owns the UI elements required to display AA.
36 //
37 // This class and its UI elements are tied to a ChromeActivity. A
38 // UiControllerAndroid can be attached and detached from an AA controller, which
39 // is tied to a BrowserContent.
40 //
41 // TODO(crbug.com/806868): This class should be renamed to
42 // AssistantMediator(Android) and listen for state changes to forward those
43 // changes to the UI model.
44 class UiControllerAndroid : public ControllerObserver {
45  public:
46   static std::unique_ptr<UiControllerAndroid> CreateFromWebContents(
47       content::WebContents* web_contents,
48       const base::android::JavaParamRef<jobject>& jonboarding_coordinator);
49 
50   // pointers to |web_contents|, |client| must remain valid for the lifetime of
51   // this instance.
52   //
53   // Pointer to |ui_delegate| must remain valid for the lifetime of this
54   // instance or until WillShutdown is called.
55   UiControllerAndroid(
56       JNIEnv* env,
57       const base::android::JavaRef<jobject>& jactivity,
58       const base::android::JavaParamRef<jobject>& jonboarding_coordinator);
59   ~UiControllerAndroid() override;
60 
61   // Attaches the UI to the given client, its web contents and delegate.
62   //
63   // |web_contents|, |client| and |ui_delegate| must remain valid for the
64   // lifetime of this instance or until Attach() is called again, with different
65   // pointers.
66   void Attach(content::WebContents* web_contents,
67               ClientAndroid* client,
68               UiDelegate* ui_delegate);
69 
70   // Detaches the UI from |ui_delegate_|. It will stop receiving notifications
71   // from the delegate until it is attached again.
72   void Detach();
73 
74   // Returns true if the UI is attached to a delegate.
IsAttached()75   bool IsAttached() { return ui_delegate_ != nullptr; }
76 
77   // Returns whether the UI is currently attached to the given delegate or not.
IsAttachedTo(UiDelegate * ui_delegate)78   bool IsAttachedTo(UiDelegate* ui_delegate) {
79     return ui_delegate_ == ui_delegate;
80   }
81 
82   // Have the UI react as if a close or cancel button was pressed.
83   //
84   // If action_index != -1, execute that action as close/cancel. Otherwise
85   // execute the default close or cancel action.
86   void CloseOrCancel(int action_index,
87                      std::unique_ptr<TriggerContext> trigger_context,
88                      Metrics::DropOutReason dropout_reason);
89 
90   // Overrides ControllerObserver:
91   void OnStateChanged(AutofillAssistantState new_state) override;
92   void OnStatusMessageChanged(const std::string& message) override;
93   void OnBubbleMessageChanged(const std::string& message) override;
94   void CloseCustomTab() override;
95   void OnUserActionsChanged(const std::vector<UserAction>& actions) override;
96   void OnCollectUserDataOptionsChanged(
97       const CollectUserDataOptions* collect_user_data_options) override;
98   void OnUserDataChanged(const UserData* state,
99                          UserData::FieldChange field_change) override;
100   void OnDetailsChanged(const Details* details) override;
101   void OnInfoBoxChanged(const InfoBox* info_box) override;
102   void OnProgressChanged(int progress) override;
103   void OnProgressActiveStepChanged(int active_step) override;
104   void OnProgressVisibilityChanged(bool visible) override;
105   void OnProgressBarErrorStateChanged(bool error) override;
106   void OnStepProgressBarConfigurationChanged(
107       const ShowProgressBarProto::StepProgressBarConfiguration& configuration)
108       override;
109   void OnTouchableAreaChanged(
110       const RectF& visual_viewport,
111       const std::vector<RectF>& touchable_areas,
112       const std::vector<RectF>& restricted_areas) override;
113   void OnViewportModeChanged(ViewportMode mode) override;
114   void OnPeekModeChanged(
115       ConfigureBottomSheetProto::PeekMode peek_mode) override;
116   void OnExpandBottomSheet() override;
117   void OnCollapseBottomSheet() override;
118   void OnOverlayColorsChanged(const UiDelegate::OverlayColors& colors) override;
119   void OnFormChanged(const FormProto* form,
120                      const FormProto::Result* result) override;
121   void OnClientSettingsChanged(const ClientSettings& settings) override;
122   void OnGenericUserInterfaceChanged(
123       const GenericUserInterfaceProto* generic_ui) override;
124   void OnShouldShowOverlayChanged(bool should_show) override;
125   void OnFeedbackFormRequested() override;
126 
127   // Called by AssistantOverlayDelegate:
128   void OnUnexpectedTaps();
129   void OnUserInteractionInsideTouchableArea();
130 
131   // Called by AssistantHeaderDelegate:
132   void OnFeedbackButtonClicked();
133 
134   // Called by AssistantGenericUiDelegate:
135   void OnViewEvent(const EventHandler::EventKey& key);
136   void OnValueChanged(const std::string& identifier, const ValueProto& value);
137 
138   // Called by AssistantCollectUserDataDelegate:
139   void OnShippingAddressChanged(
140       std::unique_ptr<autofill::AutofillProfile> address);
141   void OnContactInfoChanged(std::unique_ptr<autofill::AutofillProfile> profile);
142   void OnCreditCardChanged(
143       std::unique_ptr<autofill::CreditCard> card,
144       std::unique_ptr<autofill::AutofillProfile> billing_profile);
145   void OnTermsAndConditionsChanged(TermsAndConditionsState state);
146   void OnLoginChoiceChanged(std::string identifier);
147   void OnTextLinkClicked(int link);
148   void OnFormActionLinkClicked(int link);
149   void OnDateTimeRangeStartDateChanged(int year, int month, int day);
150   void OnDateTimeRangeStartDateCleared();
151   void OnDateTimeRangeStartTimeSlotChanged(int index);
152   void OnDateTimeRangeStartTimeSlotCleared();
153   void OnDateTimeRangeEndDateChanged(int year, int month, int day);
154   void OnDateTimeRangeEndDateCleared();
155   void OnDateTimeRangeEndTimeSlotChanged(int index);
156   void OnDateTimeRangeEndTimeSlotCleared();
157   void OnKeyValueChanged(const std::string& key, const ValueProto& value);
158   void OnTextFocusLost();
159   bool IsContactComplete(autofill::AutofillProfile* contact);
160   bool IsShippingAddressComplete(autofill::AutofillProfile* address);
161   bool IsPaymentInstrumentComplete(autofill::CreditCard* card,
162                                    autofill::AutofillProfile* address);
163 
164   // Called by AssistantFormDelegate:
165   void OnCounterChanged(int input_index, int counter_index, int value);
166   void OnChoiceSelectionChanged(int input_index,
167                                 int choice_index,
168                                 bool selected);
169 
170   // Called by AssistantBottomBarNativeDelegate:
171   bool OnBackButtonClicked();
172   void OnBottomSheetClosedWithSwipe();
173 
174   // Called by Java.
175   void SnackbarResult(JNIEnv* env,
176                       const base::android::JavaParamRef<jobject>& obj,
177                       jboolean undo);
178   void Stop(JNIEnv* env,
179             const base::android::JavaParamRef<jobject>& obj,
180             int reason);
181   void OnFatalError(JNIEnv* env,
182                     const base::android::JavaParamRef<jobject>& obj,
183                     const base::android::JavaParamRef<jstring>& message,
184                     int reason);
185   base::android::ScopedJavaLocalRef<jstring> GetPrimaryAccountName(
186       JNIEnv* env,
187       const base::android::JavaParamRef<jobject>& jcaller);
188   void OnUserActionSelected(JNIEnv* env,
189                             const base::android::JavaParamRef<jobject>& jcaller,
190                             jint index);
191   void OnCancelButtonClicked(
192       JNIEnv* env,
193       const base::android::JavaParamRef<jobject>& jcaller,
194       jint actionIndex);
195   void OnCloseButtonClicked(
196       JNIEnv* env,
197       const base::android::JavaParamRef<jobject>& jcaller);
198   void OnFeedbackButtonClicked(
199       JNIEnv* env,
200       const base::android::JavaParamRef<jobject>& jcaller,
201       jint actionIndex);
202   void OnKeyboardVisibilityChanged(
203       JNIEnv* env,
204       const base::android::JavaParamRef<jobject>& jcaller,
205       jboolean visible);
206   void SetVisible(JNIEnv* env,
207                   const base::android::JavaParamRef<jobject>& jcaller,
208                   jboolean visible);
209   void OnTabSwitched(JNIEnv* env,
210                      const base::android::JavaParamRef<jobject>& jcaller,
211                      jint state,
212                      jboolean activity_changed);
213   void OnTabSelected(JNIEnv* env,
214                      const base::android::JavaParamRef<jobject>& jcaller);
215 
216  private:
217   // A pointer to the client. nullptr until Attach() is called.
218   ClientAndroid* client_ = nullptr;
219 
220   // A pointer to the ui_delegate. nullptr until Attach() is called.
221   UiDelegate* ui_delegate_ = nullptr;
222   AssistantOverlayDelegate overlay_delegate_;
223   AssistantHeaderDelegate header_delegate_;
224   AssistantCollectUserDataDelegate collect_user_data_delegate_;
225   AssistantFormDelegate form_delegate_;
226   AssistantGenericUiDelegate generic_ui_delegate_;
227   AssistantBottomBarDelegate bottom_bar_delegate_;
228 
229   // What to do if undo is not pressed on the current snackbar.
230   base::OnceCallback<void()> snackbar_action_;
231 
232   base::android::ScopedJavaLocalRef<jobject> GetModel();
233   base::android::ScopedJavaLocalRef<jobject> GetOverlayModel();
234   base::android::ScopedJavaLocalRef<jobject> GetHeaderModel();
235   base::android::ScopedJavaLocalRef<jobject> GetDetailsModel();
236   base::android::ScopedJavaLocalRef<jobject> GetInfoBoxModel();
237   base::android::ScopedJavaLocalRef<jobject> GetCollectUserDataModel();
238   base::android::ScopedJavaLocalRef<jobject> GetFormModel();
239   base::android::ScopedJavaLocalRef<jobject> GetGenericUiModel();
240 
241   // The UiDelegate has the last say on whether we should show the overlay.
242   // This saves the AutofillAssistantState-determined OverlayState and then
243   // applies it the actual UI only if the UiDelegate's ShouldShowOverlay is
244   // true.
245   void SetOverlayState(OverlayState state);
246   // Applies the specified OverlayState to the UI.
247   void ApplyOverlayState(OverlayState state);
248   void AllowShowingSoftKeyboard(bool enabled);
249   void ShowContentAndExpandBottomSheet();
250   void SetSpinPoodle(bool enabled);
251   std::string GetDebugContext();
252   void DestroySelf();
253   void Shutdown(Metrics::DropOutReason reason);
254   void UpdateActions(const std::vector<UserAction>& GetUserActions);
255   void HideKeyboardIfFocusNotOnText();
256 
257   void ResetGenericUiControllers();
258   std::unique_ptr<GenericUiRootControllerAndroid>
259   CreateGenericUiControllerForProto(const GenericUserInterfaceProto& proto);
260 
261   // Hide the UI, show a snackbar with an undo button, and execute the given
262   // action after a short delay unless the user taps the undo button.
263   void ShowSnackbar(base::TimeDelta delay,
264                     const std::string& message,
265                     base::OnceCallback<void()> action);
266 
267   void OnCancel(int action_index,
268                 std::unique_ptr<TriggerContext> context,
269                 Metrics::DropOutReason dropout_reason);
270 
271   // Updates the state of the UI to reflect the UIDelegate's state.
272   void SetupForState();
273 
274   // Makes the whole of AA invisible or visible again.
275   void SetVisible(bool visible);
276 
277   // Restore the UI for the current UIDelegate.
278   void RestoreUi();
279 
280   // Java-side AutofillAssistantUiController object.
281   base::android::ScopedJavaGlobalRef<jobject> java_object_;
282 
283   // Native controllers for generic UI.
284   std::unique_ptr<GenericUiRootControllerAndroid>
285       collect_user_data_prepended_generic_ui_controller_;
286   std::unique_ptr<GenericUiRootControllerAndroid>
287       collect_user_data_appended_generic_ui_controller_;
288   std::unique_ptr<GenericUiRootControllerAndroid> generic_ui_controller_;
289 
290   OverlayState desired_overlay_state_ = OverlayState::FULL;
291   OverlayState overlay_state_ = OverlayState::FULL;
292 
293   std::unique_ptr<AssistantHeaderModel> header_model_;
294 
295   base::WeakPtrFactory<UiControllerAndroid> weak_ptr_factory_{this};
296 
297   DISALLOW_COPY_AND_ASSIGN(UiControllerAndroid);
298 };
299 
300 }  // namespace autofill_assistant.
301 #endif  // CHROME_BROWSER_ANDROID_AUTOFILL_ASSISTANT_UI_CONTROLLER_ANDROID_H_
302