OLD | NEW |
---|---|
(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 } | |
OLD | NEW |