| 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 <vector> | 5 #include <vector> |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "base/stl_util.h" | 10 #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" |
| 11 #include "chrome/browser/download/download_test_observer.h" | 14 #include "chrome/browser/download/download_test_observer.h" |
| 12 #include "chrome/test/base/ui_test_utils.h" | 15 #include "chrome/test/base/ui_test_utils.h" |
| 13 #include "content/public/browser/browser_thread.h" | 16 #include "content/public/browser/browser_thread.h" |
| 14 #include "content/public/browser/download_url_parameters.h" | 17 #include "content/public/browser/download_url_parameters.h" |
| 15 | 18 |
| 16 using content::BrowserThread; | 19 using content::BrowserThread; |
| 17 using content::DownloadItem; | 20 using content::DownloadItem; |
| 18 using content::DownloadManager; | 21 using content::DownloadManager; |
| 19 | 22 |
| 23 namespace { |
| 24 |
| 20 // These functions take scoped_refptr's to DownloadManager because they | 25 // These functions take scoped_refptr's to DownloadManager because they |
| 21 // are posted to message queues, and hence may execute arbitrarily after | 26 // are posted to message queues, and hence may execute arbitrarily after |
| 22 // their actual posting. Once posted, there is no connection between | 27 // their actual posting. Once posted, there is no connection between |
| 23 // these routines and the DownloadTestObserver class from which | 28 // these routines and the DownloadTestObserver class from which |
| 24 // they came, so the DownloadTestObserver's reference to the | 29 // they came, so the DownloadTestObserver's reference to the |
| 25 // DownloadManager cannot be counted on to keep the DownloadManager around. | 30 // DownloadManager cannot be counted on to keep the DownloadManager around. |
| 26 | 31 |
| 27 // Fake user click on "Accept". | 32 // Fake user click on "Accept". |
| 28 void AcceptDangerousDownload(scoped_refptr<DownloadManager> download_manager, | 33 void AcceptDangerousDownload(scoped_refptr<DownloadManager> download_manager, |
| 29 int32 download_id) { | 34 int32 download_id) { |
| 30 DownloadItem* download = download_manager->GetDownloadItem(download_id); | 35 DownloadItem* download = download_manager->GetDownloadItem(download_id); |
| 31 download->DangerousDownloadValidated(); | 36 download->DangerousDownloadValidated(); |
| 32 } | 37 } |
| 33 | 38 |
| 34 // Fake user click on "Deny". | 39 // Fake user click on "Deny". |
| 35 void DenyDangerousDownload(scoped_refptr<DownloadManager> download_manager, | 40 void DenyDangerousDownload(scoped_refptr<DownloadManager> download_manager, |
| 36 int32 download_id) { | 41 int32 download_id) { |
| 37 DownloadItem* download = download_manager->GetDownloadItem(download_id); | 42 DownloadItem* download = download_manager->GetDownloadItem(download_id); |
| 38 ASSERT_TRUE(download->IsPartialDownload()); | 43 ASSERT_TRUE(download->IsPartialDownload()); |
| 39 download->Cancel(true); | 44 download->Cancel(true); |
| 40 download->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD); | 45 download->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD); |
| 41 } | 46 } |
| 42 | 47 |
| 48 } // namespace |
| 49 |
| 43 DownloadTestObserver::DownloadTestObserver( | 50 DownloadTestObserver::DownloadTestObserver( |
| 44 DownloadManager* download_manager, | 51 DownloadManager* download_manager, |
| 45 size_t wait_count, | 52 size_t wait_count, |
| 46 bool finish_on_select_file, | |
| 47 DangerousDownloadAction dangerous_download_action) | 53 DangerousDownloadAction dangerous_download_action) |
| 48 : download_manager_(download_manager), | 54 : download_manager_(download_manager), |
| 49 wait_count_(wait_count), | 55 wait_count_(wait_count), |
| 50 finished_downloads_at_construction_(0), | 56 finished_downloads_at_construction_(0), |
| 51 waiting_(false), | 57 waiting_(false), |
| 52 finish_on_select_file_(finish_on_select_file), | |
| 53 select_file_dialog_seen_(false), | |
| 54 dangerous_download_action_(dangerous_download_action) { | 58 dangerous_download_action_(dangerous_download_action) { |
| 55 } | 59 } |
| 56 | 60 |
| 57 DownloadTestObserver::~DownloadTestObserver() { | 61 DownloadTestObserver::~DownloadTestObserver() { |
| 58 for (DownloadSet::iterator it = downloads_observed_.begin(); | 62 for (DownloadSet::iterator it = downloads_observed_.begin(); |
| 59 it != downloads_observed_.end(); ++it) | 63 it != downloads_observed_.end(); ++it) |
| 60 (*it)->RemoveObserver(this); | 64 (*it)->RemoveObserver(this); |
| 61 | 65 |
| 62 download_manager_->RemoveObserver(this); | 66 download_manager_->RemoveObserver(this); |
| 63 } | 67 } |
| 64 | 68 |
| 65 void DownloadTestObserver::Init() { | 69 void DownloadTestObserver::Init() { |
| 66 download_manager_->AddObserver(this); // Will call initial ModelChanged(). | 70 download_manager_->AddObserver(this); // Will call initial ModelChanged(). |
| 67 finished_downloads_at_construction_ = finished_downloads_.size(); | 71 finished_downloads_at_construction_ = finished_downloads_.size(); |
| 68 states_observed_.clear(); | 72 states_observed_.clear(); |
| 69 } | 73 } |
| 70 | 74 |
| 71 void DownloadTestObserver::WaitForFinished() { | 75 void DownloadTestObserver::WaitForFinished() { |
| 72 if (!IsFinished()) { | 76 if (!IsFinished()) { |
| 73 waiting_ = true; | 77 waiting_ = true; |
| 74 ui_test_utils::RunMessageLoop(); | 78 ui_test_utils::RunMessageLoop(); |
| 75 waiting_ = false; | 79 waiting_ = false; |
| 76 } | 80 } |
| 77 } | 81 } |
| 78 | 82 |
| 79 bool DownloadTestObserver::IsFinished() const { | 83 bool DownloadTestObserver::IsFinished() const { |
| 80 if (finished_downloads_.size() - finished_downloads_at_construction_ >= | 84 return (finished_downloads_.size() - finished_downloads_at_construction_ >= |
| 81 wait_count_) | 85 wait_count_); |
| 82 return true; | |
| 83 return (finish_on_select_file_ && select_file_dialog_seen_); | |
| 84 } | 86 } |
| 85 | 87 |
| 86 void DownloadTestObserver::OnDownloadUpdated(DownloadItem* download) { | 88 void DownloadTestObserver::OnDownloadUpdated(DownloadItem* download) { |
| 87 // The REMOVING state indicates that the download is being destroyed. | 89 // The REMOVING state indicates that the download is being destroyed. |
| 88 // Stop observing. Do not do anything with it, as it is about to be gone. | 90 // Stop observing. Do not do anything with it, as it is about to be gone. |
| 89 if (download->GetState() == DownloadItem::REMOVING) { | 91 if (download->GetState() == DownloadItem::REMOVING) { |
| 90 DownloadSet::iterator it = downloads_observed_.find(download); | 92 DownloadSet::iterator it = downloads_observed_.find(download); |
| 91 ASSERT_TRUE(it != downloads_observed_.end()); | 93 ASSERT_TRUE(it != downloads_observed_.end()); |
| 92 downloads_observed_.erase(it); | 94 downloads_observed_.erase(it); |
| 93 download->RemoveObserver(this); | 95 download->RemoveObserver(this); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 // If it is finished and we are observing it, stop. | 166 // If it is finished and we are observing it, stop. |
| 165 if (finished_it != finished_downloads_.end() && | 167 if (finished_it != finished_downloads_.end() && |
| 166 observed_it != downloads_observed_.end()) { | 168 observed_it != downloads_observed_.end()) { |
| 167 (*it)->RemoveObserver(this); | 169 (*it)->RemoveObserver(this); |
| 168 downloads_observed_.erase(observed_it); | 170 downloads_observed_.erase(observed_it); |
| 169 continue; | 171 continue; |
| 170 } | 172 } |
| 171 } | 173 } |
| 172 } | 174 } |
| 173 | 175 |
| 174 void DownloadTestObserver::SelectFileDialogDisplayed( | |
| 175 DownloadManager* manager, int32 /* id */) { | |
| 176 DCHECK_EQ(manager, download_manager_); | |
| 177 select_file_dialog_seen_ = true; | |
| 178 SignalIfFinished(); | |
| 179 } | |
| 180 | |
| 181 size_t DownloadTestObserver::NumDangerousDownloadsSeen() const { | 176 size_t DownloadTestObserver::NumDangerousDownloadsSeen() const { |
| 182 return dangerous_downloads_seen_.size(); | 177 return dangerous_downloads_seen_.size(); |
| 183 } | 178 } |
| 184 | 179 |
| 185 size_t DownloadTestObserver::NumDownloadsSeenInState( | 180 size_t DownloadTestObserver::NumDownloadsSeenInState( |
| 186 content::DownloadItem::DownloadState state) const { | 181 content::DownloadItem::DownloadState state) const { |
| 187 StateMap::const_iterator it = states_observed_.find(state); | 182 StateMap::const_iterator it = states_observed_.find(state); |
| 188 | 183 |
| 189 if (it == states_observed_.end()) | 184 if (it == states_observed_.end()) |
| 190 return 0; | 185 return 0; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 208 } | 203 } |
| 209 | 204 |
| 210 void DownloadTestObserver::SignalIfFinished() { | 205 void DownloadTestObserver::SignalIfFinished() { |
| 211 if (waiting_ && IsFinished()) | 206 if (waiting_ && IsFinished()) |
| 212 MessageLoopForUI::current()->Quit(); | 207 MessageLoopForUI::current()->Quit(); |
| 213 } | 208 } |
| 214 | 209 |
| 215 DownloadTestObserverTerminal::DownloadTestObserverTerminal( | 210 DownloadTestObserverTerminal::DownloadTestObserverTerminal( |
| 216 content::DownloadManager* download_manager, | 211 content::DownloadManager* download_manager, |
| 217 size_t wait_count, | 212 size_t wait_count, |
| 218 bool finish_on_select_file, | |
| 219 DangerousDownloadAction dangerous_download_action) | 213 DangerousDownloadAction dangerous_download_action) |
| 220 : DownloadTestObserver(download_manager, | 214 : DownloadTestObserver(download_manager, |
| 221 wait_count, | 215 wait_count, |
| 222 finish_on_select_file, | |
| 223 dangerous_download_action) { | 216 dangerous_download_action) { |
| 224 // You can't rely on overriden virtual functions in a base class constructor; | 217 // You can't rely on overriden virtual functions in a base class constructor; |
| 225 // the virtual function table hasn't been set up yet. So, we have to do any | 218 // the virtual function table hasn't been set up yet. So, we have to do any |
| 226 // work that depends on those functions in the derived class constructor | 219 // work that depends on those functions in the derived class constructor |
| 227 // instead. In this case, it's because of |IsDownloadInFinalState()|. | 220 // instead. In this case, it's because of |IsDownloadInFinalState()|. |
| 228 Init(); | 221 Init(); |
| 229 } | 222 } |
| 230 | 223 |
| 231 DownloadTestObserverTerminal::~DownloadTestObserverTerminal() { | 224 DownloadTestObserverTerminal::~DownloadTestObserverTerminal() { |
| 232 } | 225 } |
| 233 | 226 |
| 234 | 227 |
| 235 bool DownloadTestObserverTerminal::IsDownloadInFinalState( | 228 bool DownloadTestObserverTerminal::IsDownloadInFinalState( |
| 236 content::DownloadItem* download) { | 229 content::DownloadItem* download) { |
| 237 return (download->GetState() != DownloadItem::IN_PROGRESS); | 230 return (download->GetState() != DownloadItem::IN_PROGRESS); |
| 238 } | 231 } |
| 239 | 232 |
| 240 DownloadTestObserverInProgress::DownloadTestObserverInProgress( | 233 DownloadTestObserverInProgress::DownloadTestObserverInProgress( |
| 241 content::DownloadManager* download_manager, | 234 content::DownloadManager* download_manager, |
| 242 size_t wait_count, | 235 size_t wait_count) |
| 243 bool finish_on_select_file) | |
| 244 : DownloadTestObserver(download_manager, | 236 : DownloadTestObserver(download_manager, |
| 245 wait_count, | 237 wait_count, |
| 246 finish_on_select_file, | |
| 247 ON_DANGEROUS_DOWNLOAD_ACCEPT) { | 238 ON_DANGEROUS_DOWNLOAD_ACCEPT) { |
| 248 // You can't override virtual functions in a base class constructor; the | 239 // You can't override virtual functions in a base class constructor; the |
| 249 // virtual function table hasn't been set up yet. So, we have to do any | 240 // virtual function table hasn't been set up yet. So, we have to do any |
| 250 // work that depends on those functions in the derived class constructor | 241 // work that depends on those functions in the derived class constructor |
| 251 // instead. In this case, it's because of |IsDownloadInFinalState()|. | 242 // instead. In this case, it's because of |IsDownloadInFinalState()|. |
| 252 Init(); | 243 Init(); |
| 253 } | 244 } |
| 254 | 245 |
| 255 DownloadTestObserverInProgress::~DownloadTestObserverInProgress() { | 246 DownloadTestObserverInProgress::~DownloadTestObserverInProgress() { |
| 256 } | 247 } |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 if (waiting_) | 385 if (waiting_) |
| 395 MessageLoopForUI::current()->Quit(); | 386 MessageLoopForUI::current()->Quit(); |
| 396 } | 387 } |
| 397 | 388 |
| 398 const content::DownloadUrlParameters::OnStartedCallback | 389 const content::DownloadUrlParameters::OnStartedCallback |
| 399 DownloadTestItemCreationObserver::callback() { | 390 DownloadTestItemCreationObserver::callback() { |
| 400 return base::Bind( | 391 return base::Bind( |
| 401 &DownloadTestItemCreationObserver::DownloadItemCreationCallback, this); | 392 &DownloadTestItemCreationObserver::DownloadItemCreationCallback, this); |
| 402 } | 393 } |
| 403 | 394 |
| 395 namespace internal { |
| 396 |
| 397 // Test ChromeDownloadManagerDelegate that controls whether how file chooser |
| 398 // dialogs are handled. By default, file chooser dialogs are disabled. |
| 399 class MockFileChooserDownloadManagerDelegate |
| 400 : public ChromeDownloadManagerDelegate { |
| 401 public: |
| 402 explicit MockFileChooserDownloadManagerDelegate(Profile* profile) |
| 403 : ChromeDownloadManagerDelegate(profile), |
| 404 file_chooser_enabled_(false), |
| 405 file_chooser_displayed_(false) {} |
| 406 |
| 407 void EnableFileChooser(bool enable) { |
| 408 file_chooser_enabled_ = enable; |
| 409 } |
| 410 |
| 411 bool TestAndResetDidShowFileChooser() { |
| 412 bool did_show = file_chooser_displayed_; |
| 413 file_chooser_displayed_ = false; |
| 414 return did_show; |
| 415 } |
| 416 |
| 417 private: |
| 418 virtual ~MockFileChooserDownloadManagerDelegate() {} |
| 419 |
| 420 virtual void ChooseDownloadPath(DownloadItem* item, |
| 421 const FilePath& suggested_path, |
| 422 const FileSelectedCallback& |
| 423 callback) OVERRIDE { |
| 424 file_chooser_displayed_ = true; |
| 425 MessageLoop::current()->PostTask( |
| 426 FROM_HERE, |
| 427 base::Bind(callback, |
| 428 (file_chooser_enabled_ ? suggested_path : FilePath()))); |
| 429 } |
| 430 |
| 431 bool file_chooser_enabled_; |
| 432 bool file_chooser_displayed_; |
| 433 }; |
| 434 |
| 435 } // namespace internal |
| 436 |
| 437 DownloadTestFileChooserObserver::DownloadTestFileChooserObserver( |
| 438 Profile* profile) { |
| 439 test_delegate_ = |
| 440 new internal::MockFileChooserDownloadManagerDelegate(profile); |
| 441 DownloadServiceFactory::GetForProfile(profile)-> |
| 442 SetDownloadManagerDelegateForTesting(test_delegate_.get()); |
| 443 } |
| 444 |
| 445 DownloadTestFileChooserObserver::~DownloadTestFileChooserObserver() { |
| 446 } |
| 447 |
| 448 void DownloadTestFileChooserObserver::EnableFileChooser(bool enable) { |
| 449 test_delegate_->EnableFileChooser(enable); |
| 450 } |
| 451 |
| 452 bool DownloadTestFileChooserObserver::TestAndResetDidShowFileChooser() { |
| 453 return test_delegate_->TestAndResetDidShowFileChooser(); |
| 454 } |
| OLD | NEW |