// 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/lifetime/browser_close_manager.h"

#include <memory>
#include <optional>
#include <utility>
#include <vector>

#include "base/callback_list.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/background/background_mode_manager.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/defaults.h"
#include "chrome/browser/download/chrome_download_manager_delegate.h"
#include "chrome/browser/download/download_browsertest_utils.h"
#include "chrome/browser/download/download_core_service.h"
#include "chrome/browser/download/download_core_service_factory.h"
#include "chrome/browser/download/download_prefs.h"
#include "chrome/browser/lifetime/application_lifetime_desktop.h"
#include "chrome/browser/lifetime/browser_shutdown.h"
#include "chrome/browser/prefs/session_startup_pref.h"
#include "chrome/browser/profiles/keep_alive/profile_keep_alive_types.h"
#include "chrome/browser/profiles/keep_alive/scoped_profile_keep_alive.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/sessions/tab_restore_service_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/tabs/tab_enums.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/buildflags.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/download/public/common/download_item.h"
#include "components/download/public/common/download_target_info.h"
#include "components/javascript_dialogs/app_modal_dialog_controller.h"
#include "components/javascript_dialogs/app_modal_dialog_view.h"
#include "components/keep_alive_registry/keep_alive_types.h"
#include "components/keep_alive_registry/scoped_keep_alive.h"
#include "components/sessions/core/tab_restore_service.h"
#include "components/sessions/core/tab_restore_service_observer.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/download_test_observer.h"
#include "content/public/test/slow_download_http_response.h"
#include "content/public/test/test_navigation_observer.h"
#include "net/test/embedded_test_server/embedded_test_server.h"

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "ash/constants/ash_switches.h"
#endif

namespace {

javascript_dialogs::AppModalDialogView* GetNextDialog() {
  javascript_dialogs::AppModalDialogController* dialog =
      ui_test_utils::WaitForAppModalDialog();
  CHECK(dialog->view());
  return dialog->view();
}

// Note: call |PrepareForDialog| on the relevant WebContents or Browser before
// trying to close it, to avoid flakiness. https://crbug.com/519646
void AcceptClose() {
  GetNextDialog()->AcceptAppModalDialog();
}

// Note: call |PrepareForDialog| on the relevant WebContents or Browser before
// trying to close it, to avoid flakiness. https://crbug.com/519646
void CancelClose() {
  GetNextDialog()->CancelAppModalDialog();
}

class AllBrowsersClosingCancelledObserver {
 public:
  explicit AllBrowsersClosingCancelledObserver(int count)
      : num_outstanding_(count) {
    closing_all_browsers_subscription_ =
        chrome::AddClosingAllBrowsersCallback(base::BindRepeating(
            &AllBrowsersClosingCancelledObserver::OnClosingAllBrowsersChanged,
            base::Unretained(this)));
  }

  void OnClosingAllBrowsersChanged(bool closing) {
    if (closing)
      return;

    ASSERT_GT(num_outstanding_, 0);
    if (!--num_outstanding_)
      run_loop_.Quit();
  }

  void Wait() {
    run_loop_.Run();
    EXPECT_LE(num_outstanding_, 0);
  }

 private:
  base::CallbackListSubscription closing_all_browsers_subscription_;
  int num_outstanding_;
  base::RunLoop run_loop_;
};

class TabRestoreServiceChangesObserver
    : public sessions::TabRestoreServiceObserver {
 public:
  explicit TabRestoreServiceChangesObserver(Profile* profile)
      : service_(TabRestoreServiceFactory::GetForProfile(profile)) {
    if (service_)
      service_->AddObserver(this);
  }

  TabRestoreServiceChangesObserver(const TabRestoreServiceChangesObserver&) =
      delete;
  TabRestoreServiceChangesObserver& operator=(
      const TabRestoreServiceChangesObserver&) = delete;

  ~TabRestoreServiceChangesObserver() override {
    if (service_)
      service_->RemoveObserver(this);
  }

  size_t changes_count() const { return changes_count_; }

 private:
  // sessions::TabRestoreServiceObserver:
  void TabRestoreServiceChanged(sessions::TabRestoreService*) override {
    changes_count_++;
  }

  // sessions::TabRestoreServiceObserver:
  void TabRestoreServiceDestroyed(sessions::TabRestoreService*) override {
    service_ = nullptr;
  }

  raw_ptr<sessions::TabRestoreService, DanglingUntriaged> service_ = nullptr;
  size_t changes_count_ = 0;
};

class TestBrowserCloseManager : public BrowserCloseManager {
 public:
  enum UserChoice {
    USER_CHOICE_USER_CANCELS_CLOSE,
    USER_CHOICE_USER_ALLOWS_CLOSE,
    NO_USER_CHOICE
  };

  TestBrowserCloseManager(const TestBrowserCloseManager&) = delete;
  TestBrowserCloseManager& operator=(const TestBrowserCloseManager&) = delete;

  static void AttemptClose(UserChoice user_choice) {
    scoped_refptr<BrowserCloseManager> browser_close_manager =
        new TestBrowserCloseManager(user_choice);
    browser_shutdown::SetTryingToQuit(true);
    browser_close_manager->StartClosingBrowsers();
  }

 protected:
  ~TestBrowserCloseManager() override {}

  void ConfirmCloseWithPendingDownloads(
      int download_count,
      base::OnceCallback<void(bool)> callback) override {
    EXPECT_NE(NO_USER_CHOICE, user_choice_);
    switch (user_choice_) {
      case NO_USER_CHOICE:
      case USER_CHOICE_USER_CANCELS_CLOSE: {
        std::move(callback).Run(false);
        break;
      }
      case USER_CHOICE_USER_ALLOWS_CLOSE: {
        std::move(callback).Run(true);
        break;
      }
    }
  }

 private:
  explicit TestBrowserCloseManager(UserChoice user_choice)
      : user_choice_(user_choice) {}

  UserChoice user_choice_;
};

class TestDownloadManagerDelegate : public ChromeDownloadManagerDelegate {
 public:
  explicit TestDownloadManagerDelegate(Profile* profile)
      : ChromeDownloadManagerDelegate(profile) {
    GetDownloadIdReceiverCallback().Run(download::DownloadItem::kInvalidId + 1);
  }
  ~TestDownloadManagerDelegate() override {}

  bool DetermineDownloadTarget(
      download::DownloadItem* item,
      download::DownloadTargetCallback* callback) override {
    auto set_dangerous = [](download::DownloadTargetCallback callback,
                            download::DownloadTargetInfo target_info) {
      target_info.danger_type = download::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL;
      std::move(callback).Run(std::move(target_info));
    };

    download::DownloadTargetCallback dangerous_callback =
        base::BindOnce(set_dangerous, std::move(*callback));
    bool run = ChromeDownloadManagerDelegate::DetermineDownloadTarget(
        item, &dangerous_callback);
    // ChromeDownloadManagerDelegate::DetermineDownloadTarget() needs to run the
    // |callback|.
    DCHECK(run);
    DCHECK(!dangerous_callback);
    return true;
  }
};

#if BUILDFLAG(ENABLE_BACKGROUND_MODE)
class FakeBackgroundModeManager : public BackgroundModeManager {
 public:
  FakeBackgroundModeManager()
      : BackgroundModeManager(*base::CommandLine::ForCurrentProcess(),
                              &g_browser_process->profile_manager()
                                  ->GetProfileAttributesStorage()),
        suspended_(false) {}

