Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(352)

Side by Side Diff: content/browser/download/download_manager_impl.cc

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

Powered by Google App Engine
This is Rietveld 408576698