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 content::RunMessageLoop(); | 78 content::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 |