blob: 61c9feb7359e082f8f9402598c7e2d2c495af19a [file] [log] [blame]
// Copyright 2016 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/previews/previews_infobar_delegate.h"
#include "base/feature_list.h"
#include "base/metrics/histogram.h"
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/android/android_theme_resources.h"
#include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.h"
#include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings_factory.h"
#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/browser/previews/previews_ui_tab_helper.h"
#include "chrome/grit/generated_resources.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
#include "components/infobars/core/infobar.h"
#include "components/previews/content/previews_ui_service.h"
#include "components/previews/core/previews_features.h"
#include "components/previews/core/previews_logger.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/l10n/l10n_util.h"
#if defined(OS_ANDROID)
#include "chrome/browser/ui/android/infobars/previews_infobar.h"
#endif
namespace {
static const char kPreviewInfobarEventType[] = "InfoBar";
void RecordPreviewsInfoBarAction(
previews::PreviewsType previews_type,
PreviewsInfoBarDelegate::PreviewsInfoBarAction action) {
int32_t max_limit =
static_cast<int32_t>(PreviewsInfoBarDelegate::INFOBAR_INDEX_BOUNDARY);
base::LinearHistogram::FactoryGet(
base::StringPrintf("Previews.InfoBarAction.%s",
GetStringNameForType(previews_type).c_str()),
1, max_limit, max_limit + 1,
base::HistogramBase::kUmaTargetedHistogramFlag)
->Add(static_cast<int32_t>(action));
}
} // namespace
PreviewsInfoBarDelegate::~PreviewsInfoBarDelegate() {
RecordPreviewsInfoBarAction(previews_type_, infobar_dismissed_action_);
}
// static
void PreviewsInfoBarDelegate::Create(
content::WebContents* web_contents,
previews::PreviewsType previews_type,
bool is_data_saver_user,
previews::PreviewsUIService* previews_ui_service) {
PreviewsUITabHelper* ui_tab_helper =
PreviewsUITabHelper::FromWebContents(web_contents);
InfoBarService* infobar_service =
InfoBarService::FromWebContents(web_contents);
// The WebContents may not have TabHelpers set. If TabHelpers are not set,
// don't show Previews infobars.
if (!ui_tab_helper || !infobar_service)
return;
if (ui_tab_helper->displayed_preview_ui())
return;
std::unique_ptr<PreviewsInfoBarDelegate> delegate(new PreviewsInfoBarDelegate(
ui_tab_helper, previews_type, is_data_saver_user));
#if defined(OS_ANDROID)
std::unique_ptr<infobars::InfoBar> infobar_ptr(
PreviewsInfoBar::CreateInfoBar(infobar_service, std::move(delegate)));
#else
std::unique_ptr<infobars::InfoBar> infobar_ptr(
infobar_service->CreateConfirmInfoBar(std::move(delegate)));
#endif
infobar_service->AddInfoBar(std::move(infobar_ptr));
uint64_t page_id = (ui_tab_helper->previews_user_data())
? ui_tab_helper->previews_user_data()->page_id()
: 0;
if (previews_ui_service) {
// Not in incognito mode or guest mode.
previews_ui_service->previews_logger()->LogMessage(
kPreviewInfobarEventType,
previews::GetDescriptionForInfoBarDescription(previews_type),
web_contents->GetController()
.GetLastCommittedEntry()
->GetRedirectChain()[0] /* GURL */,
base::Time::Now(), page_id);
}
RecordPreviewsInfoBarAction(previews_type, INFOBAR_SHOWN);
ui_tab_helper->set_displayed_preview_ui(true);
}
PreviewsInfoBarDelegate::PreviewsInfoBarDelegate(
PreviewsUITabHelper* ui_tab_helper,
previews::PreviewsType previews_type,
bool is_data_saver_user)
: ConfirmInfoBarDelegate(),
ui_tab_helper_(ui_tab_helper),
previews_type_(previews_type),
infobar_dismissed_action_(INFOBAR_DISMISSED_BY_TAB_CLOSURE),
message_text_(l10n_util::GetStringUTF16(
is_data_saver_user ? IDS_PREVIEWS_INFOBAR_SAVED_DATA_TITLE
: IDS_PREVIEWS_INFOBAR_FASTER_PAGE_TITLE)) {
DCHECK(previews_type_ != previews::PreviewsType::NONE &&
previews_type_ != previews::PreviewsType::UNSPECIFIED);
}
infobars::InfoBarDelegate::InfoBarIdentifier
PreviewsInfoBarDelegate::GetIdentifier() const {
return DATA_REDUCTION_PROXY_PREVIEW_INFOBAR_DELEGATE;
}
int PreviewsInfoBarDelegate::GetIconId() const {
#if defined(OS_ANDROID)
return IDR_ANDROID_INFOBAR_PREVIEWS;
#else
return kNoIconID;
#endif
}
bool PreviewsInfoBarDelegate::ShouldExpire(
const NavigationDetails& details) const {
infobar_dismissed_action_ = details.is_reload
? INFOBAR_DISMISSED_BY_RELOAD
: INFOBAR_DISMISSED_BY_NAVIGATION;
return InfoBarDelegate::ShouldExpire(details);
}
void PreviewsInfoBarDelegate::InfoBarDismissed() {
infobar_dismissed_action_ = INFOBAR_DISMISSED_BY_USER;
}
base::string16 PreviewsInfoBarDelegate::GetMessageText() const {
// Android has a custom infobar that calls GetStalePreviewTimestampText() and
// adds the timestamp in a separate description view. Other OS's can enable
// previews for debugging purposes and don't have a custom infobar with a
// description view, so the timestamp should be appended to the message.
#if defined(OS_ANDROID)
return message_text_;
#else
base::string16 timestamp = GetStalePreviewTimestampText();
if (timestamp.empty())
return message_text_;
// This string concatenation wouldn't fly for l10n, but this is only a hack
// for Chromium devs and not expected to ever appear for users.
return message_text_ + base::ASCIIToUTF16(" - ") + timestamp;
#endif
}
int PreviewsInfoBarDelegate::GetButtons() const {
return BUTTON_NONE;
}
base::string16 PreviewsInfoBarDelegate::GetLinkText() const {
return l10n_util::GetStringUTF16(IDS_PREVIEWS_INFOBAR_LINK);
}
bool PreviewsInfoBarDelegate::LinkClicked(WindowOpenDisposition disposition) {
infobar_dismissed_action_ = INFOBAR_LOAD_ORIGINAL_CLICKED;
ui_tab_helper_->ReloadWithoutPreviews(previews_type_);
return true;
}
base::string16 PreviewsInfoBarDelegate::GetStalePreviewTimestampText() const {
if (!ui_tab_helper_)
return base::string16();
const base::string16 text = ui_tab_helper_->GetStalePreviewTimestampText();
if (text.length() > 0)
ui_tab_helper_->set_displayed_preview_timestamp(true);
return text;
}