1 // Copyright 2016 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_UI_VIEWS_PAYMENTS_PAYMENT_REQUEST_DIALOG_VIEW_H_ 6 #define CHROME_BROWSER_UI_VIEWS_PAYMENTS_PAYMENT_REQUEST_DIALOG_VIEW_H_ 7 8 #include <map> 9 #include <memory> 10 11 #include "base/callback_forward.h" 12 #include "base/macros.h" 13 #include "base/memory/weak_ptr.h" 14 #include "chrome/browser/ui/views/payments/view_stack.h" 15 #include "components/payments/content/initialization_task.h" 16 #include "components/payments/content/payment_request_dialog.h" 17 #include "components/payments/content/payment_request_spec.h" 18 #include "components/payments/content/payment_request_state.h" 19 #include "ui/views/controls/throbber.h" 20 #include "ui/views/window/dialog_delegate.h" 21 22 namespace autofill { 23 class AutofillProfile; 24 class CreditCard; 25 } // namespace autofill 26 27 class Profile; 28 29 namespace payments { 30 31 class PaymentRequest; 32 class PaymentRequestSheetController; 33 34 // Maps views owned by PaymentRequestDialogView::view_stack_ to their 35 // controller. PaymentRequestDialogView is responsible for listening for those 36 // views being removed from the hierarchy and delete the associated controllers. 37 using ControllerMap = 38 std::map<views::View*, std::unique_ptr<PaymentRequestSheetController>>; 39 40 enum class BackNavigationType { 41 kOneStep = 0, 42 kPaymentSheet, 43 }; 44 45 // The dialog delegate that represents a desktop WebPayments dialog. This class 46 // is responsible for displaying the view associated with the current state of 47 // the WebPayments flow and managing the transition between those states. 48 class PaymentRequestDialogView : public views::DialogDelegateView, 49 public PaymentRequestDialog, 50 public PaymentRequestSpec::Observer, 51 public InitializationTask::Observer { 52 public: 53 class ObserverForTest { 54 public: 55 virtual void OnDialogOpened() = 0; 56 57 virtual void OnContactInfoOpened() = 0; 58 59 virtual void OnOrderSummaryOpened() = 0; 60 61 virtual void OnPaymentMethodOpened() = 0; 62 63 virtual void OnShippingAddressSectionOpened() = 0; 64 65 virtual void OnShippingOptionSectionOpened() = 0; 66 67 virtual void OnCreditCardEditorOpened() = 0; 68 69 virtual void OnShippingAddressEditorOpened() = 0; 70 71 virtual void OnContactInfoEditorOpened() = 0; 72 73 virtual void OnBackNavigation() = 0; 74 75 virtual void OnBackToPaymentSheetNavigation() = 0; 76 77 virtual void OnEditorViewUpdated() = 0; 78 79 virtual void OnErrorMessageShown() = 0; 80 81 virtual void OnSpecDoneUpdating() = 0; 82 83 virtual void OnCvcPromptShown() = 0; 84 85 virtual void OnProcessingSpinnerShown() = 0; 86 87 virtual void OnProcessingSpinnerHidden() = 0; 88 89 virtual void OnPaymentHandlerWindowOpened() = 0; 90 }; 91 92 // Build a Dialog around the PaymentRequest object. |observer| is used to 93 // be notified of dialog events as they happen (but may be NULL) and should 94 // outlive this object. 95 static base::WeakPtr<PaymentRequestDialogView> Create( 96 base::WeakPtr<PaymentRequest> request, 97 PaymentRequestDialogView::ObserverForTest* observer); 98 99 // views::View 100 void RequestFocus() override; 101 102 // views::WidgetDelegate: 103 ui::ModalType GetModalType() const override; 104 views::View* GetInitiallyFocusedView() override; 105 106 // views::DialogDelegate: 107 bool ShouldShowCloseButton() const override; 108 109 // payments::PaymentRequestDialog: 110 void ShowDialog() override; 111 void CloseDialog() override; 112 void ShowErrorMessage() override; 113 void ShowProcessingSpinner() override; 114 bool IsInteractive() const override; 115 void ShowPaymentHandlerScreen( 116 const GURL& url, 117 PaymentHandlerOpenWindowCallback callback) override; 118 void RetryDialog() override; 119 void ConfirmPaymentForTesting() override; 120 121 // PaymentRequestSpec::Observer: 122 void OnStartUpdating(PaymentRequestSpec::UpdateReason reason) override; 123 void OnSpecUpdated() override; 124 125 // InitializationTask::Observer: 126 void OnInitialized(InitializationTask* initialization_task) override; 127 128 void Pay(); 129 void GoBack(); 130 void GoBackToPaymentSheet(bool animate = true); 131 void ShowContactProfileSheet(); 132 void ShowOrderSummary(); 133 void ShowShippingProfileSheet(); 134 void ShowPaymentMethodSheet(); 135 void ShowShippingOptionSheet(); 136 // |credit_card| is the card to be edited, or nullptr for adding a card. 137 // |on_edited| is called when |credit_card| was successfully edited, and 138 // |on_added| is called when a new credit card was added (the reference is 139 // short-lived; callee should make a copy of the CreditCard object). 140 // |back_navigation_type| identifies the type of navigation to execute once 141 // the editor has completed successfully. 142 void ShowCreditCardEditor( 143 BackNavigationType back_navigation_type, 144 base::OnceClosure on_edited, 145 base::OnceCallback<void(const autofill::CreditCard&)> on_added, 146 autofill::CreditCard* credit_card = nullptr); 147 // |profile| is the address to be edited, or nullptr for adding an address. 148 // |on_edited| is called when |profile| was successfully edited, and 149 // |on_added| is called when a new profile was added (the reference is 150 // short-lived; callee should make a copy of the profile object). 151 // |back_navigation_type| identifies the type of navigation to execute once 152 // the editor has completed successfully. 153 void ShowShippingAddressEditor( 154 BackNavigationType back_navigation_type, 155 base::OnceClosure on_edited, 156 base::OnceCallback<void(const autofill::AutofillProfile&)> on_added, 157 autofill::AutofillProfile* profile); 158 // |profile| is the profile to be edited, or nullptr for adding a profile. 159 // |on_edited| is called when |profile| was successfully edited, and 160 // |on_added| is called when a new profile was added (the reference is 161 // short-lived; callee should make a copy of the profile object). 162 // |back_navigation_type| identifies the type of navigation to execute once 163 // the editor has completed successfully. 164 void ShowContactInfoEditor( 165 BackNavigationType back_navigation_type, 166 base::OnceClosure on_edited, 167 base::OnceCallback<void(const autofill::AutofillProfile&)> on_added, 168 autofill::AutofillProfile* profile = nullptr); 169 void EditorViewUpdated(); 170 171 void ShowCvcUnmaskPrompt( 172 const autofill::CreditCard& credit_card, 173 base::WeakPtr<autofill::payments::FullCardRequest::ResultDelegate> 174 result_delegate, 175 content::WebContents* web_contents) override; 176 177 // Hides the full dialog spinner with the "processing" label. 178 void HideProcessingSpinner(); 179 180 Profile* GetProfile(); 181 182 // Calculates the actual payment handler dialog height based on the preferred 183 // height and current browser window size. 184 int GetActualPaymentHandlerDialogHeight() const; 185 186 // Calculates the dialog width depending on whether or not the large payment 187 // handler window is currently showing. 188 int GetActualDialogWidth() const; 189 view_stack_for_testing()190 ViewStack* view_stack_for_testing() { return view_stack_; } throbber_overlay_for_testing()191 views::View* throbber_overlay_for_testing() { return throbber_overlay_; } 192 193 private: 194 // The browsertest validates the calculated dialog size. 195 friend class PaymentHandlerWindowSizeTest; 196 197 PaymentRequestDialogView(base::WeakPtr<PaymentRequest> request, 198 PaymentRequestDialogView::ObserverForTest* observer); 199 ~PaymentRequestDialogView() override; 200 201 void OnDialogOpened(); 202 void ShowInitialPaymentSheet(); 203 void SetupSpinnerOverlay(); 204 void OnDialogClosed(); 205 void ResizeDialogWindow(); 206 207 // views::View 208 gfx::Size CalculatePreferredSize() const override; 209 void ViewHierarchyChanged( 210 const views::ViewHierarchyChangedDetails& details) override; 211 212 // The PaymentRequest object that initiated this dialog. 213 base::WeakPtr<PaymentRequest> request_; 214 ControllerMap controller_map_; 215 ViewStack* view_stack_; 216 217 // A full dialog overlay that shows a spinner and the "processing" label. It's 218 // hidden until ShowProcessingSpinner is called. 219 views::View* throbber_overlay_; 220 views::Throbber* throbber_; 221 222 // May be null. 223 ObserverForTest* observer_for_testing_; 224 225 // Used when the dialog is being closed to avoid re-entrance into the 226 // controller_map_ or view_stack_. 227 bool being_closed_ = false; 228 229 // The number of initialization tasks that are not yet initialized. 230 size_t number_of_initialization_tasks_ = 0; 231 232 // True when payment handler screen is shown and the 233 // kPaymentHandlerPopUpSizeWindow runtime flag is set. 234 bool is_showing_large_payment_handler_window_ = false; 235 236 // Calculated based on the browser content size at the time of opening payment 237 // handler window. 238 int payment_handler_window_height_ = 0; 239 240 base::WeakPtrFactory<PaymentRequestDialogView> weak_ptr_factory_{this}; 241 242 DISALLOW_COPY_AND_ASSIGN(PaymentRequestDialogView); 243 }; 244 245 } // namespace payments 246 247 #endif // CHROME_BROWSER_UI_VIEWS_PAYMENTS_PAYMENT_REQUEST_DIALOG_VIEW_H_ 248