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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/logging.h"
6 #include "base/stringprintf.h"
7 #include "chrome/browser/browser_process.h"
8 #include "chrome/browser/download/download_item.h"
9 #include "chrome/browser/download/download_test_observer.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/profiles/profile_manager.h"
12 #include "chrome/browser/ui/browser.h"
13 #include "chrome/browser/ui/browser_window.h"
14 #include "chrome/test/in_process_browser_test.h"
15 #include "chrome/test/ui_test_utils.h"
16 #include "content/browser/net/url_request_slow_download_job.h"
17 #include "content/browser/tab_contents/tab_contents.h"
18 #include "content/common/page_transition_types.h"
19 #include "content/common/url_constants.h"
20
21 class BrowserCloseTest : public InProcessBrowserTest {
22 protected:
23 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
24 NOTREACHED();
25 return NULL;
26 }
27
28 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.
29 GURL url(URLRequestSlowDownloadJob::kKnownSizeUrl);
30
31 if (num_downloads == 0)
32 return;
33
34 // Setup an observer waiting for the given number of downloads
35 // to get to IN_PROGRESS.
36 DownloadManager* download_manager =
37 browser->profile()->GetDownloadManager();
38 scoped_ptr<DownloadTestObserver> observer(
39 new DownloadTestObserver(
40 download_manager, num_downloads,
41 DownloadItem::IN_PROGRESS,
42 true, // Bail on select file
43 DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL));
44
45 // Set of that number of downloads.
46 while (num_downloads--)
47 ui_test_utils::NavigateToURLWithDisposition(
48 browser, url, NEW_BACKGROUND_TAB,
49 ui_test_utils::BROWSER_TEST_NONE);
50
51 // Wait for them.
52 observer->WaitForFinished();
53 }
54
55 void CompleteAllDownloads() {
56 GURL finish_url(URLRequestSlowDownloadJob::kFinishDownloadUrl);
57 ui_test_utils::NavigateToURL(browser(), finish_url);
58
59 // Go through and, for every single profile, wait until there are
60 // no active downloads on that download manager.
61 std::vector<Profile*> profiles(
62 g_browser_process->profile_manager()->GetLoadedProfiles());
63 for (std::vector<Profile*>::const_iterator pit = profiles.begin();
64 pit != profiles.end(); ++pit) {
65 if ((*pit)->HasCreatedDownloadManager()) {
66 DownloadManager *mgr = (*pit)->GetDownloadManager();
67 scoped_refptr<DownloadTestFlushObserver> observer(
68 new DownloadTestFlushObserver(mgr));
69 observer->WaitForFlush();
70 }
71 }
72 }
73
74 Browser* CreateBrowserOnProfile(Profile* profile) {
75 Browser* new_browser = Browser::Create(profile);
76 new_browser->AddSelectedTabWithURL(GURL(chrome::kAboutBlankURL),
77 PageTransition::START_PAGE);
78 ui_test_utils::WaitForNavigation(
79 &new_browser->GetSelectedTabContents()->controller());
80 new_browser->window()->Show();
81 return new_browser;
82 }
83
84 // Assumes a single browser on the profile passed in in *base_browser.
85 bool AdjustBrowsersOnProfile(Browser** base_browser, int num_windows) {
86 Browser::DownloadClosePreventionType type;
87 int num_downloads_blocking;
88 if (num_windows == 0) {
89 if (!(*base_browser)->OkToCloseWithInProgressDownloads(
90 &type, &num_downloads_blocking))
91 return false;
92 (*base_browser)->window()->Close();
93 *base_browser = 0;
94 return true;
95 }
96
97 // num_windows > 0
98 Profile* profile((*base_browser)->profile());
99 for (int w = 1; w < num_windows; w++) {
100 CreateBrowserOnProfile(profile);
101 }
102 return true;
103 }
104
105 };
106
107 struct DownloadsCloseCheckCase {
108 std::string DebugString() const;
109
110 // Input
111 struct {
112 struct {
113 int windows;
114 int downloads;
115 } regular;
116 struct {
117 int windows;
118 int downloads;
119 } incognito;
120 } profile_a;
121
122 struct {
123 struct {
124 int windows;
125 int downloads;
126 } regular;
127 struct {
128 int windows;
129 int downloads;
130 } incognito;
131 } profile_b;
132
133 // We always probe a window in profile A.
134 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.
135
136 // Output
137 bool warn; // Controlling; if we don't warn, the rest aren't checked.
138
139 Browser::DownloadClosePreventionType type;
140 int num_blocking;
141 };
142
143 std::string DownloadsCloseCheckCase::DebugString() const {
144 std::string result;
145 result += "Case: {";
146 if (profile_a.regular.windows || profile_a.regular.downloads)
147 result += base::StringPrintf("Regular profile A: (%d w, %d d), ",
148 profile_a.regular.windows,
149 profile_a.regular.downloads);
150 if (profile_a.incognito.windows || profile_a.incognito.downloads)
151 result += base::StringPrintf("Incognito profile A: (%d w, %d d), ",
152 profile_a.incognito.windows,
153 profile_a.incognito.downloads);
154 if (profile_b.regular.windows || profile_b.regular.downloads)
155 result += base::StringPrintf("Regular profile B: (%d w, %d d), ",
156 profile_b.regular.windows,
157 profile_b.regular.downloads);
158 if (profile_b.incognito.windows || profile_b.incognito.downloads)
159 result += base::StringPrintf("Incognito profile B: (%d w, %d d), ",
160 profile_b.incognito.windows,
161 profile_b.incognito.downloads);
162 result += (window_to_probe == REGULAR ? "Probe regular" :
163 window_to_probe == INCOGNITO ? "Probe incognito" :
164 "Probe unknown");
165 result += "} -> ";
166 if (!warn) {
167 result += "No warning";
168 } else {
169 result += base::StringPrintf(
170 "%s (%d downloads) warning",
171 (type == Browser::BROWSER_SHUTDOWN ? "Browser shutdown" :
172 type == Browser::LAST_WINDOW_IN_INCOGNITO_PROFILE ? "Incognito close" :
173 "Unknown"), num_blocking);
174 }
175 return result;
176 }
177
178 static const DownloadsCloseCheckCase download_close_check_cases[] = {
179 // Top level nesting is {profile_a, profile_b}
180 // Second level nesting is {regular, incognito
181 // Third level (inner) nesting is {windows, downloads}
182
183 // Last window (incognito) triggers browser close warning.
184 {{{0, 0}, {1, 1}}, {{0, 0}, {0, 0}}, DownloadsCloseCheckCase::INCOGNITO,
185 true, Browser::BROWSER_SHUTDOWN, 1},
186
187 // Last incognito window triggers incognito close warning.
188 {{{1, 0}, {1, 1}}, {{0, 0}, {0, 0}}, DownloadsCloseCheckCase::INCOGNITO,
189 true, Browser::LAST_WINDOW_IN_INCOGNITO_PROFILE, 1},
190
191 // Last incognito window with no downloads triggers no warning.
192 {{{0, 0}, {1, 0}}, {{0, 0}, {0, 0}}, DownloadsCloseCheckCase::INCOGNITO,
193 1},
194
195 // Last incognito window with window+download on another incognito profile
196 // triggers no warning.
197 {{{0, 0}, {1, 0}}, {{0, 0}, {1, 1}}, DownloadsCloseCheckCase::INCOGNITO,
198 1},
199
200 // Non-last incognito window triggers no warning.
201 {{{0, 0}, {2, 1}}, {{0, 0}, {0, 0}}, DownloadsCloseCheckCase::INCOGNITO,
202 1},
203
204 // Non-last regular window triggers no warning.
205 {{{2, 1}, {0, 0}}, {{0, 0}, {0, 0}}, DownloadsCloseCheckCase::REGULAR,
206 1},
207
208 // Last regular window triggers browser close.
209 {{{1, 1}, {0, 0}}, {{0, 0}, {0, 0}}, DownloadsCloseCheckCase::REGULAR,
210 true, Browser::BROWSER_SHUTDOWN, 1},
211
212 // Last regular window triggers browser close for download on different
213 // profile.
214 {{{1, 0}, {0, 0}}, {{0, 1}, {0, 0}}, DownloadsCloseCheckCase::REGULAR,
215 true, Browser::BROWSER_SHUTDOWN, 1},
216
217 // Last regular window triggers no warning if incognito
218 // active (http://crbug.com/61257).
219 {{{1, 0}, {1, 1}}, {{0, 0}, {0, 0}}, DownloadsCloseCheckCase::REGULAR,
220 1},
221
222 // Last regular window triggers no warning if other profile window active.
223 {{{1, 1}, {0, 0}}, {{1, 0}, {0, 0}}, DownloadsCloseCheckCase::REGULAR,
224 1},
225
226 // Last regular window triggers no warning if other incognito window
227 // active.
228 {{{1, 0}, {0, 0}}, {{0, 0}, {1, 1}}, DownloadsCloseCheckCase::REGULAR,
229 1},
230
231 // Last regular window triggers no warning if incognito active.
232 {{{1, 1}, {1, 0}}, {{0, 0}, {0, 0}}, DownloadsCloseCheckCase::REGULAR,
233 1},
234
235 // Test plural for regular.
236 {{{1, 2}, {0, 0}}, {{0, 0}, {0, 0}}, DownloadsCloseCheckCase::REGULAR,
237 true, Browser::BROWSER_SHUTDOWN, 2},
238
239 // Test plural for incognito.
240 {{{1, 0}, {1, 2}}, {{0, 0}, {0, 0}}, DownloadsCloseCheckCase::INCOGNITO,
241 true, Browser::LAST_WINDOW_IN_INCOGNITO_PROFILE, 2},
242 };
243
244 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
245 Profile* profile_a = browser()->profile();
246 Profile* profile_b = CreateNewProfile();
247
248 for (size_t i = 0; i < arraysize(download_close_check_cases); ++i) {
249 const DownloadsCloseCheckCase& check_case(download_close_check_cases[i]);
250
251 // Loop invariant; so that we don't actually try and close the browser,
252 // we always enter the loop with a single browser window open on the
253 // main profile. That means we need to exit the loop the same way.
254 // So we setup everything except for the profile_a regular, and then
255 // flip the bit on the main window.
256 // Note that this means that browser() is unreliable in the context
257 // of this function; we'll be killing that main window and recreating
258 // it fairly frequently.
259
260 ASSERT_EQ(1u, BrowserList::size());
261 Browser* entry_browser = *BrowserList::begin();
262 ASSERT_EQ(profile_a, entry_browser->profile());
263 int total_downloads = 0;
264 int profile_downloads = 0;
265 entry_browser->CheckDownloadsInProgress(
266 &total_downloads, &profile_downloads);
267 ASSERT_EQ(0, total_downloads);
268
269 Profile* profile_a_incognito = profile_a->GetOffTheRecordProfile();
270 Profile* profile_b_incognito = profile_b->GetOffTheRecordProfile();
271
272 // For simplicty of coding, we create a window on each profile so that
273 // we can easily create downloads, then we destroy or create windows
274 // as necessary.
275 Browser* browser_a_regular(CreateBrowserOnProfile(profile_a));
276 Browser* browser_a_incognito(CreateBrowserOnProfile(profile_a_incognito));
277 Browser* browser_b_regular(CreateBrowserOnProfile(profile_b));
278 Browser* browser_b_incognito(CreateBrowserOnProfile(profile_b_incognito));
279
280 // Kill our entry browser.
281 entry_browser->window()->Close();
282 entry_browser = NULL;
283
284 // Create all downloads needed.
285 CreateStalledDownload(
286 browser_a_regular, check_case.profile_a.regular.downloads);
287 CreateStalledDownload(
288 browser_a_incognito, check_case.profile_a.incognito.downloads);
289 CreateStalledDownload(
290 browser_b_regular, check_case.profile_b.regular.downloads);
291 CreateStalledDownload(
292 browser_b_incognito, check_case.profile_b.incognito.downloads);
293
294 // Adjust the windows
295 ASSERT_TRUE(AdjustBrowsersOnProfile(
296 &browser_a_regular, check_case.profile_a.regular.windows));
297 ASSERT_TRUE(AdjustBrowsersOnProfile(
298 &browser_a_incognito, check_case.profile_a.incognito.windows));
299 ASSERT_TRUE(AdjustBrowsersOnProfile(
300 &browser_b_regular, check_case.profile_b.regular.windows));
301 ASSERT_TRUE(AdjustBrowsersOnProfile(
302 &browser_b_incognito, check_case.profile_b.incognito.windows));
303
304 // All that work, for this one little test.
305 ASSERT_TRUE((check_case.window_to_probe ==
306 DownloadsCloseCheckCase::REGULAR) ||
307 (check_case.window_to_probe ==
308 DownloadsCloseCheckCase::INCOGNITO));
309
310 Browser::DownloadClosePreventionType type;
311 int num_downloads_blocking;
312 bool result =
313 (check_case.window_to_probe == DownloadsCloseCheckCase::REGULAR ?
314 browser_a_regular :
315 browser_a_incognito)->OkToCloseWithInProgressDownloads(
316 &type, &num_downloads_blocking);
317 EXPECT_EQ(check_case.warn, result) << check_case.DebugString();
318 if (!result) {
319 EXPECT_EQ(check_case.type, type) << check_case.DebugString();
320 EXPECT_EQ(check_case.num_blocking, num_downloads_blocking)
321 << check_case.DebugString();
322 }
323
324 // Release and all the downloads
325 CompleteAllDownloads();
326
327 // Create a new main window and kill everything else.
328 entry_browser = CreateBrowserOnProfile(profile_a);
329 if (browser_a_regular)
330 browser_a_regular->window()->Close();
331 if (browser_a_incognito)
332 browser_a_incognito->window()->Close();
333 if (browser_b_regular)
334 browser_b_regular->window()->Close();
335 if (browser_b_incognito)
336 browser_b_incognito->window()->Close();
337 }
338 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698