| // Copyright 2013 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/dialogs/outdated_upgrade_bubble.h" |
| |
| #include "base/functional/bind.h" |
| #include "base/metrics/user_metrics.h" |
| #include "base/strings/strcat.h" |
| #include "base/task/thread_pool.h" |
| #include "base/version_info/channel.h" |
| #include "build/build_config.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/ui/browser_dialogs.h" |
| #include "chrome/browser/ui/browser_element_identifiers.h" |
| #include "chrome/browser/ui/interaction/browser_elements.h" |
| #include "chrome/browser/upgrade_detector/upgrade_detector.h" |
| #include "chrome/common/channel_info.h" |
| #include "chrome/common/pref_names.h" |
| #include "chrome/common/webui_url_constants.h" |
| #include "chrome/grit/branded_strings.h" |
| #include "chrome/grit/generated_resources.h" |
| #include "components/prefs/pref_service.h" |
| #include "content/public/browser/page_navigator.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/base/models/dialog_model.h" |
| #include "url/gurl.h" |
| |
| #if BUILDFLAG(IS_WIN) |
| #include "chrome/installer/util/google_update_util.h" |
| #endif |
| |
| namespace { |
| |
| // The URL to be used to re-install Chrome when auto-update failed for too long. |
| const char* kUpdateBrowserRedirectUrl = "https://www.google.com/chrome"; |
| |
| bool g_upgrade_bubble_is_showing = false; |
| |
| void OnWindowClosing() { |
| g_upgrade_bubble_is_showing = false; |
| } |
| |
| void OnDialogAccepted(content::PageNavigator* navigator, |
| bool auto_update_enabled, |
| const std::string& update_browser_redirect_url) { |
| if (auto_update_enabled) { |
| DCHECK(UpgradeDetector::GetInstance()->is_outdated_install()); |
| base::RecordAction( |
| base::UserMetricsAction("OutdatedUpgradeBubble.Reinstall")); |
| |
| navigator->OpenURL( |
| content::OpenURLParams(GURL(update_browser_redirect_url), |
| content::Referrer(), |
| WindowOpenDisposition::NEW_FOREGROUND_TAB, |
| ui::PAGE_TRANSITION_LINK, false), |
| /*navigation_handle_callback=*/{}); |
| #if BUILDFLAG(IS_WIN) |
| } else { |
| DCHECK(UpgradeDetector::GetInstance()->is_outdated_install_no_au()); |
| base::RecordAction( |
| base::UserMetricsAction("OutdatedUpgradeBubble.EnableAU")); |
| // Record that the autoupdate flavour of the dialog has been shown. |
| if (g_browser_process->local_state()) { |
| g_browser_process->local_state()->SetBoolean( |
| prefs::kAttemptedToEnableAutoupdate, true); |
| } |
| |
| // Re-enable updates by shelling out to setup.exe asynchronously. |
| base::ThreadPool::PostTask( |
| FROM_HERE, |
| {base::MayBlock(), base::TaskPriority::BEST_EFFORT, |
| base::TaskShutdownBehavior::BLOCK_SHUTDOWN}, |
| base::BindOnce(&google_update::ElevateIfNeededToReenableUpdates)); |
| #endif // BUILDFLAG(IS_WIN) |
| } |
| } |
| |
| const char* GetUpdateUrlChannelSuffix(version_info::Channel channel) { |
| switch (channel) { |
| case version_info::Channel::CANARY: |
| return "/canary"; |
| case version_info::Channel::DEV: |
| return "/dev"; |
| case version_info::Channel::BETA: |
| return "/beta"; |
| case version_info::Channel::UNKNOWN: |
| case version_info::Channel::STABLE: |
| return ""; |
| } |
| } |
| |
| } // namespace |
| |
| void ShowOutdatedUpgradeBubble(BrowserWindowInterface* browser, |
| content::PageNavigator* page_navigator, |
| bool auto_update_enabled) { |
| if (g_upgrade_bubble_is_showing) { |
| return; |
| } |
| |
| g_upgrade_bubble_is_showing = true; |
| |
| auto update_url = std::string(kUpdateBrowserRedirectUrl) + |
| GetUpdateUrlChannelSuffix(chrome::GetChannel()); |
| |
| auto dialog_model = |
| ui::DialogModel::Builder() |
| .SetTitle(l10n_util::GetStringUTF16(IDS_UPGRADE_BUBBLE_TITLE)) |
| .AddOkButton( |
| base::BindOnce(&OnDialogAccepted, page_navigator, |
| auto_update_enabled, std::move(update_url)), |
| ui::DialogModel::Button::Params().SetLabel( |
| l10n_util::GetStringUTF16(auto_update_enabled |
| ? IDS_REINSTALL_APP |
| : IDS_REENABLE_UPDATES))) |
| .AddParagraph( |
| ui::DialogModelLabel(IDS_UPGRADE_BUBBLE_TEXT).set_is_secondary()) |
| .SetDialogDestroyingCallback(base::BindOnce(&OnWindowClosing)) |
| .SetCloseActionCallback(base::BindOnce( |
| &base::RecordAction, |
| base::UserMetricsAction("OutdatedUpgradeBubble.Later"))) |
| .Build(); |
| |
| chrome::ShowBubble(BrowserElements::From(browser)->GetContext(), |
| kToolbarAppMenuButtonElementId, std::move(dialog_model)); |
| |
| base::RecordAction( |
| auto_update_enabled |
| ? base::UserMetricsAction("OutdatedUpgradeBubble.Show") |
| : base::UserMetricsAction("OutdatedUpgradeBubble.ShowNoAU")); |
| } |