  FakeBackgroundModeManager(const FakeBackgroundModeManager&) = delete;
  FakeBackgroundModeManager& operator=(const FakeBackgroundModeManager&) =
      delete;

  void SuspendBackgroundMode() override {
    BackgroundModeManager::SuspendBackgroundMode();
    suspended_ = true;
  }

  void ResumeBackgroundMode() override {
    BackgroundModeManager::ResumeBackgroundMode();
    suspended_ = false;
  }

  bool IsBackgroundModeSuspended() {
    return suspended_;
  }

 private:
  bool suspended_;
};
#endif  // BUILDFLAG(ENABLE_BACKGROUND_MODE)

}  // namespace

class BrowserCloseManagerBrowserTest : public InProcessBrowserTest {
 protected:
  void SetUpOnMainThread() override {
    SessionStartupPref::SetStartupPref(
        browser()->profile(), SessionStartupPref(SessionStartupPref::LAST));
    browsers_.push_back(browser());
    embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
        &content::SlowDownloadHttpResponse::HandleSlowDownloadRequest));
    ASSERT_TRUE(embedded_test_server()->Start());
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
#if BUILDFLAG(IS_CHROMEOS_ASH)
    command_line->AppendSwitch(
        ash::switches::kIgnoreUserProfileMappingForTests);
#endif
  }

  void CreateStalledDownload(Browser* browser) {
    ASSERT_TRUE(embedded_test_server()->Started());

    GURL slow_download_url = embedded_test_server()->GetURL(
        content::SlowDownloadHttpResponse::kKnownSizeUrl);

    content::DownloadTestObserverInProgress observer(
        browser->profile()->GetDownloadManager(), 1);
    SetPromptForDownload(browser, false);
    ui_test_utils::NavigateToURLWithDisposition(
        browser, slow_download_url, WindowOpenDisposition::NEW_BACKGROUND_TAB,
        ui_test_utils::BROWSER_TEST_NO_WAIT);
    observer.WaitForFinished();
    EXPECT_EQ(1UL, observer.NumDownloadsSeenInState(
                       download::DownloadItem::IN_PROGRESS));
  }

  void PrepareForDialog(content::WebContents* web_contents) {
    content::PrepContentsForBeforeUnloadTest(web_contents);
  }

  void PrepareForDialog(Browser* browser) {
    for (int i = 0; i < browser->tab_strip_model()->count(); i++)
      PrepareForDialog(browser->tab_strip_model()->GetWebContentsAt(i));
  }

  void WaitForAllBrowsersToClose() {
    while (!BrowserList::GetInstance()->empty())
      ui_test_utils::WaitForBrowserToClose();
  }

  std::vector<raw_ptr<Browser, VectorExperimental>> browsers_;
};

IN_PROC_BROWSER_TEST_F(BrowserCloseManagerBrowserTest, TestSingleTabShutdown) {
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL("/beforeunload.html"))));
  PrepareForDialog(browser());

  AllBrowsersClosingCancelledObserver cancel_observer(1);
  chrome::CloseAllBrowsersAndQuit();
  ASSERT_NO_FATAL_FAILURE(CancelClose());
  cancel_observer.Wait();
  EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
  EXPECT_EQ(1, browser()->tab_strip_model()->count());

  chrome::CloseAllBrowsersAndQuit();
  ASSERT_NO_FATAL_FAILURE(AcceptClose());
  ui_test_utils::WaitForBrowserToClose();
  EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
  EXPECT_TRUE(BrowserList::GetInstance()->empty());
}

IN_PROC_BROWSER_TEST_F(BrowserCloseManagerBrowserTest,
                       TestShutdownMoreThanOnce) {
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL("/beforeunload.html"))));
  PrepareForDialog(browser());

  AllBrowsersClosingCancelledObserver cancel_observer(1);
  chrome::CloseAllBrowsersAndQuit();
  chrome::CloseAllBrowsersAndQuit();
  ASSERT_NO_FATAL_FAILURE(CancelClose());
  cancel_observer.Wait();
  EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
  EXPECT_EQ(1, browser()->tab_strip_model()->count());

  chrome::CloseAllBrowsersAndQuit();
  chrome::CloseAllBrowsersAndQuit();
  ASSERT_NO_FATAL_FAILURE(AcceptClose());
  ui_test_utils::WaitForBrowserToClose();
  EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
  EXPECT_TRUE(BrowserList::GetInstance()->empty());
}

IN_PROC_BROWSER_TEST_F(BrowserCloseManagerBrowserTest, PRE_TestSessionRestore) {
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL("/beforeunload.html"))));
  AddBlankTabAndShow(browser());
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), GURL(chrome::kChromeUIAboutURL))));
  PrepareForDialog(browser());

  AllBrowsersClosingCancelledObserver cancel_observer(1);
  chrome::CloseAllBrowsersAndQuit();
  ASSERT_NO_FATAL_FAILURE(CancelClose());
  cancel_observer.Wait();
  EXPECT_FALSE(browser_shutdown::IsTryingToQuit());

  browser()->tab_strip_model()->CloseWebContentsAt(
      1, TabCloseTypes::CLOSE_USER_GESTURE);
  content::TestNavigationObserver navigation_observer(
      browser()->tab_strip_model()->GetActiveWebContents(), 1);
  ASSERT_NO_FATAL_FAILURE(NavigateToURLWithDisposition(
      browser(), GURL(chrome::kChromeUIVersionURL),
      WindowOpenDisposition::CURRENT_TAB, ui_test_utils::BROWSER_TEST_NO_WAIT));
  ASSERT_NO_FATAL_FAILURE(AcceptClose());
  navigation_observer.Wait();

  chrome::CloseAllBrowsersAndQuit();
  ui_test_utils::WaitForBrowserToClose();
  EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
  EXPECT_TRUE(BrowserList::GetInstance()->empty());
}

