Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1579)

Unified Diff: chrome/browser/ui/browser_close_browsertest.cc

Issue 7466033: Fix warning prompting on closing a window that will cancel downloads. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Removed unneeded friend decls and tweaked a comment. Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/browser_close_browsertest.cc
diff --git a/chrome/browser/ui/browser_close_browsertest.cc b/chrome/browser/ui/browser_close_browsertest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b61682c4303b2053b327feb8dfe23a1a754195e4
--- /dev/null
+++ b/chrome/browser/ui/browser_close_browsertest.cc
@@ -0,0 +1,338 @@
+// Copyright (c) 2011 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 "base/logging.h"
+#include "base/stringprintf.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/download/download_item.h"
+#include "chrome/browser/download/download_test_observer.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/test/in_process_browser_test.h"
+#include "chrome/test/ui_test_utils.h"
+#include "content/browser/net/url_request_slow_download_job.h"
+#include "content/browser/tab_contents/tab_contents.h"
+#include "content/common/page_transition_types.h"
+#include "content/common/url_constants.h"
+
+class BrowserCloseTest : public InProcessBrowserTest {
+ protected:
+ Profile* CreateNewProfile() {
sky 2011/07/21 20:08:11 Why is this here?
Randy Smith (Not in Mondays) 2011/07/21 21:36:31 See my answer to the question about the disabled t
+ NOTREACHED();
+ return NULL;
+ }
+
+ void CreateStalledDownload(Browser* browser, int num_downloads) {
sky 2011/07/21 20:08:11 Please add descriptions for the methods that aren'
Randy Smith (Not in Mondays) 2011/07/21 21:36:31 Done.
+ GURL url(URLRequestSlowDownloadJob::kKnownSizeUrl);
+
+ if (num_downloads == 0)
+ return;
+
+ // Setup an observer waiting for the given number of downloads
+ // to get to IN_PROGRESS.
+ DownloadManager* download_manager =
+ browser->profile()->GetDownloadManager();
+ scoped_ptr<DownloadTestObserver> observer(
+ new DownloadTestObserver(
+ download_manager, num_downloads,
+ DownloadItem::IN_PROGRESS,
+ true, // Bail on select file
+ DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL));
+
+ // Set of that number of downloads.
+ while (num_downloads--)
+ ui_test_utils::NavigateToURLWithDisposition(
+ browser, url, NEW_BACKGROUND_TAB,
+ ui_test_utils::BROWSER_TEST_NONE);
+
+ // Wait for them.
+ observer->WaitForFinished();
+ }
+
+ void CompleteAllDownloads() {
+ GURL finish_url(URLRequestSlowDownloadJob::kFinishDownloadUrl);
+ ui_test_utils::NavigateToURL(browser(), finish_url);
+
+ // Go through and, for every single profile, wait until there are
+ // no active downloads on that download manager.
+ std::vector<Profile*> profiles(
+ g_browser_process->profile_manager()->GetLoadedProfiles());
+ for (std::vector<Profile*>::const_iterator pit = profiles.begin();
+ pit != profiles.end(); ++pit) {
+ if ((*pit)->HasCreatedDownloadManager()) {
+ DownloadManager *mgr = (*pit)->GetDownloadManager();
+ scoped_refptr<DownloadTestFlushObserver> observer(
+ new DownloadTestFlushObserver(mgr));
+ observer->WaitForFlush();
+ }
+ }
+ }
+
+ Browser* CreateBrowserOnProfile(Profile* profile) {
+ Browser* new_browser = Browser::Create(profile);
+ new_browser->AddSelectedTabWithURL(GURL(chrome::kAboutBlankURL),
+ PageTransition::START_PAGE);
+ ui_test_utils::WaitForNavigation(
+ &new_browser->GetSelectedTabContents()->controller());
+ new_browser->window()->Show();
+ return new_browser;
+ }
+
+ // Assumes a single browser on the profile passed in in *base_browser.
+ bool AdjustBrowsersOnProfile(Browser** base_browser, int num_windows) {
+ Browser::DownloadClosePreventionType type;
+ int num_downloads_blocking;
+ if (num_windows == 0) {
+ if (!(*base_browser)->OkToCloseWithInProgressDownloads(
+ &type, &num_downloads_blocking))
+ return false;
+ (*base_browser)->window()->Close();
+ *base_browser = 0;
+ return true;
+ }
+
+ // num_windows > 0
+ Profile* profile((*base_browser)->profile());
+ for (int w = 1; w < num_windows; w++) {
+ CreateBrowserOnProfile(profile);
+ }
+ return true;
+ }
+
+};
+
+struct DownloadsCloseCheckCase {
+ std::string DebugString() const;
+
+ // Input
+ struct {
+ struct {
+ int windows;
+ int downloads;
+ } regular;
+ struct {
+ int windows;
+ int downloads;
+ } incognito;
+ } profile_a;
+
+ struct {
+ struct {
+ int windows;
+ int downloads;
+ } regular;
+ struct {
+ int windows;
+ int downloads;
+ } incognito;
+ } profile_b;
+
+ // We always probe a window in profile A.
+ enum { REGULAR = 0, INCOGNITO = 1 } window_to_probe;
sky 2011/07/21 20:08:11 enums should be first.
Randy Smith (Not in Mondays) 2011/07/21 21:36:31 This line declares a member variable window_to_pro
sky 2011/07/22 03:00:40 Fair enough. Leave it.
Randy Smith (Not in Mondays) 2011/07/22 20:41:30 Done.
+
+ // Output
+ bool warn; // Controlling; if we don't warn, the rest aren't checked.
+
+ Browser::DownloadClosePreventionType type;
+ int num_blocking;
+};
+
+std::string DownloadsCloseCheckCase::DebugString() const {
+ std::string result;
+ result += "Case: {";
+ if (profile_a.regular.windows || profile_a.regular.downloads)
+ result += base::StringPrintf("Regular profile A: (%d w, %d d), ",
+ profile_a.regular.windows,
+ profile_a.regular.downloads);
+ if (profile_a.incognito.windows || profile_a.incognito.downloads)
+ result += base::StringPrintf("Incognito profile A: (%d w, %d d), ",
+ profile_a.incognito.windows,
+ profile_a.incognito.downloads);
+ if (profile_b.regular.windows || profile_b.regular.downloads)
+ result += base::StringPrintf("Regular profile B: (%d w, %d d), ",
+ profile_b.regular.windows,
+ profile_b.regular.downloads);
+ if (profile_b.incognito.windows || profile_b.incognito.downloads)
+ result += base::StringPrintf("Incognito profile B: (%d w, %d d), ",
+ profile_b.incognito.windows,
+ profile_b.incognito.downloads);
+ result += (window_to_probe == REGULAR ? "Probe regular" :
+ window_to_probe == INCOGNITO ? "Probe incognito" :
+ "Probe unknown");
+ result += "} -> ";
+ if (!warn) {
+ result += "No warning";
+ } else {
+ result += base::StringPrintf(
+ "%s (%d downloads) warning",
+ (type == Browser::BROWSER_SHUTDOWN ? "Browser shutdown" :
+ type == Browser::LAST_WINDOW_IN_INCOGNITO_PROFILE ? "Incognito close" :
+ "Unknown"), num_blocking);
+ }
+ return result;
+}
+
+static const DownloadsCloseCheckCase download_close_check_cases[] = {
+ // Top level nesting is {profile_a, profile_b}
+ // Second level nesting is {regular, incognito
+ // Third level (inner) nesting is {windows, downloads}
+
+ // Last window (incognito) triggers browser close warning.
+ {{{0, 0}, {1, 1}}, {{0, 0}, {0, 0}}, DownloadsCloseCheckCase::INCOGNITO,
+ true, Browser::BROWSER_SHUTDOWN, 1},
+
+ // Last incognito window triggers incognito close warning.
+ {{{1, 0}, {1, 1}}, {{0, 0}, {0, 0}}, DownloadsCloseCheckCase::INCOGNITO,
+ true, Browser::LAST_WINDOW_IN_INCOGNITO_PROFILE, 1},
+
+ // Last incognito window with no downloads triggers no warning.
+ {{{0, 0}, {1, 0}}, {{0, 0}, {0, 0}}, DownloadsCloseCheckCase::INCOGNITO,
+ 1},
+
+ // Last incognito window with window+download on another incognito profile
+ // triggers no warning.
+ {{{0, 0}, {1, 0}}, {{0, 0}, {1, 1}}, DownloadsCloseCheckCase::INCOGNITO,
+ 1},
+
+ // Non-last incognito window triggers no warning.
+ {{{0, 0}, {2, 1}}, {{0, 0}, {0, 0}}, DownloadsCloseCheckCase::INCOGNITO,
+ 1},
+
+ // Non-last regular window triggers no warning.
+ {{{2, 1}, {0, 0}}, {{0, 0}, {0, 0}}, DownloadsCloseCheckCase::REGULAR,
+ 1},
+
+ // Last regular window triggers browser close.
+ {{{1, 1}, {0, 0}}, {{0, 0}, {0, 0}}, DownloadsCloseCheckCase::REGULAR,
+ true, Browser::BROWSER_SHUTDOWN, 1},
+
+ // Last regular window triggers browser close for download on different
+ // profile.
+ {{{1, 0}, {0, 0}}, {{0, 1}, {0, 0}}, DownloadsCloseCheckCase::REGULAR,
+ true, Browser::BROWSER_SHUTDOWN, 1},
+
+ // Last regular window triggers no warning if incognito
+ // active (http://crbug.com/61257).
+ {{{1, 0}, {1, 1}}, {{0, 0}, {0, 0}}, DownloadsCloseCheckCase::REGULAR,
+ 1},
+
+ // Last regular window triggers no warning if other profile window active.
+ {{{1, 1}, {0, 0}}, {{1, 0}, {0, 0}}, DownloadsCloseCheckCase::REGULAR,
+ 1},
+
+ // Last regular window triggers no warning if other incognito window
+ // active.
+ {{{1, 0}, {0, 0}}, {{0, 0}, {1, 1}}, DownloadsCloseCheckCase::REGULAR,
+ 1},
+
+ // Last regular window triggers no warning if incognito active.
+ {{{1, 1}, {1, 0}}, {{0, 0}, {0, 0}}, DownloadsCloseCheckCase::REGULAR,
+ 1},
+
+ // Test plural for regular.
+ {{{1, 2}, {0, 0}}, {{0, 0}, {0, 0}}, DownloadsCloseCheckCase::REGULAR,
+ true, Browser::BROWSER_SHUTDOWN, 2},
+
+ // Test plural for incognito.
+ {{{1, 0}, {1, 2}}, {{0, 0}, {0, 0}}, DownloadsCloseCheckCase::INCOGNITO,
+ true, Browser::LAST_WINDOW_IN_INCOGNITO_PROFILE, 2},
+};
+
+IN_PROC_BROWSER_TEST_F(BrowserCloseTest, DISABLED_DownloadsCloseCheck) {
sky 2011/07/21 20:08:11 How come you're checking in a test that's disabled
Randy Smith (Not in Mondays) 2011/07/21 21:36:31 So if you'd like me to make that a separate CL, I'
sky 2011/07/22 03:00:40 My vote goes for separate cl with test in it.
Randy Smith (Not in Mondays) 2011/07/22 20:41:30 The postponement of multi-profile has made committ
+ Profile* profile_a = browser()->profile();
+ Profile* profile_b = CreateNewProfile();
+
+ for (size_t i = 0; i < arraysize(download_close_check_cases); ++i) {
+ const DownloadsCloseCheckCase& check_case(download_close_check_cases[i]);
+
+ // Loop invariant; so that we don't actually try and close the browser,
+ // we always enter the loop with a single browser window open on the
+ // main profile. That means we need to exit the loop the same way.
+ // So we setup everything except for the profile_a regular, and then
+ // flip the bit on the main window.
+ // Note that this means that browser() is unreliable in the context
+ // of this function; we'll be killing that main window and recreating
+ // it fairly frequently.
+
+ ASSERT_EQ(1u, BrowserList::size());
+ Browser* entry_browser = *BrowserList::begin();
+ ASSERT_EQ(profile_a, entry_browser->profile());
+ int total_downloads = 0;
+ int profile_downloads = 0;
+ entry_browser->CheckDownloadsInProgress(
+ &total_downloads, &profile_downloads);
+ ASSERT_EQ(0, total_downloads);
+
+ Profile* profile_a_incognito = profile_a->GetOffTheRecordProfile();
+ Profile* profile_b_incognito = profile_b->GetOffTheRecordProfile();
+
+ // For simplicty of coding, we create a window on each profile so that
+ // we can easily create downloads, then we destroy or create windows
+ // as necessary.
+ Browser* browser_a_regular(CreateBrowserOnProfile(profile_a));
+ Browser* browser_a_incognito(CreateBrowserOnProfile(profile_a_incognito));
+ Browser* browser_b_regular(CreateBrowserOnProfile(profile_b));
+ Browser* browser_b_incognito(CreateBrowserOnProfile(profile_b_incognito));
+
+ // Kill our entry browser.
+ entry_browser->window()->Close();
+ entry_browser = NULL;
+
+ // Create all downloads needed.
+ CreateStalledDownload(
+ browser_a_regular, check_case.profile_a.regular.downloads);
+ CreateStalledDownload(
+ browser_a_incognito, check_case.profile_a.incognito.downloads);
+ CreateStalledDownload(
+ browser_b_regular, check_case.profile_b.regular.downloads);
+ CreateStalledDownload(
+ browser_b_incognito, check_case.profile_b.incognito.downloads);
+
+ // Adjust the windows
+ ASSERT_TRUE(AdjustBrowsersOnProfile(
+ &browser_a_regular, check_case.profile_a.regular.windows));
+ ASSERT_TRUE(AdjustBrowsersOnProfile(
+ &browser_a_incognito, check_case.profile_a.incognito.windows));
+ ASSERT_TRUE(AdjustBrowsersOnProfile(
+ &browser_b_regular, check_case.profile_b.regular.windows));
+ ASSERT_TRUE(AdjustBrowsersOnProfile(
+ &browser_b_incognito, check_case.profile_b.incognito.windows));
+
+ // All that work, for this one little test.
+ ASSERT_TRUE((check_case.window_to_probe ==
+ DownloadsCloseCheckCase::REGULAR) ||
+ (check_case.window_to_probe ==
+ DownloadsCloseCheckCase::INCOGNITO));
+
+ Browser::DownloadClosePreventionType type;
+ int num_downloads_blocking;
+ bool result =
+ (check_case.window_to_probe == DownloadsCloseCheckCase::REGULAR ?
+ browser_a_regular :
+ browser_a_incognito)->OkToCloseWithInProgressDownloads(
+ &type, &num_downloads_blocking);
+ EXPECT_EQ(check_case.warn, result) << check_case.DebugString();
+ if (!result) {
+ EXPECT_EQ(check_case.type, type) << check_case.DebugString();
+ EXPECT_EQ(check_case.num_blocking, num_downloads_blocking)
+ << check_case.DebugString();
+ }
+
+ // Release and all the downloads
+ CompleteAllDownloads();
+
+ // Create a new main window and kill everything else.
+ entry_browser = CreateBrowserOnProfile(profile_a);
+ if (browser_a_regular)
+ browser_a_regular->window()->Close();
+ if (browser_a_incognito)
+ browser_a_incognito->window()->Close();
+ if (browser_b_regular)
+ browser_b_regular->window()->Close();
+ if (browser_b_incognito)
+ browser_b_incognito->window()->Close();
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698