Chromium Code Reviews| Index: chrome/browser/ui/startup/default_browser_infobar_delegate.cc |
| diff --git a/chrome/browser/ui/startup/default_browser_infobar_delegate.cc b/chrome/browser/ui/startup/default_browser_infobar_delegate.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..2ddc36c4423883f51f83111a4aff8c79c959cdfc |
| --- /dev/null |
| +++ b/chrome/browser/ui/startup/default_browser_infobar_delegate.cc |
| @@ -0,0 +1,177 @@ |
| +// 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/ui/startup/default_browser_infobar_delegate.h" |
| + |
| +#include "base/metrics/histogram_macros.h" |
| +#include "base/threading/thread_task_runner_handle.h" |
| +#include "chrome/browser/ui/startup/default_browser_prompt.h" |
| +#include "chrome/grit/chromium_strings.h" |
| +#include "chrome/grit/generated_resources.h" |
| +#include "components/infobars/core/infobar.h" |
| +#include "content/public/browser/user_metrics.h" |
| +#include "grit/theme_resources.h" |
| +#include "ui/base/l10n/l10n_util.h" |
| +#include "ui/gfx/vector_icons_public.h" |
| + |
| +#if defined(OS_WIN) |
| +#include "base/win/windows_version.h" |
| +#endif |
| + |
| +namespace chrome { |
| +/* |
| +const base::Feature kStickyDefaultBrowserPrompt{ |
| + "StickyDefaultBrowserPrompt", base::FEATURE_DISABLED_BY_DEFAULT};*/ |
|
Peter Kasting
2016/06/01 19:32:10
Remove
Patrick Monette
2016/06/01 22:07:40
Done.
|
| + |
| +bool IsStickyDefaultBrowserPromptEnabled() { |
| +#if defined(OS_WIN) |
| + // The flow to set the default browser is only asynchronous on Windows 10+. |
| + return base::win::GetVersion() >= base::win::VERSION_WIN10 && |
| + base::FeatureList::IsEnabled(kStickyDefaultBrowserPrompt); |
| +#else |
| + return false; |
| +#endif |
| +} |
| + |
| +// static |
| +void DefaultBrowserInfoBarDelegate::Create(InfoBarService* infobar_service, |
| + Profile* profile) { |
| + infobar_service->AddInfoBar(infobar_service->CreateConfirmInfoBar( |
| + std::unique_ptr<ConfirmInfoBarDelegate>( |
| + new DefaultBrowserInfoBarDelegate(profile)))); |
| +} |
| + |
| +DefaultBrowserInfoBarDelegate::DefaultBrowserInfoBarDelegate(Profile* profile) |
| + : ConfirmInfoBarDelegate(), |
| + profile_(profile), |
| + should_expire_(false), |
| + weak_factory_(this) { |
| + // We want the info-bar to stick-around for few seconds and then be hidden |
| + // on the next navigation after that. |
| + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| + FROM_HERE, base::Bind(&DefaultBrowserInfoBarDelegate::AllowExpiry, |
| + weak_factory_.GetWeakPtr()), |
| + base::TimeDelta::FromSeconds(8)); |
| +} |
| + |
| +DefaultBrowserInfoBarDelegate::~DefaultBrowserInfoBarDelegate() = default; |
| + |
| +infobars::InfoBarDelegate::Type DefaultBrowserInfoBarDelegate::GetInfoBarType() |
| + const { |
| +#if defined(OS_WIN) |
| + return WARNING_TYPE; |
| +#else |
| + return PAGE_ACTION_TYPE; |
| +#endif |
| +} |
| + |
| +infobars::InfoBarDelegate::InfoBarIdentifier |
| +DefaultBrowserInfoBarDelegate::GetIdentifier() const { |
| + return DEFAULT_BROWSER_INFOBAR_DELEGATE; |
| +} |
| + |
| +int DefaultBrowserInfoBarDelegate::GetIconId() const { |
| + return IDR_PRODUCT_LOGO_32; |
| +} |
| + |
| +gfx::VectorIconId DefaultBrowserInfoBarDelegate::GetVectorIconId() const { |
| +#if defined(OS_MACOSX) || defined(OS_ANDROID) |
| + return gfx::VectorIconId::VECTOR_ICON_NONE; |
| +#else |
| + return gfx::VectorIconId::CHROME_PRODUCT; |
| +#endif |
| +} |
| + |
| +bool DefaultBrowserInfoBarDelegate::ShouldExpire( |
| + const NavigationDetails& details) const { |
| + return should_expire_ && ConfirmInfoBarDelegate::ShouldExpire(details); |
| +} |
| + |
| +void DefaultBrowserInfoBarDelegate::InfoBarDismissed() { |
| + content::RecordAction( |
| + base::UserMetricsAction("DefaultBrowserInfoBar_Dismiss")); |
| + UMA_HISTOGRAM_ENUMERATION("DefaultBrowser.InfoBar.UserInteraction", |
| + IGNORE_INFO_BAR, |
| + NUM_INFO_BAR_USER_INTERACTION_TYPES); |
| +} |
| + |
| +base::string16 DefaultBrowserInfoBarDelegate::GetMessageText() const { |
| + return l10n_util::GetStringUTF16(IDS_DEFAULT_BROWSER_INFOBAR_SHORT_TEXT); |
| +} |
| + |
| +base::string16 DefaultBrowserInfoBarDelegate::GetButtonLabel( |
| + InfoBarButton button) const { |
| +#if defined(OS_WIN) |
| + // On Windows 10, the "OK" button opens the Windows Settings application, |
| + // through which the user must make their default browser choice. |
| + const int kSetAsDefaultButtonMessageId = |
| + base::win::GetVersion() >= base::win::VERSION_WIN10 |
| + ? IDS_DEFAULT_BROWSER_INFOBAR_OK_BUTTON_LABEL_WIN_10 |
| + : IDS_DEFAULT_BROWSER_INFOBAR_OK_BUTTON_LABEL; |
| +#else |
| + const int kSetAsDefaultButtonMessageId = |
| + IDS_DEFAULT_BROWSER_INFOBAR_OK_BUTTON_LABEL; |
| +#endif |
| + return l10n_util::GetStringUTF16( |
| + button == BUTTON_OK ? kSetAsDefaultButtonMessageId |
| + : IDS_DEFAULT_BROWSER_INFOBAR_CANCEL_BUTTON_LABEL); |
| +} |
| + |
| +// Setting an app as the default browser doesn't require elevation directly, but |
| +// it does require registering it as the protocol handler for "http", so if |
| +// protocol registration in general requires elevation, this does as well. |
| +bool DefaultBrowserInfoBarDelegate::OKButtonTriggersUACPrompt() const { |
| + return shell_integration::IsElevationNeededForSettingDefaultProtocolClient(); |
| +} |
| + |
| +bool DefaultBrowserInfoBarDelegate::Accept() { |
| + content::RecordAction( |
| + base::UserMetricsAction("DefaultBrowserInfoBar_Accept")); |
| + UMA_HISTOGRAM_ENUMERATION("DefaultBrowser.InfoBar.UserInteraction", |
| + ACCEPT_INFO_BAR, |
| + NUM_INFO_BAR_USER_INTERACTION_TYPES); |
| + |
| + bool close_infobar = true; |
| + shell_integration::DefaultWebClientWorkerCallback set_as_default_callback; |
| + |
| + if (IsStickyDefaultBrowserPromptEnabled()) { |
| + // When the experiment is enabled, the infobar is only closed when the |
| + // DefaultBrowserWorker is finished. |
| + set_as_default_callback = |
| + base::Bind(&DefaultBrowserInfoBarDelegate::OnSetAsDefaultFinished, |
| + weak_factory_.GetWeakPtr()); |
| + close_infobar = false; |
| + } |
| + |
| + // The worker pointer is reference counted. While it is running, the |
| + // message loops of the FILE and UI thread will hold references to it |
| + // and it will be automatically freed once all its tasks have finished. |
| + CreateDefaultBrowserWorker(set_as_default_callback)->StartSetAsDefault(); |
| + return close_infobar; |
| +} |
| + |
| +bool DefaultBrowserInfoBarDelegate::Cancel() { |
| + // This can get reached in tests where profile_ is null. |
| + if (profile_) |
| + chrome::DefaultBrowserPromptDeclined(profile_); |
| + content::RecordAction( |
| + base::UserMetricsAction("DefaultBrowserInfoBar_Cancel")); |
| + UMA_HISTOGRAM_ENUMERATION("DefaultBrowser.InfoBar.UserInteraction", |
| + CANCEL_INFO_BAR, |
| + NUM_INFO_BAR_USER_INTERACTION_TYPES); |
| + return true; |
| +} |
| + |
| +scoped_refptr<shell_integration::DefaultBrowserWorker> |
| +DefaultBrowserInfoBarDelegate::CreateDefaultBrowserWorker( |
| + const shell_integration::DefaultWebClientWorkerCallback& callback) { |
| + return new shell_integration::DefaultBrowserWorker(callback); |
| +} |
| + |
| +void DefaultBrowserInfoBarDelegate::OnSetAsDefaultFinished( |
| + shell_integration::DefaultWebClientState state) { |
| + infobar()->owner()->RemoveInfoBar(infobar()); |
| +} |
| + |
| +} // namespace chrome |