OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 #include "content/public/test/download_test_observer.h" |
| 6 |
5 #include <vector> | 7 #include <vector> |
6 | 8 |
7 #include "base/bind.h" | 9 #include "base/bind.h" |
8 #include "base/logging.h" | 10 #include "base/logging.h" |
9 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
10 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
11 #include "chrome/browser/download/chrome_download_manager_delegate.h" | |
12 #include "chrome/browser/download/download_service.h" | |
13 #include "chrome/browser/download/download_service_factory.h" | |
14 #include "chrome/browser/download/download_test_observer.h" | |
15 #include "chrome/test/base/ui_test_utils.h" | |
16 #include "content/public/browser/browser_thread.h" | 13 #include "content/public/browser/browser_thread.h" |
17 #include "content/public/browser/download_url_parameters.h" | 14 #include "content/public/browser/download_url_parameters.h" |
| 15 #include "content/public/test/test_utils.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" |
18 | 17 |
19 using content::BrowserThread; | 18 namespace content { |
20 using content::DownloadItem; | |
21 using content::DownloadManager; | |
22 | 19 |
23 namespace { | 20 namespace { |
24 | 21 |
25 // These functions take scoped_refptr's to DownloadManager because they | 22 // These functions take scoped_refptr's to DownloadManager because they |
26 // are posted to message queues, and hence may execute arbitrarily after | 23 // are posted to message queues, and hence may execute arbitrarily after |
27 // their actual posting. Once posted, there is no connection between | 24 // their actual posting. Once posted, there is no connection between |
28 // these routines and the DownloadTestObserver class from which | 25 // these routines and the DownloadTestObserver class from which |
29 // they came, so the DownloadTestObserver's reference to the | 26 // they came, so the DownloadTestObserver's reference to the |
30 // DownloadManager cannot be counted on to keep the DownloadManager around. | 27 // DownloadManager cannot be counted on to keep the DownloadManager around. |
31 | 28 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 | 65 |
69 void DownloadTestObserver::Init() { | 66 void DownloadTestObserver::Init() { |
70 download_manager_->AddObserver(this); // Will call initial ModelChanged(). | 67 download_manager_->AddObserver(this); // Will call initial ModelChanged(). |
71 finished_downloads_at_construction_ = finished_downloads_.size(); | 68 finished_downloads_at_construction_ = finished_downloads_.size(); |
72 states_observed_.clear(); | 69 states_observed_.clear(); |
73 } | 70 } |
74 | 71 |
75 void DownloadTestObserver::WaitForFinished() { | 72 void DownloadTestObserver::WaitForFinished() { |
76 if (!IsFinished()) { | 73 if (!IsFinished()) { |
77 waiting_ = true; | 74 waiting_ = true; |
78 content::RunMessageLoop(); | 75 RunMessageLoop(); |
79 waiting_ = false; | 76 waiting_ = false; |
80 } | 77 } |
81 } | 78 } |
82 | 79 |
83 bool DownloadTestObserver::IsFinished() const { | 80 bool DownloadTestObserver::IsFinished() const { |
84 return (finished_downloads_.size() - finished_downloads_at_construction_ >= | 81 return (finished_downloads_.size() - finished_downloads_at_construction_ >= |
85 wait_count_); | 82 wait_count_); |
86 } | 83 } |
87 | 84 |
88 void DownloadTestObserver::OnDownloadDestroyed(DownloadItem* download) { | 85 void DownloadTestObserver::OnDownloadDestroyed(DownloadItem* download) { |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 continue; | 166 continue; |
170 } | 167 } |
171 } | 168 } |
172 } | 169 } |
173 | 170 |
174 size_t DownloadTestObserver::NumDangerousDownloadsSeen() const { | 171 size_t DownloadTestObserver::NumDangerousDownloadsSeen() const { |
175 return dangerous_downloads_seen_.size(); | 172 return dangerous_downloads_seen_.size(); |
176 } | 173 } |
177 | 174 |
178 size_t DownloadTestObserver::NumDownloadsSeenInState( | 175 size_t DownloadTestObserver::NumDownloadsSeenInState( |
179 content::DownloadItem::DownloadState state) const { | 176 DownloadItem::DownloadState state) const { |
180 StateMap::const_iterator it = states_observed_.find(state); | 177 StateMap::const_iterator it = states_observed_.find(state); |
181 | 178 |
182 if (it == states_observed_.end()) | 179 if (it == states_observed_.end()) |
183 return 0; | 180 return 0; |
184 | 181 |
185 return it->second; | 182 return it->second; |
186 } | 183 } |
187 | 184 |
188 void DownloadTestObserver::DownloadInFinalState(DownloadItem* download) { | 185 void DownloadTestObserver::DownloadInFinalState(DownloadItem* download) { |
189 if (finished_downloads_.find(download) != finished_downloads_.end()) { | 186 if (finished_downloads_.find(download) != finished_downloads_.end()) { |
190 // We've already seen the final state on this download. | 187 // We've already seen the final state on this download. |
191 return; | 188 return; |
192 } | 189 } |
193 | 190 |
194 // Record the transition. | 191 // Record the transition. |
195 finished_downloads_.insert(download); | 192 finished_downloads_.insert(download); |
196 | 193 |
197 // Record the state. | 194 // Record the state. |
198 states_observed_[download->GetState()]++; // Initializes to 0 the first time. | 195 states_observed_[download->GetState()]++; // Initializes to 0 the first time. |
199 | 196 |
200 SignalIfFinished(); | 197 SignalIfFinished(); |
201 } | 198 } |
202 | 199 |
203 void DownloadTestObserver::SignalIfFinished() { | 200 void DownloadTestObserver::SignalIfFinished() { |
204 if (waiting_ && IsFinished()) | 201 if (waiting_ && IsFinished()) |
205 MessageLoopForUI::current()->Quit(); | 202 MessageLoopForUI::current()->Quit(); |
206 } | 203 } |
207 | 204 |
208 DownloadTestObserverTerminal::DownloadTestObserverTerminal( | 205 DownloadTestObserverTerminal::DownloadTestObserverTerminal( |
209 content::DownloadManager* download_manager, | 206 DownloadManager* download_manager, |
210 size_t wait_count, | 207 size_t wait_count, |
211 DangerousDownloadAction dangerous_download_action) | 208 DangerousDownloadAction dangerous_download_action) |
212 : DownloadTestObserver(download_manager, | 209 : DownloadTestObserver(download_manager, |
213 wait_count, | 210 wait_count, |
214 dangerous_download_action) { | 211 dangerous_download_action) { |
215 // You can't rely on overriden virtual functions in a base class constructor; | 212 // You can't rely on overriden virtual functions in a base class constructor; |
216 // the virtual function table hasn't been set up yet. So, we have to do any | 213 // the virtual function table hasn't been set up yet. So, we have to do any |
217 // work that depends on those functions in the derived class constructor | 214 // work that depends on those functions in the derived class constructor |
218 // instead. In this case, it's because of |IsDownloadInFinalState()|. | 215 // instead. In this case, it's because of |IsDownloadInFinalState()|. |
219 Init(); | 216 Init(); |
220 } | 217 } |
221 | 218 |
222 DownloadTestObserverTerminal::~DownloadTestObserverTerminal() { | 219 DownloadTestObserverTerminal::~DownloadTestObserverTerminal() { |
223 } | 220 } |
224 | 221 |
225 | 222 |
226 bool DownloadTestObserverTerminal::IsDownloadInFinalState( | 223 bool DownloadTestObserverTerminal::IsDownloadInFinalState( |
227 content::DownloadItem* download) { | 224 DownloadItem* download) { |
228 return (download->GetState() != DownloadItem::IN_PROGRESS); | 225 return (download->GetState() != DownloadItem::IN_PROGRESS); |
229 } | 226 } |
230 | 227 |
231 DownloadTestObserverInProgress::DownloadTestObserverInProgress( | 228 DownloadTestObserverInProgress::DownloadTestObserverInProgress( |
232 content::DownloadManager* download_manager, | 229 DownloadManager* download_manager, |
233 size_t wait_count) | 230 size_t wait_count) |
234 : DownloadTestObserver(download_manager, | 231 : DownloadTestObserver(download_manager, |
235 wait_count, | 232 wait_count, |
236 ON_DANGEROUS_DOWNLOAD_ACCEPT) { | 233 ON_DANGEROUS_DOWNLOAD_ACCEPT) { |
237 // You can't override virtual functions in a base class constructor; the | 234 // You can't override virtual functions in a base class constructor; the |
238 // virtual function table hasn't been set up yet. So, we have to do any | 235 // virtual function table hasn't been set up yet. So, we have to do any |
239 // work that depends on those functions in the derived class constructor | 236 // work that depends on those functions in the derived class constructor |
240 // instead. In this case, it's because of |IsDownloadInFinalState()|. | 237 // instead. In this case, it's because of |IsDownloadInFinalState()|. |
241 Init(); | 238 Init(); |
242 } | 239 } |
243 | 240 |
244 DownloadTestObserverInProgress::~DownloadTestObserverInProgress() { | 241 DownloadTestObserverInProgress::~DownloadTestObserverInProgress() { |
245 } | 242 } |
246 | 243 |
247 | 244 |
248 bool DownloadTestObserverInProgress::IsDownloadInFinalState( | 245 bool DownloadTestObserverInProgress::IsDownloadInFinalState( |
249 content::DownloadItem* download) { | 246 DownloadItem* download) { |
250 return (download->GetState() == DownloadItem::IN_PROGRESS); | 247 return (download->GetState() == DownloadItem::IN_PROGRESS); |
251 } | 248 } |
252 | 249 |
253 DownloadTestFlushObserver::DownloadTestFlushObserver( | 250 DownloadTestFlushObserver::DownloadTestFlushObserver( |
254 DownloadManager* download_manager) | 251 DownloadManager* download_manager) |
255 : download_manager_(download_manager), | 252 : download_manager_(download_manager), |
256 waiting_for_zero_inprogress_(true) {} | 253 waiting_for_zero_inprogress_(true) {} |
257 | 254 |
258 void DownloadTestFlushObserver::WaitForFlush() { | 255 void DownloadTestFlushObserver::WaitForFlush() { |
259 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 256 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
260 download_manager_->AddObserver(this); | 257 download_manager_->AddObserver(this); |
261 content::RunMessageLoop(); | 258 RunMessageLoop(); |
262 } | 259 } |
263 | 260 |
264 void DownloadTestFlushObserver::ModelChanged(DownloadManager* manager) { | 261 void DownloadTestFlushObserver::ModelChanged(DownloadManager* manager) { |
265 // Model has changed, so there may be more DownloadItems to observe. | 262 // Model has changed, so there may be more DownloadItems to observe. |
266 CheckDownloadsInProgress(true); | 263 CheckDownloadsInProgress(true); |
267 } | 264 } |
268 | 265 |
269 void DownloadTestFlushObserver::OnDownloadDestroyed(DownloadItem* download) { | 266 void DownloadTestFlushObserver::OnDownloadDestroyed(DownloadItem* download) { |
270 // Stop observing. Do not do anything with it, as it is about to be gone. | 267 // Stop observing. Do not do anything with it, as it is about to be gone. |
271 DownloadSet::iterator it = downloads_observed_.find(download); | 268 DownloadSet::iterator it = downloads_observed_.find(download); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 BrowserThread::PostTask( | 340 BrowserThread::PostTask( |
344 BrowserThread::UI, FROM_HERE, | 341 BrowserThread::UI, FROM_HERE, |
345 base::Bind(&DownloadTestFlushObserver::PingFileThread, this, cycle)); | 342 base::Bind(&DownloadTestFlushObserver::PingFileThread, this, cycle)); |
346 } else { | 343 } else { |
347 BrowserThread::PostTask( | 344 BrowserThread::PostTask( |
348 BrowserThread::UI, FROM_HERE, MessageLoop::QuitClosure()); | 345 BrowserThread::UI, FROM_HERE, MessageLoop::QuitClosure()); |
349 } | 346 } |
350 } | 347 } |
351 | 348 |
352 DownloadTestItemCreationObserver::DownloadTestItemCreationObserver() | 349 DownloadTestItemCreationObserver::DownloadTestItemCreationObserver() |
353 : download_id_(content::DownloadId::Invalid()), | 350 : download_id_(DownloadId::Invalid()), |
354 error_(net::OK), | 351 error_(net::OK), |
355 called_back_count_(0), | 352 called_back_count_(0), |
356 waiting_(false) { | 353 waiting_(false) { |
357 } | 354 } |
358 | 355 |
359 DownloadTestItemCreationObserver::~DownloadTestItemCreationObserver() { | 356 DownloadTestItemCreationObserver::~DownloadTestItemCreationObserver() { |
360 } | 357 } |
361 | 358 |
362 void DownloadTestItemCreationObserver::WaitForDownloadItemCreation() { | 359 void DownloadTestItemCreationObserver::WaitForDownloadItemCreation() { |
363 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 360 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
364 | 361 |
365 if (called_back_count_ == 0) { | 362 if (called_back_count_ == 0) { |
366 waiting_ = true; | 363 waiting_ = true; |
367 content::RunMessageLoop(); | 364 RunMessageLoop(); |
368 waiting_ = false; | 365 waiting_ = false; |
369 } | 366 } |
370 } | 367 } |
371 | 368 |
372 void DownloadTestItemCreationObserver::DownloadItemCreationCallback( | 369 void DownloadTestItemCreationObserver::DownloadItemCreationCallback( |
373 content::DownloadId download_id, net::Error error) { | 370 DownloadId download_id, net::Error error) { |
374 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 371 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
375 | 372 |
376 download_id_ = download_id; | 373 download_id_ = download_id; |
377 error_ = error; | 374 error_ = error; |
378 ++called_back_count_; | 375 ++called_back_count_; |
379 DCHECK_EQ(1u, called_back_count_); | 376 DCHECK_EQ(1u, called_back_count_); |
380 | 377 |
381 if (waiting_) | 378 if (waiting_) |
382 MessageLoopForUI::current()->Quit(); | 379 MessageLoopForUI::current()->Quit(); |
383 } | 380 } |
384 | 381 |
385 const content::DownloadUrlParameters::OnStartedCallback | 382 const DownloadUrlParameters::OnStartedCallback |
386 DownloadTestItemCreationObserver::callback() { | 383 DownloadTestItemCreationObserver::callback() { |
387 return base::Bind( | 384 return base::Bind( |
388 &DownloadTestItemCreationObserver::DownloadItemCreationCallback, this); | 385 &DownloadTestItemCreationObserver::DownloadItemCreationCallback, this); |
389 } | 386 } |
390 | 387 |
391 namespace internal { | 388 } // namespace content |
392 | |
393 // Test ChromeDownloadManagerDelegate that controls whether how file chooser | |
394 // dialogs are handled. By default, file chooser dialogs are disabled. | |
395 class MockFileChooserDownloadManagerDelegate | |
396 : public ChromeDownloadManagerDelegate { | |
397 public: | |
398 explicit MockFileChooserDownloadManagerDelegate(Profile* profile) | |
399 : ChromeDownloadManagerDelegate(profile), | |
400 file_chooser_enabled_(false), | |
401 file_chooser_displayed_(false) {} | |
402 | |
403 void EnableFileChooser(bool enable) { | |
404 file_chooser_enabled_ = enable; | |
405 } | |
406 | |
407 bool TestAndResetDidShowFileChooser() { | |
408 bool did_show = file_chooser_displayed_; | |
409 file_chooser_displayed_ = false; | |
410 return did_show; | |
411 } | |
412 | |
413 private: | |
414 virtual ~MockFileChooserDownloadManagerDelegate() {} | |
415 | |
416 virtual void ChooseDownloadPath(DownloadItem* item, | |
417 const FilePath& suggested_path, | |
418 const FileSelectedCallback& | |
419 callback) OVERRIDE { | |
420 file_chooser_displayed_ = true; | |
421 MessageLoop::current()->PostTask( | |
422 FROM_HERE, | |
423 base::Bind(callback, | |
424 (file_chooser_enabled_ ? suggested_path : FilePath()))); | |
425 } | |
426 | |
427 bool file_chooser_enabled_; | |
428 bool file_chooser_displayed_; | |
429 }; | |
430 | |
431 } // namespace internal | |
432 | |
433 DownloadTestFileChooserObserver::DownloadTestFileChooserObserver( | |
434 Profile* profile) { | |
435 test_delegate_ = | |
436 new internal::MockFileChooserDownloadManagerDelegate(profile); | |
437 DownloadServiceFactory::GetForProfile(profile)-> | |
438 SetDownloadManagerDelegateForTesting(test_delegate_.get()); | |
439 } | |
440 | |
441 DownloadTestFileChooserObserver::~DownloadTestFileChooserObserver() { | |
442 } | |
443 | |
444 void DownloadTestFileChooserObserver::EnableFileChooser(bool enable) { | |
445 test_delegate_->EnableFileChooser(enable); | |
446 } | |
447 | |
448 bool DownloadTestFileChooserObserver::TestAndResetDidShowFileChooser() { | |
449 return test_delegate_->TestAndResetDidShowFileChooser(); | |
450 } | |
OLD | NEW |