// Test that the tab closed after the aborted shutdown attempt is not re-opened
// when restoring the session.
// Flaky on chromium.chromeos, chromium.linux, and chromium.mac bots. See
// https://crbug.com/1145235. It was flaky on Windows, but  crrev.com/c/2559156,
// which added retries to ReplaceFile, should fix the Windows flakiness.
#if BUILDFLAG(IS_WIN)
#define MAYBE_TestSessionRestore TestSessionRestore
#else
#define MAYBE_TestSessionRestore DISABLED_TestSessionRestore
#endif
IN_PROC_BROWSER_TEST_F(BrowserCloseManagerBrowserTest,
                       MAYBE_TestSessionRestore) {
  // The testing framework launches Chrome with about:blank as args.
  EXPECT_EQ(2, browser()->tab_strip_model()->count());
  EXPECT_EQ(
      GURL(chrome::kChromeUIVersionURL),
      browser()->tab_strip_model()->GetWebContentsAt(0)->GetLastCommittedURL());
  EXPECT_EQ(
      GURL("about:blank"),
      browser()->tab_strip_model()->GetWebContentsAt(1)->GetLastCommittedURL());
}

// Test that browser windows are only closed if all browsers are ready to close
// and that all beforeunload dialogs are shown again after a cancel.
IN_PROC_BROWSER_TEST_F(BrowserCloseManagerBrowserTest, TestMultipleWindows) {
  browsers_.push_back(CreateBrowser(browser()->profile()));
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browsers_[0], embedded_test_server()->GetURL("/beforeunload.html"))));
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browsers_[1], embedded_test_server()->GetURL("/beforeunload.html"))));
  PrepareForDialog(browsers_[0]);
  PrepareForDialog(browsers_[1]);

  // Cancel shutdown on the first beforeunload event.
  {
    AllBrowsersClosingCancelledObserver cancel_observer(1);
    chrome::CloseAllBrowsersAndQuit();
    ASSERT_NO_FATAL_FAILURE(CancelClose());
    cancel_observer.Wait();
  }
  EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
  EXPECT_EQ(1, browsers_[0]->tab_strip_model()->count());
  EXPECT_EQ(1, browsers_[1]->tab_strip_model()->count());

  // Cancel shutdown on the second beforeunload event.
  {
    AllBrowsersClosingCancelledObserver cancel_observer(2);
    chrome::CloseAllBrowsersAndQuit();
    ASSERT_NO_FATAL_FAILURE(AcceptClose());
    ASSERT_NO_FATAL_FAILURE(CancelClose());
    cancel_observer.Wait();
  }
  EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
  EXPECT_EQ(1, browsers_[0]->tab_strip_model()->count());
  EXPECT_EQ(1, browsers_[1]->tab_strip_model()->count());

  // Allow shutdown for both beforeunload events.
  chrome::CloseAllBrowsersAndQuit();
  ASSERT_NO_FATAL_FAILURE(AcceptClose());
  ASSERT_NO_FATAL_FAILURE(AcceptClose());
  WaitForAllBrowsersToClose();
  EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
  EXPECT_TRUE(BrowserList::GetInstance()->empty());
}

// Test that tabs in the same window with a beforeunload event that hangs are
// treated the same as the user accepting the close, but do not close the tab
// early.
IN_PROC_BROWSER_TEST_F(BrowserCloseManagerBrowserTest,
                       TestHangInBeforeUnloadMultipleTabs) {
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browsers_[0],
      embedded_test_server()->GetURL("/beforeunload_hang.html"))));
  AddBlankTabAndShow(browsers_[0]);
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browsers_[0], embedded_test_server()->GetURL("/beforeunload.html"))));
  AddBlankTabAndShow(browsers_[0]);
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browsers_[0],
      embedded_test_server()->GetURL("/beforeunload_hang.html"))));
  // Disable the hang monitor in the tab that is not expected to hang, so that
  // the dialog is guaranteed to show.
  PrepareForDialog(browsers_[0]->tab_strip_model()->GetWebContentsAt(1));

  AllBrowsersClosingCancelledObserver cancel_observer(1);
  chrome::CloseAllBrowsersAndQuit();
  ASSERT_NO_FATAL_FAILURE(CancelClose());
  cancel_observer.Wait();
  EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
  // All tabs should still be open.
  EXPECT_EQ(3, browsers_[0]->tab_strip_model()->count());

  chrome::CloseAllBrowsersAndQuit();

  ASSERT_NO_FATAL_FAILURE(AcceptClose());
  ui_test_utils::WaitForBrowserToClose();
  EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
  EXPECT_TRUE(BrowserList::GetInstance()->empty());
}

// Test that tabs in different windows with a beforeunload event that hangs are
// treated the same as the user accepting the close, but do not close the tab
// early.
IN_PROC_BROWSER_TEST_F(BrowserCloseManagerBrowserTest,
                       TestHangInBeforeUnloadMultipleWindows) {
  browsers_.push_back(CreateBrowser(browser()->profile()));
  browsers_.push_back(CreateBrowser(browser()->profile()));
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browsers_[0],
      embedded_test_server()->GetURL("/beforeunload_hang.html"))));
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browsers_[1], embedded_test_server()->GetURL("/beforeunload.html"))));
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browsers_[2],
      embedded_test_server()->GetURL("/beforeunload_hang.html"))));
  // Disable the hang monitor in the tab that is not expected to hang, so that
  // the dialog is guaranteed to show.
  PrepareForDialog(browsers_[1]);

  AllBrowsersClosingCancelledObserver cancel_observer(2);
  chrome::CloseAllBrowsersAndQuit();
  ASSERT_NO_FATAL_FAILURE(CancelClose());
  cancel_observer.Wait();
  EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
  // All windows should still be open.
  EXPECT_EQ(1, browsers_[0]->tab_strip_model()->count());
  EXPECT_EQ(1, browsers_[1]->tab_strip_model()->count());
  EXPECT_EQ(1, browsers_[2]->tab_strip_model()->count());

  chrome::CloseAllBrowsersAndQuit();
  ASSERT_NO_FATAL_FAILURE(AcceptClose());

  WaitForAllBrowsersToClose();
}

// Test that tabs that are slow to respond are not closed prematurely.
// Regression for crbug.com/365052 caused some of tabs to be closed even if
// user chose to cancel browser close.
IN_PROC_BROWSER_TEST_F(BrowserCloseManagerBrowserTest,
                       TestUnloadMultipleSlowTabs) {
  const int kTabCount = 5;
  const int kResponsiveTabIndex = 2;
  // Create tab strip with all tabs except one responding after
  // RenderViewHostImpl::kUnloadTimeoutMS.
  // Minimum configuration is two slow tabs and then responsive tab.
  // But we also want to check how slow tabs behave in tail.
  for (int i = 0; i < kTabCount; i++) {
    if (i)
      AddBlankTabAndShow(browsers_[0]);
    ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
        browsers_[0],
        embedded_test_server()->GetURL((i == kResponsiveTabIndex)
                                           ? "/beforeunload.html"
                                           : "/beforeunload_slow.html"))));
  }
  // Disable the hang monitor in the tab that is not expected to hang, so that
  // the dialog is guaranteed to show.
  PrepareForDialog(
      browsers_[0]->tab_strip_model()->GetWebContentsAt(kResponsiveTabIndex));

  AllBrowsersClosingCancelledObserver cancel_observer(1);
  chrome::CloseAllBrowsersAndQuit();
  ASSERT_NO_FATAL_FAILURE(CancelClose());
  cancel_observer.Wait();
  EXPECT_FALSE(browser_shutdown::IsTryingToQuit());

  // All tabs should still be open.
  EXPECT_EQ(kTabCount, browsers_[0]->tab_strip_model()->count());

  // Quit, this time accepting close confirmation dialog.
  chrome::CloseAllBrowsersAndQuit();
  ASSERT_NO_FATAL_FAILURE(AcceptClose());
  ui_test_utils::WaitForBrowserToClose();
  EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
  EXPECT_TRUE(BrowserList::GetInstance()->empty());
}

