blob: d0947f1982f351f3428f93c336cc1ba59cfa6670 [file] [log] [blame]
// Copyright 2022 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_WEBID_ACCOUNT_SELECTION_BUBBLE_VIEW_H_
#define CHROME_BROWSER_UI_VIEWS_WEBID_ACCOUNT_SELECTION_BUBBLE_VIEW_H_
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "chrome/browser/ui/views/webid/account_selection_bubble_view_interface.h"
#include "components/image_fetcher/core/image_fetcher.h"
#include "content/public/browser/identity_request_account.h"
#include "content/public/browser/identity_request_dialog_controller.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "third_party/blink/public/mojom/webid/federated_auth_request.mojom.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/views/bubble/bubble_dialog_delegate_view.h"
#include "ui/views/view.h"
namespace views {
class Checkbox;
class ImageButton;
class ImageView;
class Label;
class MdTextButton;
} // namespace views
namespace {
class IdpImageView;
} // namespace
// Bubble dialog that is used in the FedCM flow. It creates a dialog with an
// account chooser for the user, and it changes the content of that dialog as
// user moves through the FedCM flow steps.
class AccountSelectionBubbleView : public views::BubbleDialogDelegateView,
public AccountSelectionBubbleViewInterface {
public:
// Used to observe changes to the account selection bubble.
class Observer {
public:
enum class LinkType { PRIVACY_POLICY, TERMS_OF_SERVICE };
// Called when a user either selects the account from the multi-account
// chooser or clicks the "continue" button.
// Takes `account` as well as `idp_display_data` since passing `account_id`
// is insufficient in the multiple IDP case. The caller should pass a cref,
// as these objects are owned by the observer.
virtual void OnAccountSelected(
const content::IdentityRequestAccount& account,
const IdentityProviderDisplayData& idp_display_data,
const ui::Event& event) = 0;
// Called when the user clicks "privacy policy" or "terms of service" link.
virtual void OnLinkClicked(LinkType link_type,
const GURL& url,
const ui::Event& event) = 0;
// Called when the user clicks "back" button.
virtual void OnBackButtonClicked() = 0;
// Called when the user clicks "close" button.
virtual void OnCloseButtonClicked(const ui::Event& event) = 0;
// Called when the user clicks the "continue" button on the sign-in
// failure dialog.
virtual void OnSigninToIdP() = 0;
// Called when IdentityProvider.close() is called from the renderer.
virtual void CloseModalDialog() = 0;
};
METADATA_HEADER(AccountSelectionBubbleView);
AccountSelectionBubbleView(
const std::u16string& top_frame_for_display,
const absl::optional<std::u16string>& iframe_for_display,
const absl::optional<std::u16string>& idp_title,
blink::mojom::RpContext rp_context,
bool show_auto_reauthn_checkbox,
views::View* anchor_view,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
Observer* observer);
~AccountSelectionBubbleView() override;
// AccountSelectionBubbleViewInterface:
void ShowMultiAccountPicker(const std::vector<IdentityProviderDisplayData>&
idp_display_data_list) override;
void ShowVerifyingSheet(const content::IdentityRequestAccount& account,
const IdentityProviderDisplayData& idp_display_data,
const std::u16string& title) override;
void ShowSingleAccountConfirmDialog(
const std::u16string& top_frame_for_display,
const absl::optional<std::u16string>& iframe_for_display,
const content::IdentityRequestAccount& account,
const IdentityProviderDisplayData& idp_display_data,
bool show_back_button) override;
void ShowFailureDialog(
const std::u16string& top_frame_for_display,
const absl::optional<std::u16string>& iframe_for_display,
const std::u16string& idp_for_display,
const content::IdentityProviderMetadata& idp_metadata) override;
// Populates `idp_images` when an IDP image has been fetched.
void AddIdpImage(const GURL& image_url, gfx::ImageSkia idp_image);
std::string GetDialogTitle() const override;
absl::optional<std::string> GetDialogSubtitle() const override;
private:
gfx::Rect GetBubbleBounds() override;
// Returns a View containing the logo of the identity provider. Creates the
// `header_icon_view_` if `has_idp_icon` is true.
std::unique_ptr<views::View> CreateHeaderView(bool has_idp_icon);
// Returns a View for single account chooser. It contains the account
// information, disclosure text and a button for the user to confirm the
// selection. The size of the `idp_display_data.accounts` vector must be 1.
std::unique_ptr<views::View> CreateSingleAccountChooser(
const IdentityProviderDisplayData& idp_display_data,
const content::IdentityRequestAccount& account);
// Returns a View for multiple account chooser. It contains the info for each
// account in a button, so the user can pick an account.
std::unique_ptr<views::View> CreateMultipleAccountChooser(
const std::vector<IdentityProviderDisplayData>& idp_display_data_list);
// Creates a row containing the IDP icon as well as the IDP ETLD+1. Used in
// the multi IDP scenario, when the user is selecting from multiple accounts.
std::unique_ptr<views::View> CreateIdpHeaderRowForMultiIdp(
const std::u16string& idp_for_display,
const content::IdentityProviderMetadata& idp_metadata);
// Returns a View containing information about an account: the picture for
// the account on the left, and information about the account on the right.
// |should_hover| determines whether the account row is a HoverButton or
// not.
std::unique_ptr<views::View> CreateAccountRow(
const content::IdentityRequestAccount& account,
const IdentityProviderDisplayData& idp_display_data,
bool should_hover);
// Updates the header title, the header icon visibility and the header back
// button visibiltiy. `idp_metadata` is not null when we need to set a header
// image based on the IDP.
void UpdateHeader(const content::IdentityProviderMetadata& idp_metadata,
const std::u16string subpage_title,
const std::u16string subpage_subtitle,
bool show_back_button);
// Sets the brand views::ImageView visibility and image. Initiates the
// download of the brand icon if necessary.
void ConfigureIdpBrandImageView(
IdpImageView* image_view,
const content::IdentityProviderMetadata& idp_metadata);
// Removes all children except for `header_view_`.
void RemoveNonHeaderChildViews();
// Opens a modal dialog webview that renders the given `url`.
void ShowModalDialog(const GURL& url);
// Closes the modal webview dialog, if it is shown.
void CloseModalDialog();
// The ImageFetcher used to fetch the account pictures for FedCM.
std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher_;
// The accessible title.
std::u16string accessible_title_;
// The initial title for the dialog.
std::u16string title_;
// The initial subtitle for the dialog.
std::u16string subtitle_;
blink::mojom::RpContext rp_context_;
// The images for the IDP icons. Stored so that they can be reused upon
// pressing the back button after choosing an account on the multi IDP
// chooser.
base::flat_map<GURL, gfx::ImageSkia> idp_images_;
// Whether the dialog has been populated via either ShowMultiAccountPicker()
// or ShowVerifyingSheet().
bool has_sheet_{false};
// View containing the logo of the identity provider and the title.
raw_ptr<views::View> header_view_ = nullptr;
// View containing the header IDP icon, if one needs to be used.
raw_ptr<IdpImageView> header_icon_view_ = nullptr;
// View containing the back button.
raw_ptr<views::ImageButton> back_button_ = nullptr;
// View containing the bubble title.
raw_ptr<views::Label> title_label_ = nullptr;
// View containing the bubble subtitle, which is empty if the iframe domain
// does not need to be displayed.
raw_ptr<views::Label> subtitle_label_ = nullptr;
// View containing the continue button.
raw_ptr<views::MdTextButton> continue_button_ = nullptr;
// View containing the sign in to IDP button.
raw_ptr<views::MdTextButton> signin_to_idp_button_ = nullptr;
// Auto re-authn opt-out checkbox.
raw_ptr<views::Checkbox> auto_reauthn_checkbox_ = nullptr;
// Whether to show the auto re-authn opt-out checkbox;
bool show_auto_reauthn_checkbox_{false};
// Observes events on AccountSelectionBubbleView.
// Dangling when running Chromedriver's run_py_tests.py test suite.
raw_ptr<Observer, DanglingUntriaged> observer_{nullptr};
// Used to ensure that callbacks are not run if the AccountSelectionBubbleView
// is destroyed.
base::WeakPtrFactory<AccountSelectionBubbleView> weak_ptr_factory_{this};
};
#endif // CHROME_BROWSER_UI_VIEWS_WEBID_ACCOUNT_SELECTION_BUBBLE_VIEW_H_