blob: ae9fa8ee2f94db6563aa39b023a50e3980c64920 [file] [log] [blame]
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/views/autofill/payments/webauthn_dialog_view.h"
#include "chrome/browser/ui/autofill/payments/webauthn_dialog_controller.h"
#include "chrome/browser/ui/autofill/payments/webauthn_dialog_model.h"
#include "chrome/browser/ui/autofill/payments/webauthn_dialog_state.h"
#include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "chrome/browser/ui/views/webauthn/authenticator_request_sheet_view.h"
#include "chrome/browser/ui/views/webauthn/sheet_view_factory.h"
#include "components/constrained_window/constrained_window_views.h"
#include "components/web_modal/web_contents_modal_dialog_host.h"
#include "components/web_modal/web_contents_modal_dialog_manager.h"
#include "components/web_modal/web_contents_modal_dialog_manager_delegate.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/layout/fill_layout.h"
namespace autofill {
WebauthnDialogView::WebauthnDialogView(WebauthnDialogController* controller,
WebauthnDialogState dialog_state)
: controller_(controller) {
SetShowTitle(false);
SetLayoutManager(std::make_unique<views::FillLayout>());
std::unique_ptr<WebauthnDialogModel> model =
std::make_unique<WebauthnDialogModel>(dialog_state);
model_ = model.get();
model_->AddObserver(this);
sheet_view_ =
AddChildView(CreateSheetViewForAutofillWebAuthn(std::move(model)));
sheet_view_->ReInitChildViews();
SetModalType(ui::MODAL_TYPE_CHILD);
SetShowCloseButton(false);
set_fixed_width(views::LayoutProvider::Get()->GetDistanceMetric(
views::DISTANCE_MODAL_DIALOG_PREFERRED_WIDTH));
SetButtonLabel(ui::DIALOG_BUTTON_OK, model_->GetAcceptButtonLabel());
SetButtonLabel(ui::DIALOG_BUTTON_CANCEL, model_->GetCancelButtonLabel());
SetButtons(model_->IsAcceptButtonVisible()
? ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL
: ui::DIALOG_BUTTON_CANCEL);
}
WebauthnDialogView::~WebauthnDialogView() {
model_->RemoveObserver(this);
if (controller_) {
controller_->OnDialogClosed();
controller_ = nullptr;
}
}
// static
WebauthnDialog* WebauthnDialog::CreateAndShow(
WebauthnDialogController* controller,
WebauthnDialogState dialog_state) {
WebauthnDialogView* dialog = new WebauthnDialogView(controller, dialog_state);
constrained_window::ShowWebModalDialogViews(dialog,
controller->GetWebContents());
return dialog;
}
WebauthnDialogModel* WebauthnDialogView::GetDialogModel() const {
return model_;
}
void WebauthnDialogView::OnDialogStateChanged() {
switch (model_->dialog_state()) {
case WebauthnDialogState::kInactive:
Hide();
break;
case WebauthnDialogState::kOfferPending:
case WebauthnDialogState::kOfferError:
case WebauthnDialogState::kVerifyPending:
RefreshContent();
break;
case WebauthnDialogState::kUnknown:
case WebauthnDialogState::kOffer:
NOTREACHED_NORETURN();
}
}
bool WebauthnDialogView::Accept() {
DCHECK_EQ(model_->dialog_state(), WebauthnDialogState::kOffer);
controller_->OnOkButtonClicked();
return false;
}
bool WebauthnDialogView::Cancel() {
if (model_->dialog_state() == WebauthnDialogState::kOffer ||
model_->dialog_state() == WebauthnDialogState::kOfferPending ||
model_->dialog_state() == WebauthnDialogState::kVerifyPending) {
controller_->OnCancelButtonClicked();
}
return true;
}
bool WebauthnDialogView::IsDialogButtonEnabled(ui::DialogButton button) const {
return button == ui::DIALOG_BUTTON_OK ? model_->IsAcceptButtonEnabled()
: true;
}
std::u16string WebauthnDialogView::GetWindowTitle() const {
return model_->GetStepTitle();
}
void WebauthnDialogView::Hide() {
// Reset controller reference if the controller has been destroyed before the
// view being destroyed. This happens if browser window is closed when the
// dialog is visible.
if (controller_) {
controller_->OnDialogClosed();
controller_ = nullptr;
}
GetWidget()->Close();
}
void WebauthnDialogView::RefreshContent() {
sheet_view_->ReInitChildViews();
sheet_view_->InvalidateLayout();
SetButtonLabel(ui::DIALOG_BUTTON_OK, model_->GetAcceptButtonLabel());
SetButtonLabel(ui::DIALOG_BUTTON_CANCEL, model_->GetCancelButtonLabel());
DCHECK(model_->IsCancelButtonVisible());
SetButtons(model_->IsAcceptButtonVisible()
? ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL
: ui::DIALOG_BUTTON_CANCEL);
DialogModelChanged();
Layout();
// Update the dialog's size.
if (GetWidget() && controller_->GetWebContents()) {
constrained_window::UpdateWebContentsModalDialogPosition(
GetWidget(), web_modal::WebContentsModalDialogManager::FromWebContents(
controller_->GetWebContents())
->delegate()
->GetWebContentsModalDialogHost());
}
}
BEGIN_METADATA(WebauthnDialogView, views::DialogDelegateView)
END_METADATA
} // namespace autofill