// Test that tabs in different windows with a slow beforeunload event response
// are treated the same as the user accepting the close, but do not close the
// tab early.
// Regression for crbug.com/365052 caused CHECK in tabstrip.
// Flaky: https://crbug.com/819541
IN_PROC_BROWSER_TEST_F(BrowserCloseManagerBrowserTest,
                       DISABLED_TestBeforeUnloadMultipleSlowWindows) {
  const int kBrowserCount = 5;
  const int kResponsiveBrowserIndex = 2;
  // Create multiple browsers with all tabs except one responding after
  // RenderViewHostImpl::kUnloadTimeoutMS .
  // Minimum configuration is just one browser with slow tab and then
  // browser with responsive tab.
  // But we also want to check how slow tabs behave in tail and make test
  // more robust.
  for (int i = 0; i < kBrowserCount; i++) {
    if (i)
      browsers_.push_back(CreateBrowser(browser()->profile()));
    ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
        browsers_[i],
        embedded_test_server()->GetURL((i == kResponsiveBrowserIndex)
                                           ? "/beforeunload.html"
                                           : "/beforeunload_slow.html"))));
  }
  // Disable the hang monitor in the tab that is not expected to hang, so that
  // the dialog is guaranteed to show.
  PrepareForDialog(browsers_[kResponsiveBrowserIndex]);

  AllBrowsersClosingCancelledObserver cancel_observer(kResponsiveBrowserIndex +
                                                      1);
  chrome::CloseAllBrowsersAndQuit();
  ASSERT_NO_FATAL_FAILURE(CancelClose());
  cancel_observer.Wait();
  EXPECT_FALSE(browser_shutdown::IsTryingToQuit());

  // All windows should still be open.
  for (int i = 0; i < kBrowserCount; i++)
    EXPECT_EQ(1, browsers_[i]->tab_strip_model()->count());

  // Quit, this time accepting close confirmation dialog.
  chrome::CloseAllBrowsersAndQuit();
  ASSERT_NO_FATAL_FAILURE(AcceptClose());
  WaitForAllBrowsersToClose();
  EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
  EXPECT_TRUE(BrowserList::GetInstance()->empty());
}

// Flaky on Windows 7 (dbg) trybot, see https://crbug.com/751081.
#if BUILDFLAG(IS_WIN) && !defined(NDEBUG)
#define MAYBE_TestAddWindowDuringShutdown DISABLED_TestAddWindowDuringShutdown
#else
#define MAYBE_TestAddWindowDuringShutdown TestAddWindowDuringShutdown
#endif

// Test that a window created during shutdown is closed.
IN_PROC_BROWSER_TEST_F(BrowserCloseManagerBrowserTest,
                       MAYBE_TestAddWindowDuringShutdown) {
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browsers_[0], embedded_test_server()->GetURL("/beforeunload.html"))));
  PrepareForDialog(browsers_[0]);

  chrome::CloseAllBrowsersAndQuit();
  browsers_.push_back(CreateBrowser(browser()->profile()));
  ASSERT_NO_FATAL_FAILURE(AcceptClose());
  WaitForAllBrowsersToClose();
  EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
  EXPECT_TRUE(BrowserList::GetInstance()->empty());
}

// Test that a window created during shutdown with a beforeunload handler can
// cancel the shutdown.
IN_PROC_BROWSER_TEST_F(BrowserCloseManagerBrowserTest,
                       TestAddWindowWithBeforeUnloadDuringShutdown) {
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browsers_[0], embedded_test_server()->GetURL("/beforeunload.html"))));
  PrepareForDialog(browsers_[0]);

  AllBrowsersClosingCancelledObserver cancel_observer(2);
  chrome::CloseAllBrowsersAndQuit();
  browsers_.push_back(CreateBrowser(browser()->profile()));
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browsers_[1], embedded_test_server()->GetURL("/beforeunload.html"))));
  PrepareForDialog(browsers_[1]);
  ASSERT_NO_FATAL_FAILURE(AcceptClose());
  ASSERT_NO_FATAL_FAILURE(CancelClose());
  cancel_observer.Wait();
  EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
  EXPECT_EQ(1, browsers_[0]->tab_strip_model()->count());
  EXPECT_EQ(1, browsers_[1]->tab_strip_model()->count());

  // Allow shutdown for both beforeunload dialogs.
  chrome::CloseAllBrowsersAndQuit();
  ASSERT_NO_FATAL_FAILURE(AcceptClose());
  ASSERT_NO_FATAL_FAILURE(AcceptClose());
  WaitForAllBrowsersToClose();
  EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
  EXPECT_TRUE(BrowserList::GetInstance()->empty());
}

// Test that tabs added during shutdown are closed.
IN_PROC_BROWSER_TEST_F(BrowserCloseManagerBrowserTest,
                       TestAddTabDuringShutdown) {
  browsers_.push_back(CreateBrowser(browser()->profile()));
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browsers_[0], embedded_test_server()->GetURL("/beforeunload.html"))));
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browsers_[1], embedded_test_server()->GetURL("/beforeunload.html"))));
  PrepareForDialog(browsers_[0]);
  PrepareForDialog(browsers_[1]);

  chrome::CloseAllBrowsersAndQuit();
  ASSERT_NO_FATAL_FAILURE(AcceptClose());
  AddBlankTabAndShow(browsers_[0]);
  AddBlankTabAndShow(browsers_[1]);
  ASSERT_NO_FATAL_FAILURE(AcceptClose());
  WaitForAllBrowsersToClose();
  EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
  EXPECT_TRUE(BrowserList::GetInstance()->empty());
}

// Test that tabs created during shutdown with beforeunload handlers can cancel
// the shutdown.

