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/browser/download/download_manager_impl.h" | 5 #include "content/browser/download/download_manager_impl.h" |
6 | 6 |
7 #include <iterator> | 7 #include <iterator> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
11 #include "base/debug/alias.h" | 11 #include "base/debug/alias.h" |
12 #include "base/file_util.h" | 12 #include "base/file_util.h" |
13 #include "base/i18n/case_conversion.h" | 13 #include "base/i18n/case_conversion.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/message_loop.h" | 15 #include "base/message_loop.h" |
16 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
17 #include "base/stringprintf.h" | 17 #include "base/stringprintf.h" |
18 #include "base/supports_user_data.h" | 18 #include "base/supports_user_data.h" |
19 #include "base/synchronization/lock.h" | 19 #include "base/synchronization/lock.h" |
20 #include "base/sys_string_conversions.h" | 20 #include "base/sys_string_conversions.h" |
21 #include "build/build_config.h" | 21 #include "build/build_config.h" |
22 #include "content/browser/download/byte_stream.h" | 22 #include "content/browser/download/byte_stream.h" |
23 #include "content/browser/download/download_create_info.h" | 23 #include "content/browser/download/download_create_info.h" |
24 #include "content/browser/download/download_file_factory.h" | 24 #include "content/browser/download/download_file_manager.h" |
25 #include "content/browser/download/download_item_impl.h" | 25 #include "content/browser/download/download_item_impl.h" |
26 #include "content/browser/download/download_stats.h" | 26 #include "content/browser/download/download_stats.h" |
27 #include "content/browser/renderer_host/render_view_host_impl.h" | 27 #include "content/browser/renderer_host/render_view_host_impl.h" |
28 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h" | 28 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h" |
29 #include "content/browser/web_contents/web_contents_impl.h" | 29 #include "content/browser/web_contents/web_contents_impl.h" |
30 #include "content/public/browser/browser_context.h" | 30 #include "content/public/browser/browser_context.h" |
31 #include "content/public/browser/browser_thread.h" | 31 #include "content/public/browser/browser_thread.h" |
32 #include "content/public/browser/content_browser_client.h" | 32 #include "content/public/browser/content_browser_client.h" |
33 #include "content/public/browser/download_interrupt_reasons.h" | 33 #include "content/public/browser/download_interrupt_reasons.h" |
34 #include "content/public/browser/download_manager_delegate.h" | 34 #include "content/public/browser/download_manager_delegate.h" |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 | 137 |
138 bool operator!=(const MapValueIteratorAdapter& that) const { | 138 bool operator!=(const MapValueIteratorAdapter& that) const { |
139 return iter_ != that.iter_; | 139 return iter_ != that.iter_; |
140 } | 140 } |
141 | 141 |
142 private: | 142 private: |
143 base::hash_map<int64, DownloadItem*>::const_iterator iter_; | 143 base::hash_map<int64, DownloadItem*>::const_iterator iter_; |
144 // Allow copy and assign. | 144 // Allow copy and assign. |
145 }; | 145 }; |
146 | 146 |
147 void EnsureNoPendingDownloadJobsOnFile(bool* result) { | 147 void EnsureNoPendingDownloadsOnFile(scoped_refptr<DownloadFileManager> dfm, |
148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 148 bool* result) { |
149 *result = (content::DownloadFile::GetNumberOfDownloadFiles() == 0); | 149 if (dfm->NumberOfActiveDownloads()) |
| 150 *result = false; |
150 BrowserThread::PostTask( | 151 BrowserThread::PostTask( |
151 BrowserThread::UI, FROM_HERE, MessageLoop::QuitClosure()); | 152 BrowserThread::UI, FROM_HERE, MessageLoop::QuitClosure()); |
152 } | 153 } |
153 | 154 |
| 155 void EnsureNoPendingDownloadJobsOnIO(bool* result) { |
| 156 scoped_refptr<DownloadFileManager> download_file_manager = |
| 157 ResourceDispatcherHostImpl::Get()->download_file_manager(); |
| 158 BrowserThread::PostTask( |
| 159 BrowserThread::FILE, FROM_HERE, |
| 160 base::Bind(&EnsureNoPendingDownloadsOnFile, |
| 161 download_file_manager, result)); |
| 162 } |
| 163 |
154 class DownloadItemFactoryImpl : public content::DownloadItemFactory { | 164 class DownloadItemFactoryImpl : public content::DownloadItemFactory { |
155 public: | 165 public: |
156 DownloadItemFactoryImpl() {} | 166 DownloadItemFactoryImpl() {} |
157 virtual ~DownloadItemFactoryImpl() {} | 167 virtual ~DownloadItemFactoryImpl() {} |
158 | 168 |
159 virtual DownloadItemImpl* CreatePersistedItem( | 169 virtual DownloadItemImpl* CreatePersistedItem( |
160 DownloadItemImplDelegate* delegate, | 170 DownloadItemImplDelegate* delegate, |
161 content::DownloadId download_id, | 171 content::DownloadId download_id, |
162 const content::DownloadPersistentStoreInfo& info, | 172 const content::DownloadPersistentStoreInfo& info, |
163 const net::BoundNetLog& bound_net_log) OVERRIDE { | 173 const net::BoundNetLog& bound_net_log) OVERRIDE { |
(...skipping 24 matching lines...) Expand all Loading... |
188 }; | 198 }; |
189 | 199 |
190 } // namespace | 200 } // namespace |
191 | 201 |
192 namespace content { | 202 namespace content { |
193 | 203 |
194 bool DownloadManager::EnsureNoPendingDownloadsForTesting() { | 204 bool DownloadManager::EnsureNoPendingDownloadsForTesting() { |
195 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 205 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
196 bool result = true; | 206 bool result = true; |
197 BrowserThread::PostTask( | 207 BrowserThread::PostTask( |
198 BrowserThread::FILE, FROM_HERE, | 208 BrowserThread::IO, FROM_HERE, |
199 base::Bind(&EnsureNoPendingDownloadJobsOnFile, &result)); | 209 base::Bind(&EnsureNoPendingDownloadJobsOnIO, &result)); |
200 MessageLoop::current()->Run(); | 210 MessageLoop::current()->Run(); |
201 return result; | 211 return result; |
202 } | 212 } |
203 | 213 |
204 } // namespace content | 214 } // namespace content |
205 | 215 |
206 DownloadManagerImpl::DownloadManagerImpl( | 216 DownloadManagerImpl::DownloadManagerImpl( |
207 scoped_ptr<content::DownloadItemFactory> item_factory, | 217 DownloadFileManager* file_manager, |
| 218 scoped_ptr<content::DownloadItemFactory> factory, |
208 net::NetLog* net_log) | 219 net::NetLog* net_log) |
209 : item_factory_(item_factory.Pass()), | 220 : factory_(factory.Pass()), |
210 history_size_(0), | 221 history_size_(0), |
211 shutdown_needed_(false), | 222 shutdown_needed_(false), |
212 browser_context_(NULL), | 223 browser_context_(NULL), |
| 224 file_manager_(file_manager), |
213 delegate_(NULL), | 225 delegate_(NULL), |
214 net_log_(net_log) { | 226 net_log_(net_log) { |
215 if (!item_factory_.get()) | 227 DCHECK(file_manager); |
216 item_factory_.reset(new DownloadItemFactoryImpl()); | 228 if (!factory_.get()) |
217 file_factory_.reset(new content::DownloadFileFactory()); | 229 factory_.reset(new DownloadItemFactoryImpl()); |
218 } | 230 } |
219 | 231 |
220 DownloadManagerImpl::~DownloadManagerImpl() { | 232 DownloadManagerImpl::~DownloadManagerImpl() { |
221 DCHECK(!shutdown_needed_); | 233 DCHECK(!shutdown_needed_); |
222 } | 234 } |
223 | 235 |
224 DownloadId DownloadManagerImpl::GetNextId() { | 236 DownloadId DownloadManagerImpl::GetNextId() { |
225 DownloadId id; | 237 DownloadId id; |
226 if (delegate_) | 238 if (delegate_) |
227 id = delegate_->GetNextId(); | 239 id = delegate_->GetNextId(); |
228 if (!id.IsValid()) { | 240 if (!id.IsValid()) { |
229 static int next_id; | 241 static int next_id; |
230 id = DownloadId(browser_context_, ++next_id); | 242 id = DownloadId(browser_context_, ++next_id); |
231 } | 243 } |
232 | 244 |
233 return id; | 245 return id; |
234 } | 246 } |
235 | 247 |
236 void DownloadManagerImpl::DelegateStart(DownloadItemImpl* item) { | 248 DownloadFileManager* DownloadManagerImpl::GetDownloadFileManager() { |
237 content::DownloadTargetCallback callback = | 249 return file_manager_; |
238 base::Bind(&DownloadManagerImpl::OnDownloadTargetDetermined, | |
239 this, item->GetId()); | |
240 if (!delegate_ || !delegate_->DetermineDownloadTarget(item, callback)) { | |
241 FilePath target_path = item->GetForcedFilePath(); | |
242 // TODO(asanka): Determine a useful path if |target_path| is empty. | |
243 callback.Run(target_path, | |
244 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
245 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
246 target_path); | |
247 } | |
248 } | 250 } |
249 | 251 |
250 bool DownloadManagerImpl::ShouldOpenDownload(DownloadItemImpl* item) { | 252 bool DownloadManagerImpl::ShouldOpenDownload(DownloadItemImpl* item) { |
251 if (!delegate_) | 253 if (!delegate_) |
252 return true; | 254 return true; |
253 | 255 |
254 return delegate_->ShouldOpenDownload(item); | 256 return delegate_->ShouldOpenDownload(item); |
255 } | 257 } |
256 | 258 |
257 bool DownloadManagerImpl::ShouldOpenFileBasedOnExtension(const FilePath& path) { | 259 bool DownloadManagerImpl::ShouldOpenFileBasedOnExtension(const FilePath& path) { |
(...skipping 15 matching lines...) Expand all Loading... |
273 void DownloadManagerImpl::Shutdown() { | 275 void DownloadManagerImpl::Shutdown() { |
274 VLOG(20) << __FUNCTION__ << "()" | 276 VLOG(20) << __FUNCTION__ << "()" |
275 << " shutdown_needed_ = " << shutdown_needed_; | 277 << " shutdown_needed_ = " << shutdown_needed_; |
276 if (!shutdown_needed_) | 278 if (!shutdown_needed_) |
277 return; | 279 return; |
278 shutdown_needed_ = false; | 280 shutdown_needed_ = false; |
279 | 281 |
280 FOR_EACH_OBSERVER(Observer, observers_, ManagerGoingDown(this)); | 282 FOR_EACH_OBSERVER(Observer, observers_, ManagerGoingDown(this)); |
281 // TODO(benjhayden): Consider clearing observers_. | 283 // TODO(benjhayden): Consider clearing observers_. |
282 | 284 |
283 // The DownloadFiles will be canceled and deleted by their DownloadItems. | 285 DCHECK(file_manager_); |
| 286 BrowserThread::PostTask( |
| 287 BrowserThread::FILE, FROM_HERE, |
| 288 base::Bind(&DownloadFileManager::OnDownloadManagerShutdown, |
| 289 file_manager_, make_scoped_refptr(this))); |
284 | 290 |
285 AssertContainersConsistent(); | 291 AssertContainersConsistent(); |
286 | 292 |
287 // Go through all downloads in downloads_. Dangerous ones we need to | 293 // Go through all downloads in downloads_. Dangerous ones we need to |
288 // remove on disk, and in progress ones we need to cancel. | 294 // remove on disk, and in progress ones we need to cancel. |
289 for (DownloadMap::iterator it = downloads_.begin(); it != downloads_.end();) { | 295 for (DownloadMap::iterator it = downloads_.begin(); it != downloads_.end();) { |
290 DownloadItemImpl* download = it->second; | 296 DownloadItemImpl* download = it->second; |
291 | 297 |
292 // Save iterator from potential erases in this set done by called code. | 298 // Save iterator from potential erases in this set done by called code. |
293 // Iterators after an erasure point are still valid for lists and | 299 // Iterators after an erasure point are still valid for lists and |
(...skipping 22 matching lines...) Expand all Loading... |
316 // and all in progress downloads have been cancelled. We can now delete | 322 // and all in progress downloads have been cancelled. We can now delete |
317 // anything left. | 323 // anything left. |
318 | 324 |
319 active_downloads_.clear(); | 325 active_downloads_.clear(); |
320 STLDeleteValues(&downloads_); | 326 STLDeleteValues(&downloads_); |
321 downloads_.clear(); | 327 downloads_.clear(); |
322 | 328 |
323 // We'll have nothing more to report to the observers after this point. | 329 // We'll have nothing more to report to the observers after this point. |
324 observers_.Clear(); | 330 observers_.Clear(); |
325 | 331 |
| 332 file_manager_ = NULL; |
326 if (delegate_) | 333 if (delegate_) |
327 delegate_->Shutdown(); | 334 delegate_->Shutdown(); |
328 delegate_ = NULL; | 335 delegate_ = NULL; |
329 } | 336 } |
330 | 337 |
331 void DownloadManagerImpl::GetTemporaryDownloads( | 338 void DownloadManagerImpl::GetTemporaryDownloads( |
332 const FilePath& dir_path, DownloadVector* result) { | 339 const FilePath& dir_path, DownloadVector* result) { |
333 DCHECK(result); | 340 DCHECK(result); |
334 | 341 |
335 for (DownloadMap::iterator it = downloads_.begin(); | 342 for (DownloadMap::iterator it = downloads_.begin(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 bool DownloadManagerImpl::Init(content::BrowserContext* browser_context) { | 390 bool DownloadManagerImpl::Init(content::BrowserContext* browser_context) { |
384 DCHECK(browser_context); | 391 DCHECK(browser_context); |
385 DCHECK(!shutdown_needed_) << "DownloadManager already initialized."; | 392 DCHECK(!shutdown_needed_) << "DownloadManager already initialized."; |
386 shutdown_needed_ = true; | 393 shutdown_needed_ = true; |
387 | 394 |
388 browser_context_ = browser_context; | 395 browser_context_ = browser_context; |
389 | 396 |
390 return true; | 397 return true; |
391 } | 398 } |
392 | 399 |
| 400 // We have received a message from DownloadFileManager about a new download. |
393 content::DownloadId DownloadManagerImpl::StartDownload( | 401 content::DownloadId DownloadManagerImpl::StartDownload( |
394 scoped_ptr<DownloadCreateInfo> info, | 402 scoped_ptr<DownloadCreateInfo> info, |
395 scoped_ptr<content::ByteStreamReader> stream) { | 403 scoped_ptr<content::ByteStreamReader> stream) { |
396 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 404 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
397 | 405 |
398 net::BoundNetLog bound_net_log = | 406 // |bound_net_log| will be used for logging both the download item's and |
399 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); | 407 // the download file's events. |
| 408 net::BoundNetLog bound_net_log = CreateDownloadItem(info.get()); |
400 | 409 |
401 // We create the DownloadItem before the DownloadFile because the | 410 // If info->download_id was unknown on entry to this function, it was |
402 // DownloadItem already needs to handle a state in which there is | 411 // assigned in CreateDownloadItem. |
403 // no associated DownloadFile (history downloads, !IN_PROGRESS downloads) | 412 DownloadId download_id = info->download_id; |
404 DownloadItemImpl* download = | |
405 CreateDownloadItem(info.get(), bound_net_log); | |
406 scoped_ptr<content::DownloadFile> download_file( | |
407 file_factory_->CreateFile( | |
408 info->save_info, info->url(), info->referrer_url, | |
409 info->received_bytes, GenerateFileHash(), | |
410 stream.Pass(), bound_net_log, | |
411 download->DestinationObserverAsWeakPtr())); | |
412 download->Start(download_file.Pass()); | |
413 | 413 |
414 return download->GetGlobalId(); | 414 DownloadFileManager::CreateDownloadFileCallback callback( |
| 415 base::Bind(&DownloadManagerImpl::OnDownloadFileCreated, |
| 416 this, download_id.local())); |
| 417 |
| 418 BrowserThread::PostTask( |
| 419 BrowserThread::FILE, FROM_HERE, |
| 420 base::Bind(&DownloadFileManager::CreateDownloadFile, |
| 421 file_manager_, base::Passed(info.Pass()), |
| 422 base::Passed(stream.Pass()), |
| 423 make_scoped_refptr(this), |
| 424 GenerateFileHash(), bound_net_log, |
| 425 callback)); |
| 426 |
| 427 return download_id; |
| 428 } |
| 429 |
| 430 void DownloadManagerImpl::OnDownloadFileCreated( |
| 431 int32 download_id, content::DownloadInterruptReason reason) { |
| 432 if (reason != content::DOWNLOAD_INTERRUPT_REASON_NONE) { |
| 433 OnDownloadInterrupted(download_id, reason); |
| 434 // TODO(rdsmith): It makes no sense to continue along the |
| 435 // regular download path after we've gotten an error. But it's |
| 436 // the way the code has historically worked, and this allows us |
| 437 // to get the download persisted and observers of the download manager |
| 438 // notified, so tests work. When we execute all side effects of cancel |
| 439 // (including queue removal) immedately rather than waiting for |
| 440 // persistence we should replace this comment with a "return;". |
| 441 } |
| 442 |
| 443 DownloadMap::iterator download_iter = active_downloads_.find(download_id); |
| 444 if (download_iter == active_downloads_.end()) |
| 445 return; |
| 446 |
| 447 DownloadItemImpl* download = download_iter->second; |
| 448 content::DownloadTargetCallback callback = |
| 449 base::Bind(&DownloadManagerImpl::OnDownloadTargetDetermined, |
| 450 this, download_id); |
| 451 if (!delegate_ || !delegate_->DetermineDownloadTarget(download, callback)) { |
| 452 FilePath target_path = download->GetForcedFilePath(); |
| 453 // TODO(asanka): Determine a useful path if |target_path| is empty. |
| 454 callback.Run(target_path, |
| 455 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 456 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
| 457 target_path); |
| 458 } |
415 } | 459 } |
416 | 460 |
417 void DownloadManagerImpl::OnDownloadTargetDetermined( | 461 void DownloadManagerImpl::OnDownloadTargetDetermined( |
418 int32 download_id, | 462 int32 download_id, |
419 const FilePath& target_path, | 463 const FilePath& target_path, |
420 DownloadItem::TargetDisposition disposition, | 464 DownloadItem::TargetDisposition disposition, |
421 content::DownloadDangerType danger_type, | 465 content::DownloadDangerType danger_type, |
422 const FilePath& intermediate_path) { | 466 const FilePath& intermediate_path) { |
423 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 467 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
424 DownloadMap::iterator download_iter = active_downloads_.find(download_id); | 468 DownloadMap::iterator download_iter = active_downloads_.find(download_id); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
468 void DownloadManagerImpl::OnFileRemovalDetected(int32 download_id) { | 512 void DownloadManagerImpl::OnFileRemovalDetected(int32 download_id) { |
469 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 513 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
470 if (ContainsKey(downloads_, download_id)) | 514 if (ContainsKey(downloads_, download_id)) |
471 downloads_[download_id]->OnDownloadedFileRemoved(); | 515 downloads_[download_id]->OnDownloadedFileRemoved(); |
472 } | 516 } |
473 | 517 |
474 content::BrowserContext* DownloadManagerImpl::GetBrowserContext() const { | 518 content::BrowserContext* DownloadManagerImpl::GetBrowserContext() const { |
475 return browser_context_; | 519 return browser_context_; |
476 } | 520 } |
477 | 521 |
478 DownloadItemImpl* DownloadManagerImpl::CreateDownloadItem( | 522 net::BoundNetLog DownloadManagerImpl::CreateDownloadItem( |
479 DownloadCreateInfo* info, const net::BoundNetLog& bound_net_log) { | 523 DownloadCreateInfo* info) { |
480 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 524 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
481 | 525 |
| 526 net::BoundNetLog bound_net_log = |
| 527 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); |
482 if (!info->download_id.IsValid()) | 528 if (!info->download_id.IsValid()) |
483 info->download_id = GetNextId(); | 529 info->download_id = GetNextId(); |
484 DownloadItemImpl* download = item_factory_->CreateActiveItem( | 530 DownloadItemImpl* download = factory_->CreateActiveItem( |
485 this, *info, | 531 this, *info, |
486 scoped_ptr<DownloadRequestHandleInterface>( | 532 scoped_ptr<DownloadRequestHandleInterface>( |
487 new DownloadRequestHandle(info->request_handle)).Pass(), | 533 new DownloadRequestHandle(info->request_handle)).Pass(), |
488 browser_context_->IsOffTheRecord(), bound_net_log); | 534 browser_context_->IsOffTheRecord(), bound_net_log); |
489 | 535 |
490 DCHECK(!ContainsKey(downloads_, download->GetId())); | 536 DCHECK(!ContainsKey(downloads_, download->GetId())); |
491 downloads_[download->GetId()] = download; | 537 downloads_[download->GetId()] = download; |
492 DCHECK(!ContainsKey(active_downloads_, download->GetId())); | 538 DCHECK(!ContainsKey(active_downloads_, download->GetId())); |
493 active_downloads_[download->GetId()] = download; | 539 active_downloads_[download->GetId()] = download; |
494 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); | 540 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); |
495 | 541 |
496 return download; | 542 return bound_net_log; |
497 } | 543 } |
498 | 544 |
499 DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem( | 545 DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem( |
500 const FilePath& main_file_path, | 546 const FilePath& main_file_path, |
501 const GURL& page_url, | 547 const GURL& page_url, |
502 bool is_otr, | 548 bool is_otr, |
503 const std::string& mime_type, | 549 const std::string& mime_type, |
504 DownloadItem::Observer* observer) { | 550 DownloadItem::Observer* observer) { |
505 net::BoundNetLog bound_net_log = | 551 net::BoundNetLog bound_net_log = |
506 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); | 552 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); |
507 DownloadItemImpl* download = item_factory_->CreateSavePageItem( | 553 DownloadItemImpl* download = factory_->CreateSavePageItem( |
508 this, | 554 this, |
509 main_file_path, | 555 main_file_path, |
510 page_url, | 556 page_url, |
511 is_otr, | 557 is_otr, |
512 GetNextId(), | 558 GetNextId(), |
513 mime_type, | 559 mime_type, |
514 bound_net_log); | 560 bound_net_log); |
515 | 561 |
516 download->AddObserver(observer); | 562 download->AddObserver(observer); |
517 | 563 |
518 DCHECK(!ContainsKey(downloads_, download->GetId())); | 564 DCHECK(!ContainsKey(downloads_, download->GetId())); |
519 downloads_[download->GetId()] = download; | 565 downloads_[download->GetId()] = download; |
520 DCHECK(!SavePageData::Get(download)); | 566 DCHECK(!SavePageData::Get(download)); |
521 new SavePageData(download); | 567 new SavePageData(download); |
522 DCHECK(SavePageData::Get(download)); | 568 DCHECK(SavePageData::Get(download)); |
523 | 569 |
524 // TODO(benjhayden): Fire OnDownloadCreated for SavePackage downloads when | 570 // TODO(benjhayden): Fire OnDownloadCreated for SavePackage downloads when |
525 // we're comfortable with the user interacting with them. | 571 // we're comfortable with the user interacting with them. |
526 // FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); | 572 // FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); |
527 | 573 |
528 // Will notify the observer in the callback. | 574 // Will notify the observer in the callback. |
529 if (delegate_) | 575 if (delegate_) |
530 delegate_->AddItemToPersistentStore(download); | 576 delegate_->AddItemToPersistentStore(download); |
531 | 577 |
532 return download; | 578 return download; |
533 } | 579 } |
534 | 580 |
| 581 void DownloadManagerImpl::UpdateDownload(int32 download_id, |
| 582 int64 bytes_so_far, |
| 583 int64 bytes_per_sec, |
| 584 const std::string& hash_state) { |
| 585 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 586 DownloadMap::iterator it = active_downloads_.find(download_id); |
| 587 if (it != active_downloads_.end()) { |
| 588 DownloadItemImpl* download = it->second; |
| 589 if (download->IsInProgress()) { |
| 590 download->UpdateProgress(bytes_so_far, bytes_per_sec, hash_state); |
| 591 if (delegate_) |
| 592 delegate_->UpdateItemInPersistentStore(download); |
| 593 } |
| 594 } |
| 595 } |
| 596 |
| 597 void DownloadManagerImpl::OnResponseCompleted(int32 download_id, |
| 598 int64 size, |
| 599 const std::string& hash) { |
| 600 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 601 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id |
| 602 << " size = " << size; |
| 603 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 604 |
| 605 // If it's not in active_downloads_, that means it was cancelled; just |
| 606 // ignore the notification. |
| 607 if (active_downloads_.count(download_id) == 0) |
| 608 return; |
| 609 |
| 610 DownloadItemImpl* download = active_downloads_[download_id]; |
| 611 download->OnAllDataSaved(size, hash); |
| 612 MaybeCompleteDownload(download); |
| 613 } |
| 614 |
535 void DownloadManagerImpl::AssertStateConsistent( | 615 void DownloadManagerImpl::AssertStateConsistent( |
536 DownloadItemImpl* download) const { | 616 DownloadItemImpl* download) const { |
537 CHECK(ContainsKey(downloads_, download->GetId())); | 617 CHECK(ContainsKey(downloads_, download->GetId())); |
538 | 618 |
539 int64 state = download->GetState(); | 619 int64 state = download->GetState(); |
540 base::debug::Alias(&state); | 620 base::debug::Alias(&state); |
541 if (ContainsKey(active_downloads_, download->GetId())) { | 621 if (ContainsKey(active_downloads_, download->GetId())) { |
542 if (download->IsPersisted()) | 622 if (download->IsPersisted()) |
543 CHECK_EQ(DownloadItem::IN_PROGRESS, download->GetState()); | 623 CHECK_EQ(DownloadItem::IN_PROGRESS, download->GetState()); |
544 if (DownloadItem::IN_PROGRESS != download->GetState()) | 624 if (DownloadItem::IN_PROGRESS != download->GetState()) |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
646 void DownloadManagerImpl::DownloadStopped(DownloadItemImpl* download) { | 726 void DownloadManagerImpl::DownloadStopped(DownloadItemImpl* download) { |
647 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 727 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
648 | 728 |
649 VLOG(20) << __FUNCTION__ << "()" | 729 VLOG(20) << __FUNCTION__ << "()" |
650 << " download = " << download->DebugString(true); | 730 << " download = " << download->DebugString(true); |
651 | 731 |
652 RemoveFromActiveList(download); | 732 RemoveFromActiveList(download); |
653 // This function is called from the DownloadItem, so DI state | 733 // This function is called from the DownloadItem, so DI state |
654 // should already have been updated. | 734 // should already have been updated. |
655 AssertStateConsistent(download); | 735 AssertStateConsistent(download); |
| 736 |
| 737 DCHECK(file_manager_); |
| 738 download->OffThreadCancel(); |
| 739 } |
| 740 |
| 741 void DownloadManagerImpl::OnDownloadInterrupted( |
| 742 int32 download_id, |
| 743 content::DownloadInterruptReason reason) { |
| 744 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 745 |
| 746 if (!ContainsKey(active_downloads_, download_id)) |
| 747 return; |
| 748 active_downloads_[download_id]->Interrupt(reason); |
656 } | 749 } |
657 | 750 |
658 void DownloadManagerImpl::RemoveFromActiveList(DownloadItemImpl* download) { | 751 void DownloadManagerImpl::RemoveFromActiveList(DownloadItemImpl* download) { |
659 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 752 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
660 DCHECK(download); | 753 DCHECK(download); |
661 | 754 |
662 // Clean up will happen when the history system create callback runs if we | 755 // Clean up will happen when the history system create callback runs if we |
663 // don't have a valid db_handle yet. | 756 // don't have a valid db_handle yet. |
664 if (download->IsPersisted()) { | 757 if (download->IsPersisted()) { |
665 active_downloads_.erase(download->GetId()); | 758 active_downloads_.erase(download->GetId()); |
666 if (delegate_) | 759 if (delegate_) |
667 delegate_->UpdateItemInPersistentStore(download); | 760 delegate_->UpdateItemInPersistentStore(download); |
668 } | 761 } |
669 } | 762 } |
670 | 763 |
671 bool DownloadManagerImpl::GenerateFileHash() { | 764 bool DownloadManagerImpl::GenerateFileHash() { |
672 return delegate_ && delegate_->GenerateFileHash(); | 765 return delegate_ && delegate_->GenerateFileHash(); |
673 } | 766 } |
674 | 767 |
675 void DownloadManagerImpl::SetDownloadFileFactoryForTesting( | |
676 scoped_ptr<content::DownloadFileFactory> file_factory) { | |
677 file_factory_ = file_factory.Pass(); | |
678 } | |
679 | |
680 content::DownloadFileFactory* | |
681 DownloadManagerImpl::GetDownloadFileFactoryForTesting() { | |
682 return file_factory_.get(); | |
683 } | |
684 | |
685 int DownloadManagerImpl::RemoveDownloadItems( | 768 int DownloadManagerImpl::RemoveDownloadItems( |
686 const DownloadItemImplVector& pending_deletes) { | 769 const DownloadItemImplVector& pending_deletes) { |
687 if (pending_deletes.empty()) | 770 if (pending_deletes.empty()) |
688 return 0; | 771 return 0; |
689 | 772 |
690 // Delete from internal maps. | 773 // Delete from internal maps. |
691 for (DownloadItemImplVector::const_iterator it = pending_deletes.begin(); | 774 for (DownloadItemImplVector::const_iterator it = pending_deletes.begin(); |
692 it != pending_deletes.end(); | 775 it != pending_deletes.end(); |
693 ++it) { | 776 ++it) { |
694 DownloadItemImpl* download = *it; | 777 DownloadItemImpl* download = *it; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
782 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). | 865 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). |
783 void DownloadManagerImpl::OnPersistentStoreQueryComplete( | 866 void DownloadManagerImpl::OnPersistentStoreQueryComplete( |
784 std::vector<DownloadPersistentStoreInfo>* entries) { | 867 std::vector<DownloadPersistentStoreInfo>* entries) { |
785 history_size_ = entries->size(); | 868 history_size_ = entries->size(); |
786 for (size_t i = 0; i < entries->size(); ++i) { | 869 for (size_t i = 0; i < entries->size(); ++i) { |
787 int64 db_handle = entries->at(i).db_handle; | 870 int64 db_handle = entries->at(i).db_handle; |
788 base::debug::Alias(&db_handle); | 871 base::debug::Alias(&db_handle); |
789 | 872 |
790 net::BoundNetLog bound_net_log = | 873 net::BoundNetLog bound_net_log = |
791 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); | 874 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); |
792 DownloadItemImpl* download = item_factory_->CreatePersistedItem( | 875 DownloadItemImpl* download = factory_->CreatePersistedItem( |
793 this, GetNextId(), entries->at(i), bound_net_log); | 876 this, GetNextId(), entries->at(i), bound_net_log); |
794 DCHECK(!ContainsKey(downloads_, download->GetId())); | 877 DCHECK(!ContainsKey(downloads_, download->GetId())); |
795 downloads_[download->GetId()] = download; | 878 downloads_[download->GetId()] = download; |
796 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); | 879 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); |
797 VLOG(20) << __FUNCTION__ << "()" << i << ">" | 880 VLOG(20) << __FUNCTION__ << "()" << i << ">" |
798 << " download = " << download->DebugString(true); | 881 << " download = " << download->DebugString(true); |
799 } | 882 } |
800 NotifyModelChanged(); | 883 NotifyModelChanged(); |
801 CheckForHistoryFilesRemoval(); | 884 CheckForHistoryFilesRemoval(); |
802 } | 885 } |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
997 ++num_unopened; | 1080 ++num_unopened; |
998 } | 1081 } |
999 download_stats::RecordOpensOutstanding(num_unopened); | 1082 download_stats::RecordOpensOutstanding(num_unopened); |
1000 } | 1083 } |
1001 | 1084 |
1002 void DownloadManagerImpl::DownloadRenamedToIntermediateName( | 1085 void DownloadManagerImpl::DownloadRenamedToIntermediateName( |
1003 DownloadItemImpl* download) { | 1086 DownloadItemImpl* download) { |
1004 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1087 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1005 // download->GetFullPath() is only expected to be meaningful after this | 1088 // download->GetFullPath() is only expected to be meaningful after this |
1006 // callback is received. Therefore we can now add the download to a persistent | 1089 // callback is received. Therefore we can now add the download to a persistent |
1007 // store. If the rename failed, we processed an interrupt | 1090 // store. If the rename failed, we receive an OnDownloadInterrupted() call |
1008 // before we receive the DownloadRenamedToIntermediateName() call. | 1091 // before we receive the DownloadRenamedToIntermediateName() call. |
1009 if (delegate_) { | 1092 if (delegate_) { |
1010 delegate_->AddItemToPersistentStore(download); | 1093 delegate_->AddItemToPersistentStore(download); |
1011 } else { | 1094 } else { |
1012 OnItemAddedToPersistentStore(download->GetId(), | 1095 OnItemAddedToPersistentStore(download->GetId(), |
1013 DownloadItem::kUninitializedHandle); | 1096 DownloadItem::kUninitializedHandle); |
1014 } | 1097 } |
1015 } | 1098 } |
1016 | 1099 |
1017 void DownloadManagerImpl::DownloadRenamedToFinalName( | 1100 void DownloadManagerImpl::DownloadRenamedToFinalName( |
1018 DownloadItemImpl* download) { | 1101 DownloadItemImpl* download) { |
1019 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1102 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1020 // If the rename failed, we processed an interrupt before we get here. | 1103 // If the rename failed, we receive an OnDownloadInterrupted() call before we |
| 1104 // receive the DownloadRenamedToFinalName() call. |
1021 if (delegate_) { | 1105 if (delegate_) { |
1022 delegate_->UpdatePathForItemInPersistentStore( | 1106 delegate_->UpdatePathForItemInPersistentStore( |
1023 download, download->GetFullPath()); | 1107 download, download->GetFullPath()); |
1024 } | 1108 } |
1025 } | 1109 } |
OLD | NEW |