blob: f30cf62af025ca656562b9fb5f794ca018a2c481 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// 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/extensions/pwa_confirmation.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "chrome/browser/ui/views/chrome_typography.h"
#include "chrome/browser/ui/views/extensions/web_app_info_image_source.h"
#include "chrome/grit/generated_resources.h"
#include "components/strings/grit/components_strings.h"
#include "components/url_formatter/elide_url.h"
#include "extensions/common/constants.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/text_elider.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
namespace {
bool g_auto_accept_pwa_for_testing = false;
// Returns an ImageView containing the app icon.
std::unique_ptr<views::ImageView> CreateIconView(
const std::vector<WebApplicationInfo::IconInfo>& icons) {
constexpr int kIconSize = 48;
gfx::ImageSkia image(
std::make_unique<WebAppInfoImageSource>(kIconSize, icons),
gfx::Size(kIconSize, kIconSize));
auto icon_image_view = std::make_unique<views::ImageView>();
icon_image_view->SetImage(image);
return icon_image_view;
}
// Returns a label containing the app name.
std::unique_ptr<views::Label> CreateNameLabel(const base::string16& name) {
auto name_label = std::make_unique<views::Label>(
name, CONTEXT_BODY_TEXT_LARGE, views::style::TextStyle::STYLE_PRIMARY);
name_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
name_label->SetElideBehavior(gfx::ELIDE_TAIL);
return name_label;
}
std::unique_ptr<views::Label> CreateOriginLabel(const url::Origin& origin) {
auto origin_label = std::make_unique<views::Label>(
FormatOriginForSecurityDisplay(
origin, url_formatter::SchemeDisplay::OMIT_HTTP_AND_HTTPS),
CONTEXT_BODY_TEXT_SMALL, STYLE_SECONDARY);
origin_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
// Elide from head to prevent origin spoofing.
origin_label->SetElideBehavior(gfx::ELIDE_HEAD);
// Multiline breaks elision, so explicitly disable multiline.
origin_label->SetMultiLine(false);
return origin_label;
}
void InitializeDialogView(views::DialogDelegateView* dialog,
const WebApplicationInfo& web_app_info) {
const ChromeLayoutProvider* layout_provider = ChromeLayoutProvider::Get();
// Use CONTROL insets, because the icon is non-text (see documentation for
// DialogContentType).
gfx::Insets margin_insets = layout_provider->GetDialogInsetsForContentType(
views::CONTROL, views::CONTROL);
dialog->set_margins(margin_insets);
int icon_label_spacing = layout_provider->GetDistanceMetric(
views::DISTANCE_RELATED_CONTROL_HORIZONTAL);
dialog->SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::kHorizontal, gfx::Insets(), icon_label_spacing));
dialog->AddChildView(CreateIconView(web_app_info.icons).release());
views::View* labels = new views::View();
dialog->AddChildView(labels);
labels->SetLayoutManager(
std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical));
labels->AddChildView(CreateNameLabel(web_app_info.title).release());
labels->AddChildView(
CreateOriginLabel(url::Origin::Create(web_app_info.app_url)).release());
}
} // namespace
PWAConfirmation::PWAConfirmation(
views::DialogDelegateView* dialog,
std::unique_ptr<WebApplicationInfo> web_app_info,
chrome::AppInstallationAcceptanceCallback callback)
: web_app_info_(std::move(web_app_info)), callback_(std::move(callback)) {
DCHECK(web_app_info_);
base::TrimWhitespace(web_app_info_->title, base::TRIM_ALL,
&web_app_info_->title);
// PWAs should always be configured to open in a window.
DCHECK(web_app_info_->open_as_window);
InitializeDialogView(dialog, *web_app_info_);
chrome::RecordDialogCreation(chrome::DialogIdentifier::PWA_CONFIRMATION);
if (g_auto_accept_pwa_for_testing)
dialog->Accept();
}
PWAConfirmation::~PWAConfirmation() {}
base::string16 PWAConfirmation::GetWindowTitle() {
return l10n_util::GetStringUTF16(
IDS_INSTALL_TO_OS_LAUNCH_SURFACE_BUBBLE_TITLE);
}
base::string16 PWAConfirmation::GetDialogButtonLabel(ui::DialogButton button) {
return l10n_util::GetStringUTF16(button == ui::DIALOG_BUTTON_OK
? IDS_INSTALL_PWA_BUTTON_LABEL
: IDS_CANCEL);
}
void PWAConfirmation::Accept() {
DCHECK(web_app_info_);
std::move(callback_).Run(true, std::move(web_app_info_));
}
void PWAConfirmation::WindowClosing() {
if (callback_) {
DCHECK(web_app_info_);
std::move(callback_).Run(false, std::move(web_app_info_));
}
}
namespace chrome {
void SetAutoAcceptPWAInstallConfirmationForTesting(bool auto_accept) {
g_auto_accept_pwa_for_testing = auto_accept;
}
} // namespace chrome