IN_PROC_BROWSER_TEST_F(BrowserCloseManagerBrowserTest,
                       TestAddTabWithBeforeUnloadDuringShutdown) {
  browsers_.push_back(CreateBrowser(browser()->profile()));
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browsers_[0], embedded_test_server()->GetURL("/beforeunload.html"))));
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browsers_[1], embedded_test_server()->GetURL("/beforeunload.html"))));
  PrepareForDialog(browsers_[0]);
  PrepareForDialog(browsers_[1]);

  AllBrowsersClosingCancelledObserver cancel_observer(2);
  chrome::CloseAllBrowsersAndQuit();
  ASSERT_NO_FATAL_FAILURE(AcceptClose());
  AddBlankTabAndShow(browsers_[0]);
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browsers_[0], embedded_test_server()->GetURL("/beforeunload.html"))));
  AddBlankTabAndShow(browsers_[1]);
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browsers_[1], embedded_test_server()->GetURL("/beforeunload.html"))));
  PrepareForDialog(browsers_[0]);
  PrepareForDialog(browsers_[1]);
  ASSERT_NO_FATAL_FAILURE(AcceptClose());
  ASSERT_NO_FATAL_FAILURE(CancelClose());
  cancel_observer.Wait();
  EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
  EXPECT_EQ(2, browsers_[0]->tab_strip_model()->count());
  EXPECT_EQ(2, browsers_[1]->tab_strip_model()->count());

  chrome::CloseAllBrowsersAndQuit();
  ASSERT_NO_FATAL_FAILURE(AcceptClose());
  ASSERT_NO_FATAL_FAILURE(AcceptClose());
  ASSERT_NO_FATAL_FAILURE(AcceptClose());
  ASSERT_NO_FATAL_FAILURE(AcceptClose());

  WaitForAllBrowsersToClose();
  EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
  EXPECT_TRUE(BrowserList::GetInstance()->empty());
}

// TODO(crbug.com/41314042):
// BrowserCloseManagerBrowserTest.AddBeforeUnloadDuringClosing flaky on Mac.
#if BUILDFLAG(IS_MAC)
#define MAYBE_AddBeforeUnloadDuringClosing DISABLED_AddBeforeUnloadDuringClosing
#else
#define MAYBE_AddBeforeUnloadDuringClosing AddBeforeUnloadDuringClosing
#endif

IN_PROC_BROWSER_TEST_F(BrowserCloseManagerBrowserTest,
                       MAYBE_AddBeforeUnloadDuringClosing) {
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL("/title1.html"))));

  // Open second window.
  ui_test_utils::NavigateToURLWithDisposition(
      browser(), embedded_test_server()->GetURL("/beforeunload.html"),
      WindowOpenDisposition::NEW_WINDOW,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
  EXPECT_EQ(2u, BrowserList::GetInstance()->size());
  auto* browser2 = BrowserList::GetInstance()->get(0) != browser()
                       ? BrowserList::GetInstance()->get(0)
                       : BrowserList::GetInstance()->get(1);
  EXPECT_TRUE(content::WaitForLoadStop(
      browser2->tab_strip_model()->GetWebContentsAt(0)));

  // Let's work with second window only.
  // This page has beforeunload handler already.
  EXPECT_TRUE(browser2->tab_strip_model()
                  ->GetWebContentsAt(0)
                  ->NeedToFireBeforeUnloadOrUnloadEvents());
  // This page doesn't have beforeunload handler. Yet.
  ui_test_utils::NavigateToURLWithDisposition(
      browser2, embedded_test_server()->GetURL("/title2.html"),
      WindowOpenDisposition::NEW_FOREGROUND_TAB,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
  EXPECT_TRUE(content::WaitForLoadStop(
      browser2->tab_strip_model()->GetWebContentsAt(1)));
  EXPECT_FALSE(browser2->tab_strip_model()
                   ->GetWebContentsAt(1)
                   ->NeedToFireBeforeUnloadOrUnloadEvents());
  EXPECT_EQ(2, browser2->tab_strip_model()->count());

  PrepareForDialog(browser2);

  // The test.

  TabRestoreServiceChangesObserver restore_observer(browser2->profile());
  chrome::CloseWindow(browser2);
  // Just to be sure CloseWindow doesn't have asynchronous tasks
  // that could have an impact.
  content::RunAllPendingInMessageLoop();

  // Closing browser shouldn't happen because of beforeunload handler.
  EXPECT_EQ(2u, BrowserList::GetInstance()->size());
  // Add beforeunload handler for the 2nd (title2.html) tab which haven't had it
  // yet.
  ASSERT_TRUE(
      content::ExecJs(browser2->tab_strip_model()->GetWebContentsAt(1),
                      "window.addEventListener('beforeunload', "
                      "function(event) { event.returnValue = 'Foo'; });"));
  EXPECT_TRUE(browser2->tab_strip_model()
                  ->GetWebContentsAt(1)
                  ->NeedToFireBeforeUnloadOrUnloadEvents());
  // Accept closing the first tab.
  ASSERT_NO_FATAL_FAILURE(AcceptClose());
  // Just to be sure accepting a dialog doesn't have asynchronous tasks
  // that could have an impact.
  content::RunAllPendingInMessageLoop();
  // It shouldn't close the whole window/browser.
  EXPECT_EQ(2u, BrowserList::GetInstance()->size());
  EXPECT_EQ(2, browser2->tab_strip_model()->count());
  // Accept closing the second tab.
  ASSERT_NO_FATAL_FAILURE(AcceptClose());
  ui_test_utils::WaitForBrowserToClose();
  // Now the second window/browser should be closed.
  EXPECT_EQ(1u, BrowserList::GetInstance()->size());
  EXPECT_EQ(browser(), BrowserList::GetInstance()->get(0));
  EXPECT_EQ(1u, restore_observer.changes_count());

  // Restore the closed browser.
  chrome::OpenWindowWithRestoredTabs(browser()->profile());
  EXPECT_EQ(2u, BrowserList::GetInstance()->size());
  browser2 = BrowserList::GetInstance()->get(0) != browser()
                 ? BrowserList::GetInstance()->get(0)
                 : BrowserList::GetInstance()->get(1);

  // Check the restored browser contents.
  EXPECT_EQ(2, browser2->tab_strip_model()->count());
  EXPECT_EQ(
      embedded_test_server()->GetURL("/beforeunload.html"),
      browser2->tab_strip_model()->GetWebContentsAt(0)->GetLastCommittedURL());
  EXPECT_EQ(
      embedded_test_server()->GetURL("/title2.html"),
      browser2->tab_strip_model()->GetWebContentsAt(1)->GetLastCommittedURL());
}

// TODO(crbug.com/40921700): This test is failing on Linux.
#if BUILDFLAG(IS_LINUX)
#define MAYBE_TestCloseTabDuringShutdown DISABLED_TestCloseTabDuringShutdown
#else
#define MAYBE_TestCloseTabDuringShutdown TestCloseTabDuringShutdown
#endif  // BUILDFLAG(IS_LINUX)
IN_PROC_BROWSER_TEST_F(BrowserCloseManagerBrowserTest,
                       MAYBE_TestCloseTabDuringShutdown) {
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browsers_[0], embedded_test_server()->GetURL("/beforeunload.html"))));
  PrepareForDialog(browsers_[0]);

  AllBrowsersClosingCancelledObserver cancel_observer(1);
  chrome::CloseAllBrowsersAndQuit();

  browsers_.push_back(CreateBrowser(browser()->profile()));
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browsers_[1], embedded_test_server()->GetURL("/beforeunload.html"))));
  PrepareForDialog(browsers_[1]);
  browsers_[1]->tab_strip_model()->CloseAllTabs();
  ASSERT_NO_FATAL_FAILURE(CancelClose());
  ASSERT_NO_FATAL_FAILURE(CancelClose());
  cancel_observer.Wait();
  EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
  EXPECT_EQ(1, browsers_[0]->tab_strip_model()->count());
  EXPECT_EQ(1, browsers_[1]->tab_strip_model()->count());

  chrome::CloseAllBrowsersAndQuit();
  browsers_[1]->tab_strip_model()->CloseAllTabs();
  ASSERT_NO_FATAL_FAILURE(AcceptClose());
  ASSERT_NO_FATAL_FAILURE(AcceptClose());

  WaitForAllBrowsersToClose();
  EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
  EXPECT_TRUE(BrowserList::GetInstance()->empty());
}

