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