Chromium Code Reviews| 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 |