IN_PROC_BROWSER_TEST_F(BrowserCloseManagerBrowserTest,
                       TestOpenAndCloseWindowDuringShutdown) {
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browsers_[0], embedded_test_server()->GetURL("/beforeunload.html"))));
  PrepareForDialog(browsers_[0]);

  AllBrowsersClosingCancelledObserver cancel_observer(2);
  chrome::CloseAllBrowsersAndQuit();

  browsers_.push_back(CreateBrowser(browser()->profile()));
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browsers_[1], embedded_test_server()->GetURL("/beforeunload.html"))));
  PrepareForDialog(browsers_[1]);
  ASSERT_GE(browsers_.size(), 2u);
  EXPECT_NE(BrowserClosingStatus::kPermitted,
            browsers_[1]->HandleBeforeClose());
  ASSERT_NO_FATAL_FAILURE(CancelClose());
  ASSERT_NO_FATAL_FAILURE(CancelClose());
  cancel_observer.Wait();
  EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
  EXPECT_EQ(1, browsers_[0]->tab_strip_model()->count());
  EXPECT_EQ(1, browsers_[1]->tab_strip_model()->count());

  chrome::CloseAllBrowsersAndQuit();
  ASSERT_GE(browsers_.size(), 2u);
  EXPECT_NE(BrowserClosingStatus::kPermitted,
            browsers_[1]->HandleBeforeClose());
  ASSERT_NO_FATAL_FAILURE(AcceptClose());
  ASSERT_NO_FATAL_FAILURE(AcceptClose());

  WaitForAllBrowsersToClose();
  EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
  EXPECT_TRUE(BrowserList::GetInstance()->empty());
}

IN_PROC_BROWSER_TEST_F(BrowserCloseManagerBrowserTest,
                       TestCloseWindowDuringShutdown) {
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browsers_[0], embedded_test_server()->GetURL("/beforeunload.html"))));
  browsers_.push_back(CreateBrowser(browser()->profile()));
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browsers_[1], embedded_test_server()->GetURL("/beforeunload.html"))));
  PrepareForDialog(browsers_[0]);
  PrepareForDialog(browsers_[1]);

  AllBrowsersClosingCancelledObserver cancel_observer(1);
  chrome::CloseAllBrowsersAndQuit();

  ASSERT_FALSE(browsers_.empty());
  EXPECT_NE(BrowserClosingStatus::kPermitted,
            browsers_[0]->HandleBeforeClose());
  ASSERT_NO_FATAL_FAILURE(CancelClose());
  cancel_observer.Wait();
  EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
  EXPECT_EQ(1, browsers_[0]->tab_strip_model()->count());
  EXPECT_EQ(1, browsers_[1]->tab_strip_model()->count());

  chrome::CloseAllBrowsersAndQuit();
  ASSERT_FALSE(browsers_.empty());
  EXPECT_NE(BrowserClosingStatus::kPermitted,
            browsers_[0]->HandleBeforeClose());
  ASSERT_NO_FATAL_FAILURE(AcceptClose());
  ASSERT_NO_FATAL_FAILURE(AcceptClose());

  WaitForAllBrowsersToClose();
  EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
  EXPECT_TRUE(BrowserList::GetInstance()->empty());
}

// Mac has its own in-progress download prompt in app_controller_mac.mm, so
// BrowserCloseManager should simply close all browsers. If there are no
// browsers, it should not crash.
#if BUILDFLAG(IS_MAC)
IN_PROC_BROWSER_TEST_F(BrowserCloseManagerBrowserTest, TestWithDownloads) {
  ASSERT_NO_FATAL_FAILURE(CreateStalledDownload(browser()));

  TestBrowserCloseManager::AttemptClose(
      TestBrowserCloseManager::NO_USER_CHOICE);
  WaitForAllBrowsersToClose();
  EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
  EXPECT_TRUE(BrowserList::GetInstance()->empty());
  EXPECT_EQ(1, DownloadCoreService::BlockingShutdownCountAllProfiles());

  // Attempting to close again should not crash.
  TestBrowserCloseManager::AttemptClose(
      TestBrowserCloseManager::NO_USER_CHOICE);
}
#else  // BUILDFLAG(IS_MAC)

// Test shutdown with a DANGEROUS_URL download undecided.
IN_PROC_BROWSER_TEST_F(BrowserCloseManagerBrowserTest,
                       TestWithDangerousUrlDownload) {
  // Set up the fake delegate that forces the download to be malicious.
  std::unique_ptr<TestDownloadManagerDelegate> test_delegate(
      new TestDownloadManagerDelegate(browser()->profile()));
  DownloadCoreServiceFactory::GetForBrowserContext(browser()->profile())
      ->SetDownloadManagerDelegateForTesting(std::move(test_delegate));

  // Run a dangerous download, but the user doesn't make a decision.
  // This .swf normally would be categorized as DANGEROUS_FILE, but
  // TestDownloadManagerDelegate turns it into DANGEROUS_URL.
  GURL download_url(
      embedded_test_server()->GetURL("/downloads/dangerous/dangerous.swf"));
  content::DownloadTestObserverInterrupted observer(
      browser()->profile()->GetDownloadManager(), 1,
      content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_QUIT);
  ui_test_utils::NavigateToURLWithDisposition(
      browser(), GURL(download_url), WindowOpenDisposition::NEW_BACKGROUND_TAB,
      ui_test_utils::BROWSER_TEST_NO_WAIT);
  observer.WaitForFinished();

  // Check that the download manager has the expected state.
  EXPECT_EQ(1, browser()->profile()->GetDownloadManager()->InProgressCount());
  EXPECT_EQ(
      0, browser()->profile()->GetDownloadManager()->BlockingShutdownCount());

  // Close the browser with no user action.
  TestBrowserCloseManager::AttemptClose(
      TestBrowserCloseManager::NO_USER_CHOICE);
  WaitForAllBrowsersToClose();
  EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
  EXPECT_TRUE(BrowserList::GetInstance()->empty());
}

