#include "chrome/browser/ui/views/webid/fedcm_modal_dialog_view.h"
#include <algorithm>
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "components/constrained_window/constrained_window_views.h"
#include "components/url_formatter/elide_url.h"
#include "components/web_modal/web_contents_modal_dialog_manager.h"
#include "content/public/browser/webid/identity_request_dialog_controller.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/views/border.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/layout/table_layout.h"
namespace webid {
namespace {
gfx::Rect ComputePopupWindowBounds(gfx::Rect source_window_bounds) {
constexpr int kPopupWindowWidth = 500;
constexpr int kPopupWindowPreferredHeight = 600;
int popup_window_height =
std::min(kPopupWindowPreferredHeight,
static_cast<int>(source_window_bounds.height() * 0.8));
int x_coordinate = source_window_bounds.x() +
((source_window_bounds.width() - kPopupWindowWidth) / 2);
int y_coordinate =
source_window_bounds.y() +
((source_window_bounds.height() - popup_window_height) / 2);
return gfx::Rect(x_coordinate, y_coordinate, kPopupWindowWidth,
popup_window_height);
}
}
FedCmModalDialogView::FedCmModalDialogView(
content::WebContents* web_contents,
FedCmModalDialogView::Observer* observer)
: source_window_(web_contents), observer_(observer) {}
FedCmModalDialogView::~FedCmModalDialogView() = default;
content::WebContents* FedCmModalDialogView::ShowPopupWindow(
const GURL& url,
bool user_close_cancels_flow) {
user_close_cancels_flow_ = user_close_cancels_flow;
if (popup_window_) {
return popup_window_;
}
if (!url.is_valid() || !url.SchemeIsHTTPOrHTTPS()) {
UMA_HISTOGRAM_ENUMERATION(
"Blink.FedCm.IdpSigninStatus.ShowPopupWindowResult",
ShowPopupWindowResult::kFailedByInvalidUrl);
return nullptr;
}
content::OpenURLParams params(
url, content::Referrer(), WindowOpenDisposition::NEW_POPUP,
ui::PAGE_TRANSITION_AUTO_TOPLEVEL, false);
popup_window_ = source_window_->GetDelegate()->OpenURLFromTab(
source_window_, params, {});
if (!popup_window_) {
UMA_HISTOGRAM_ENUMERATION(
"Blink.FedCm.IdpSigninStatus.ShowPopupWindowResult",
ShowPopupWindowResult::kFailedForOtherReasons);
return nullptr;
}
ResizeAndFocusPopupWindow();
Observe(popup_window_);
UMA_HISTOGRAM_ENUMERATION("Blink.FedCm.IdpSigninStatus.ShowPopupWindowResult",
ShowPopupWindowResult::kSuccess);
return popup_window_;
}
void FedCmModalDialogView::ClosePopupWindow() {
if (!popup_window_) {
return;
}
std::string histogram_name =
active_mode_sheet_type_ == webid::SheetType::kLoading
? "Blink.FedCm.Button.LoadingStatePopupInteraction"
: "Blink.FedCm.Button.UseOtherAccountPopupInteraction";
PopupInteraction metric =
num_lost_focus_ > 0
? PopupInteraction::kLosesFocusAndIdpInitiatedClose
: PopupInteraction::kNeverLosesFocusAndIdpInitiatedClose;
if (!popup_interaction_metric_recorded_) {
base::UmaHistogramEnumeration(histogram_name, metric);
popup_interaction_metric_recorded_ = true;
}
content::WebContents* popup = popup_window_;
popup_window_ = nullptr;
popup->Close();
UMA_HISTOGRAM_ENUMERATION(
"Blink.FedCm.IdpSigninStatus.ClosePopupWindowReason",
FedCmModalDialogView::ClosePopupWindowReason::kIdpInitiatedClose);
}
void FedCmModalDialogView::ResizeAndFocusPopupWindow() {
CHECK(popup_window_);
gfx::Rect popup_window_bounds =
ComputePopupWindowBounds(source_window_->GetContainerBounds());
if (custom_y_position_) {
popup_window_bounds.set_y(*custom_y_position_);
}
popup_window_->GetDelegate()->SetContentsBounds(popup_window_,
popup_window_bounds);
popup_window_->GetDelegate()->ActivateContents(popup_window_);
}
void FedCmModalDialogView::WebContentsDestroyed() {
std::string histogram_name =
active_mode_sheet_type_ == webid::SheetType::kLoading
? "Blink.FedCm.Button.LoadingStatePopupInteraction"
: "Blink.FedCm.Button.UseOtherAccountPopupInteraction";
PopupInteraction metric =
num_lost_focus_ > 1
? PopupInteraction::kLosesFocusAndPopupWindowDestroyed
: PopupInteraction::kNeverLosesFocusAndPopupWindowDestroyed;
if (!popup_interaction_metric_recorded_) {
base::UmaHistogramEnumeration(histogram_name, metric);
popup_interaction_metric_recorded_ = true;
}
popup_window_ = nullptr;
if (observer_) {
observer_->OnPopupWindowDestroyed();
}
UMA_HISTOGRAM_ENUMERATION(
"Blink.FedCm.IdpSigninStatus.ClosePopupWindowReason",
FedCmModalDialogView::ClosePopupWindowReason::kPopupWindowDestroyed);
}
void FedCmModalDialogView::SetCustomYPosition(int y) {
custom_y_position_ = y;
}
void FedCmModalDialogView::SetActiveModeSheetType(webid::SheetType sheet_type) {
active_mode_sheet_type_ = sheet_type;
}
bool FedCmModalDialogView::UserCloseCancelsFlow() {
return user_close_cancels_flow_;
}
void FedCmModalDialogView::OnWebContentsLostFocus(
content::RenderWidgetHost* render_widget_host) {
++num_lost_focus_;
}
void FedCmModalDialogView::ResetObserver() {
observer_ = nullptr;
}
FedCmModalDialogView::Observer* FedCmModalDialogView::GetObserverForTesting() {
return observer_;
}
}