// Test shutdown with a download in progress.
IN_PROC_BROWSER_TEST_F(BrowserCloseManagerBrowserTest, TestWithDownloads) {
  ASSERT_NO_FATAL_FAILURE(CreateStalledDownload(browser()));
  content::TestNavigationObserver navigation_observer(
      browser()->tab_strip_model()->GetActiveWebContents(), 1);
  TestBrowserCloseManager::AttemptClose(
      TestBrowserCloseManager::USER_CHOICE_USER_CANCELS_CLOSE);
  EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
  navigation_observer.Wait();
  EXPECT_EQ(GURL(chrome::kChromeUIDownloadsURL), browser()
                                                     ->tab_strip_model()
                                                     ->GetActiveWebContents()
                                                     ->GetLastCommittedURL());

  TestBrowserCloseManager::AttemptClose(
      TestBrowserCloseManager::USER_CHOICE_USER_ALLOWS_CLOSE);
  WaitForAllBrowsersToClose();
  EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
  EXPECT_TRUE(BrowserList::GetInstance()->empty());
  if (browser_defaults::kBrowserAliveWithNoWindows)
    EXPECT_EQ(1, DownloadCoreService::BlockingShutdownCountAllProfiles());
  else
    EXPECT_EQ(0, DownloadCoreService::BlockingShutdownCountAllProfiles());
}

// Test shutdown with a download in progress in an off-the-record profile.
IN_PROC_BROWSER_TEST_F(BrowserCloseManagerBrowserTest,
                       TestWithOffTheRecordDownloads) {
  Profile* otr_profile =
      browser()->profile()->GetPrimaryOTRProfile(/*create_if_needed=*/true);
  Browser* otr_browser = CreateBrowser(otr_profile);
  {
    browser()->window()->Close();
    ui_test_utils::WaitForBrowserToClose();
  }
  ASSERT_NO_FATAL_FAILURE(CreateStalledDownload(otr_browser));
  content::TestNavigationObserver navigation_observer(
      otr_browser->tab_strip_model()->GetActiveWebContents(), 1);
  TestBrowserCloseManager::AttemptClose(
      TestBrowserCloseManager::USER_CHOICE_USER_CANCELS_CLOSE);
  EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
  navigation_observer.Wait();
  EXPECT_EQ(GURL(chrome::kChromeUIDownloadsURL), otr_browser->tab_strip_model()
                                                     ->GetActiveWebContents()
                                                     ->GetLastCommittedURL());

  TestBrowserCloseManager::AttemptClose(
      TestBrowserCloseManager::USER_CHOICE_USER_ALLOWS_CLOSE);
  ui_test_utils::WaitForBrowserToClose();
  EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
  EXPECT_TRUE(BrowserList::GetInstance()->empty());
  EXPECT_EQ(0, DownloadCoreService::BlockingShutdownCountAllProfiles());
}

// Test shutdown with a download in progress in a regular profile an inconito
// browser is opened and closed. While there are active downloads, closing the
// incognito window shouldn't block on the active downloads which belong to the
// parent profile.
// TODO(crbug.com/40576829): Fix the notification expectation around the
// call to AttemptClose.
IN_PROC_BROWSER_TEST_F(BrowserCloseManagerBrowserTest,
                       DISABLED_TestWithOffTheRecordWindowAndRegularDownload) {
  Profile* otr_profile =
      browser()->profile()->GetPrimaryOTRProfile(/*create_if_needed=*/true);
  Browser* otr_browser = CreateBrowser(otr_profile);
  ASSERT_NO_FATAL_FAILURE(CreateStalledDownload(browser()));

  content::TestNavigationObserver navigation_observer(
      otr_browser->tab_strip_model()->GetActiveWebContents(), 1);
  ASSERT_TRUE(ui_test_utils::NavigateToURL(otr_browser, GURL("about:blank")));
  navigation_observer.Wait();

  int num_downloads_blocking = 0;
  ASSERT_EQ(
      Browser::DownloadCloseType::kOk,
      otr_browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
  ASSERT_EQ(0, num_downloads_blocking);

  {
    otr_browser->window()->Close();
    ui_test_utils::WaitForBrowserToClose();
  }

  ASSERT_EQ(
      Browser::DownloadCloseType::kBrowserShutdown,
      browser()->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
  ASSERT_EQ(1, num_downloads_blocking);

  {
    TestBrowserCloseManager::AttemptClose(
        TestBrowserCloseManager::USER_CHOICE_USER_ALLOWS_CLOSE);
    ui_test_utils::WaitForBrowserToClose();
  }

  EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
  EXPECT_TRUE(BrowserList::GetInstance()->empty());
  if (browser_defaults::kBrowserAliveWithNoWindows)
    EXPECT_EQ(1, DownloadCoreService::BlockingShutdownCountAllProfiles());
  else
    EXPECT_EQ(0, DownloadCoreService::BlockingShutdownCountAllProfiles());
}

// Test shutdown with a download in progress from one profile, where the only
// open windows are for another profile.
IN_PROC_BROWSER_TEST_F(BrowserCloseManagerBrowserTest,
                       TestWithDownloadsFromDifferentProfiles) {
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  std::unique_ptr<Profile> other_profile;
  {
    base::FilePath path =
        profile_manager->user_data_dir().AppendASCII("test_profile");
    base::ScopedAllowBlockingForTesting allow_blocking;
    if (!base::PathExists(path))
      ASSERT_TRUE(base::CreateDirectory(path));
    other_profile = Profile::CreateProfile(path, nullptr,
                                           Profile::CreateMode::kSynchronous);
  }
  Profile* other_profile_ptr = other_profile.get();
  profile_manager->RegisterTestingProfile(std::move(other_profile), true);
  Browser* other_profile_browser = CreateBrowser(other_profile_ptr);
  ui_test_utils::WaitUntilBrowserBecomeActive(other_profile_browser);

  ASSERT_NO_FATAL_FAILURE(CreateStalledDownload(browser()));
  {
    browser()->window()->Close();
    ui_test_utils::WaitForBrowserToClose();
  }

  // When the shutdown is cancelled, the downloads page should be opened in a
  // browser for that profile. Because there are no browsers for that profile, a
  // new browser should be opened.
  ui_test_utils::BrowserChangeObserver new_browser_observer(
      nullptr, ui_test_utils::BrowserChangeObserver::ChangeType::kAdded);
  TestBrowserCloseManager::AttemptClose(
      TestBrowserCloseManager::USER_CHOICE_USER_CANCELS_CLOSE);
  Browser* opened_browser = new_browser_observer.Wait();
  ASSERT_TRUE(opened_browser);
  ui_test_utils::WaitUntilBrowserBecomeActive(opened_browser);
  EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
  EXPECT_NE(other_profile_ptr, opened_browser->profile());
  EXPECT_EQ(GURL(chrome::kChromeUIDownloadsURL),
            opened_browser->tab_strip_model()
                ->GetActiveWebContents()
                ->GetVisibleURL());
  EXPECT_EQ(GURL("about:blank"), other_profile_browser->tab_strip_model()
                                     ->GetActiveWebContents()
                                     ->GetVisibleURL());

  TestBrowserCloseManager::AttemptClose(
      TestBrowserCloseManager::USER_CHOICE_USER_ALLOWS_CLOSE);
  ui_test_utils::WaitForBrowserToClose();
  ui_test_utils::WaitForBrowserToClose();
  EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
  EXPECT_TRUE(BrowserList::GetInstance()->empty());
  if (browser_defaults::kBrowserAliveWithNoWindows)
    EXPECT_EQ(1, DownloadCoreService::BlockingShutdownCountAllProfiles());
  else
    EXPECT_EQ(0, DownloadCoreService::BlockingShutdownCountAllProfiles());
}

// Fails on ChromeOS and Linux, times out on Win. crbug.com/749098
// Test shutdown with downloads in progress and beforeunload handlers.
IN_PROC_BROWSER_TEST_F(BrowserCloseManagerBrowserTest,
                       DISABLED_TestBeforeUnloadAndDownloads) {
  ASSERT_NO_FATAL_FAILURE(CreateStalledDownload(browser()));
  ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL("/beforeunload.html"))));
  PrepareForDialog(browser());

  AllBrowsersClosingCancelledObserver cancel_observer(1);
  TestBrowserCloseManager::AttemptClose(
      TestBrowserCloseManager::USER_CHOICE_USER_CANCELS_CLOSE);
  ASSERT_NO_FATAL_FAILURE(AcceptClose());
  cancel_observer.Wait();
  EXPECT_FALSE(browser_shutdown::IsTryingToQuit());

  TestBrowserCloseManager::AttemptClose(
      TestBrowserCloseManager::USER_CHOICE_USER_ALLOWS_CLOSE);
  ASSERT_NO_FATAL_FAILURE(AcceptClose());
  ui_test_utils::WaitForBrowserToClose();
  EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
  EXPECT_TRUE(BrowserList::GetInstance()->empty());
}

#endif  // BUILDFLAG(IS_MAC)

#if BUILDFLAG(ENABLE_BACKGROUND_MODE)

class BrowserCloseManagerWithBackgroundModeBrowserTest
    : public BrowserCloseManagerBrowserTest {
 public:
  BrowserCloseManagerWithBackgroundModeBrowserTest() {}

  BrowserCloseManagerWithBackgroundModeBrowserTest(
      const BrowserCloseManagerWithBackgroundModeBrowserTest&) = delete;
  BrowserCloseManagerWithBackgroundModeBrowserTest& operator=(
      const BrowserCloseManagerWithBackgroundModeBrowserTest&) = delete;

  void SetUpOnMainThread() override {
    BrowserCloseManagerBrowserTest::SetUpOnMainThread();
    g_browser_process->set_background_mode_manager_for_test(
        std::unique_ptr<BackgroundModeManager>(new FakeBackgroundModeManager));
  }

  bool IsBackgroundModeSuspended() {
    return static_cast<FakeBackgroundModeManager*>(
        g_browser_process->background_mode_manager())
        ->IsBackgroundModeSuspended();
  }
};

// Check that background mode is suspended when closing all browsers unless we
// are quitting and that background mode is resumed when a new browser window is
// opened.
IN_PROC_BROWSER_TEST_F(BrowserCloseManagerWithBackgroundModeBrowserTest,
                       CloseAllBrowsersWithBackgroundMode) {
  EXPECT_FALSE(IsBackgroundModeSuspended());
  std::unique_ptr<ScopedKeepAlive> tmp_keep_alive;
  std::unique_ptr<ScopedProfileKeepAlive> tmp_profile_keep_alive;
  Profile* profile = browser()->profile();
  {
    tmp_keep_alive = std::make_unique<ScopedKeepAlive>(
        KeepAliveOrigin::PANEL_VIEW, KeepAliveRestartOption::DISABLED);
    tmp_profile_keep_alive = std::make_unique<ScopedProfileKeepAlive>(
        profile, ProfileKeepAliveOrigin::kBrowserWindow);
    chrome::CloseAllBrowsers();
    ui_test_utils::WaitForBrowserToClose();
  }
  EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
  EXPECT_TRUE(BrowserList::GetInstance()->empty());
  EXPECT_TRUE(IsBackgroundModeSuspended());

  // Background mode should be resumed when a new browser window is opened.
  chrome::NewEmptyWindow(profile);
  ui_test_utils::WaitForBrowserToOpen();
  tmp_keep_alive.reset();
  tmp_profile_keep_alive.reset();
  EXPECT_FALSE(IsBackgroundModeSuspended());

  // Background mode should not be suspended when quitting.
  chrome::CloseAllBrowsersAndQuit();
  ui_test_utils::WaitForBrowserToClose();
  EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
  EXPECT_TRUE(BrowserList::GetInstance()->empty());
  EXPECT_FALSE(IsBackgroundModeSuspended());
}

// Check that closing the last browser window individually does not affect
// background mode.
IN_PROC_BROWSER_TEST_F(BrowserCloseManagerWithBackgroundModeBrowserTest,
                       DISABLED_CloseSingleBrowserWithBackgroundMode) {
  EXPECT_FALSE(IsBackgroundModeSuspended());
  browser()->window()->Close();
  ui_test_utils::WaitForBrowserToClose();
  EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
  EXPECT_TRUE(BrowserList::GetInstance()->empty());
  EXPECT_FALSE(IsBackgroundModeSuspended());
}

// Check that closing all browsers with no browser windows open suspends
// background mode but does not cause Chrome to quit.
IN_PROC_BROWSER_TEST_F(
    BrowserCloseManagerWithBackgroundModeBrowserTest,
    DISABLED_CloseAllBrowsersWithNoOpenBrowsersWithBackgroundMode) {
  EXPECT_FALSE(IsBackgroundModeSuspended());
  ScopedKeepAlive tmp_keep_alive(KeepAliveOrigin::PANEL_VIEW,
                                 KeepAliveRestartOption::DISABLED);
  ScopedProfileKeepAlive tmp_profile_keep_alive(
      browser()->profile(), ProfileKeepAliveOrigin::kBrowserWindow);
  browser()->window()->Close();
  ui_test_utils::WaitForBrowserToClose();
  EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
  EXPECT_TRUE(BrowserList::GetInstance()->empty());
  EXPECT_FALSE(IsBackgroundModeSuspended());

  chrome::CloseAllBrowsers();
  EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
  EXPECT_TRUE(BrowserList::GetInstance()->empty());
  EXPECT_TRUE(IsBackgroundModeSuspended());
}

#endif  // BUILDFLAG(ENABLE_BACKGROUND_MODE)
