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" |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 | 129 |
130 void EnsureNoPendingDownloadJobsOnIO(bool* result) { | 130 void EnsureNoPendingDownloadJobsOnIO(bool* result) { |
131 scoped_refptr<DownloadFileManager> download_file_manager = | 131 scoped_refptr<DownloadFileManager> download_file_manager = |
132 ResourceDispatcherHostImpl::Get()->download_file_manager(); | 132 ResourceDispatcherHostImpl::Get()->download_file_manager(); |
133 BrowserThread::PostTask( | 133 BrowserThread::PostTask( |
134 BrowserThread::FILE, FROM_HERE, | 134 BrowserThread::FILE, FROM_HERE, |
135 base::Bind(&EnsureNoPendingDownloadsOnFile, | 135 base::Bind(&EnsureNoPendingDownloadsOnFile, |
136 download_file_manager, result)); | 136 download_file_manager, result)); |
137 } | 137 } |
138 | 138 |
| 139 class DownloadItemFactoryImpl : public content::DownloadItemFactory { |
| 140 public: |
| 141 DownloadItemFactoryImpl() {} |
| 142 virtual ~DownloadItemFactoryImpl() {} |
| 143 |
| 144 virtual content::DownloadItem* CreatePersistedItem( |
| 145 DownloadItemImpl::Delegate* delegate, |
| 146 content::DownloadId download_id, |
| 147 const content::DownloadPersistentStoreInfo& info, |
| 148 const net::BoundNetLog& bound_net_log) OVERRIDE { |
| 149 return new DownloadItemImpl(delegate, download_id, info, bound_net_log); |
| 150 } |
| 151 |
| 152 virtual content::DownloadItem* CreateActiveItem( |
| 153 DownloadItemImpl::Delegate* delegate, |
| 154 const DownloadCreateInfo& info, |
| 155 DownloadRequestHandleInterface* request_handle, |
| 156 bool is_otr, |
| 157 const net::BoundNetLog& bound_net_log) OVERRIDE { |
| 158 return new DownloadItemImpl(delegate, info, request_handle, is_otr, |
| 159 bound_net_log); |
| 160 } |
| 161 |
| 162 virtual content::DownloadItem* CreateSavePageItem( |
| 163 DownloadItemImpl::Delegate* delegate, |
| 164 const FilePath& path, |
| 165 const GURL& url, |
| 166 bool is_otr, |
| 167 content::DownloadId download_id, |
| 168 const std::string& mime_type, |
| 169 const net::BoundNetLog& bound_net_log) OVERRIDE { |
| 170 return new DownloadItemImpl(delegate, path, url, is_otr, download_id, |
| 171 mime_type, bound_net_log); |
| 172 } |
| 173 }; |
| 174 |
139 } // namespace | 175 } // namespace |
140 | 176 |
141 namespace content { | 177 namespace content { |
142 | 178 |
143 bool DownloadManager::EnsureNoPendingDownloadsForTesting() { | 179 bool DownloadManager::EnsureNoPendingDownloadsForTesting() { |
144 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 180 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
145 bool result = true; | 181 bool result = true; |
146 BrowserThread::PostTask( | 182 BrowserThread::PostTask( |
147 BrowserThread::IO, FROM_HERE, | 183 BrowserThread::IO, FROM_HERE, |
148 base::Bind(&EnsureNoPendingDownloadJobsOnIO, &result)); | 184 base::Bind(&EnsureNoPendingDownloadJobsOnIO, &result)); |
149 MessageLoop::current()->Run(); | 185 MessageLoop::current()->Run(); |
150 return result; | 186 return result; |
151 } | 187 } |
152 | 188 |
153 } // namespace content | 189 } // namespace content |
154 | 190 |
155 DownloadManagerImpl::DownloadManagerImpl(net::NetLog* net_log) | 191 DownloadManagerImpl::DownloadManagerImpl( |
156 : shutdown_needed_(false), | 192 DownloadFileManager* file_manager, |
| 193 scoped_ptr<content::DownloadItemFactory> factory, |
| 194 net::NetLog* net_log) |
| 195 : factory_(factory.Pass()), |
| 196 shutdown_needed_(false), |
157 browser_context_(NULL), | 197 browser_context_(NULL), |
158 file_manager_(NULL), | 198 file_manager_(file_manager), |
159 delegate_(NULL), | |
160 net_log_(net_log) { | 199 net_log_(net_log) { |
| 200 DCHECK(file_manager); |
| 201 if (!factory_.get()) |
| 202 factory_.reset(new DownloadItemFactoryImpl()); |
161 } | 203 } |
162 | 204 |
163 DownloadManagerImpl::~DownloadManagerImpl() { | 205 DownloadManagerImpl::~DownloadManagerImpl() { |
164 DCHECK(!shutdown_needed_); | 206 DCHECK(!shutdown_needed_); |
165 } | 207 } |
166 | 208 |
167 DownloadId DownloadManagerImpl::GetNextId() { | 209 DownloadId DownloadManagerImpl::GetNextId() { |
168 DownloadId id; | 210 DownloadId id; |
169 if (delegate_) | 211 if (delegate_) |
170 id = delegate_->GetNextId(); | 212 id = delegate_->GetNextId(); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 void DownloadManagerImpl::Shutdown() { | 244 void DownloadManagerImpl::Shutdown() { |
203 VLOG(20) << __FUNCTION__ << "()" | 245 VLOG(20) << __FUNCTION__ << "()" |
204 << " shutdown_needed_ = " << shutdown_needed_; | 246 << " shutdown_needed_ = " << shutdown_needed_; |
205 if (!shutdown_needed_) | 247 if (!shutdown_needed_) |
206 return; | 248 return; |
207 shutdown_needed_ = false; | 249 shutdown_needed_ = false; |
208 | 250 |
209 FOR_EACH_OBSERVER(Observer, observers_, ManagerGoingDown(this)); | 251 FOR_EACH_OBSERVER(Observer, observers_, ManagerGoingDown(this)); |
210 // TODO(benjhayden): Consider clearing observers_. | 252 // TODO(benjhayden): Consider clearing observers_. |
211 | 253 |
212 if (file_manager_) { | 254 DCHECK(file_manager_); |
213 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 255 BrowserThread::PostTask( |
214 base::Bind(&DownloadFileManager::OnDownloadManagerShutdown, | 256 BrowserThread::FILE, FROM_HERE, |
215 file_manager_, make_scoped_refptr(this))); | 257 base::Bind(&DownloadFileManager::OnDownloadManagerShutdown, |
216 } | 258 file_manager_, make_scoped_refptr(this))); |
217 | 259 |
218 AssertContainersConsistent(); | 260 AssertContainersConsistent(); |
219 | 261 |
220 // Go through all downloads in downloads_. Dangerous ones we need to | 262 // Go through all downloads in downloads_. Dangerous ones we need to |
221 // remove on disk, and in progress ones we need to cancel. | 263 // remove on disk, and in progress ones we need to cancel. |
222 for (DownloadSet::iterator it = downloads_.begin(); it != downloads_.end();) { | 264 for (DownloadSet::iterator it = downloads_.begin(); it != downloads_.end();) { |
223 DownloadItem* download = *it; | 265 DownloadItem* download = *it; |
224 | 266 |
225 // Save iterator from potential erases in this set done by called code. | 267 // Save iterator from potential erases in this set done by called code. |
226 // Iterators after an erasure point are still valid for lists and | 268 // Iterators after an erasure point are still valid for lists and |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 // The Incognito Downloads page will get the list of non-Incognito downloads | 351 // The Incognito Downloads page will get the list of non-Incognito downloads |
310 // from its parent profile. | 352 // from its parent profile. |
311 if (browser_context_->IsOffTheRecord() != download_item->IsOtr()) | 353 if (browser_context_->IsOffTheRecord() != download_item->IsOtr()) |
312 continue; | 354 continue; |
313 | 355 |
314 if (download_item->MatchesQuery(query_lower)) | 356 if (download_item->MatchesQuery(query_lower)) |
315 result->push_back(download_item); | 357 result->push_back(download_item); |
316 } | 358 } |
317 } | 359 } |
318 | 360 |
319 // Query the history service for information about all persisted downloads. | |
320 bool DownloadManagerImpl::Init(content::BrowserContext* browser_context) { | 361 bool DownloadManagerImpl::Init(content::BrowserContext* browser_context) { |
321 DCHECK(browser_context); | 362 DCHECK(browser_context); |
322 DCHECK(!shutdown_needed_) << "DownloadManager already initialized."; | 363 DCHECK(!shutdown_needed_) << "DownloadManager already initialized."; |
323 shutdown_needed_ = true; | 364 shutdown_needed_ = true; |
324 | 365 |
325 browser_context_ = browser_context; | 366 browser_context_ = browser_context; |
326 | 367 |
327 // In test mode, there may be no ResourceDispatcherHostImpl. In this case | |
328 // it's safe to avoid setting |file_manager_| because we only call a small | |
329 // set of functions, none of which need it. | |
330 ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get(); | |
331 if (rdh) { | |
332 file_manager_ = rdh->download_file_manager(); | |
333 DCHECK(file_manager_); | |
334 } | |
335 | |
336 return true; | 368 return true; |
337 } | 369 } |
338 | 370 |
339 // We have received a message from DownloadFileManager about a new download. | 371 // We have received a message from DownloadFileManager about a new download. |
340 void DownloadManagerImpl::StartDownload(int32 download_id) { | 372 void DownloadManagerImpl::StartDownload(int32 download_id) { |
341 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 373 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
342 | 374 |
343 if (!delegate_ || delegate_->ShouldStartDownload(download_id)) | 375 if (!delegate_ || delegate_->ShouldStartDownload(download_id)) |
344 RestartDownload(download_id); | 376 RestartDownload(download_id); |
345 } | 377 } |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 FilePath DownloadManagerImpl::LastDownloadPath() { | 450 FilePath DownloadManagerImpl::LastDownloadPath() { |
419 return last_download_path_; | 451 return last_download_path_; |
420 } | 452 } |
421 | 453 |
422 net::BoundNetLog DownloadManagerImpl::CreateDownloadItem( | 454 net::BoundNetLog DownloadManagerImpl::CreateDownloadItem( |
423 DownloadCreateInfo* info, const DownloadRequestHandle& request_handle) { | 455 DownloadCreateInfo* info, const DownloadRequestHandle& request_handle) { |
424 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 456 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
425 | 457 |
426 net::BoundNetLog bound_net_log = | 458 net::BoundNetLog bound_net_log = |
427 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); | 459 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); |
428 info->download_id = GetNextId(); | 460 if (!info->download_id.IsValid()) |
429 DownloadItem* download = new DownloadItemImpl( | 461 info->download_id = GetNextId(); |
| 462 DownloadItem* download = factory_->CreateActiveItem( |
430 this, *info, new DownloadRequestHandle(request_handle), | 463 this, *info, new DownloadRequestHandle(request_handle), |
431 browser_context_->IsOffTheRecord(), bound_net_log); | 464 browser_context_->IsOffTheRecord(), bound_net_log); |
432 int32 download_id = info->download_id.local(); | 465 int32 download_id = info->download_id.local(); |
433 | 466 |
434 DCHECK(!ContainsKey(active_downloads_, download_id)); | 467 DCHECK(!ContainsKey(active_downloads_, download_id)); |
435 downloads_.insert(download); | 468 downloads_.insert(download); |
436 active_downloads_[download_id] = download; | 469 active_downloads_[download_id] = download; |
437 | 470 |
438 return bound_net_log; | 471 return bound_net_log; |
439 } | 472 } |
440 | 473 |
441 DownloadItem* DownloadManagerImpl::CreateSavePackageDownloadItem( | 474 DownloadItem* DownloadManagerImpl::CreateSavePackageDownloadItem( |
442 const FilePath& main_file_path, | 475 const FilePath& main_file_path, |
443 const GURL& page_url, | 476 const GURL& page_url, |
444 bool is_otr, | 477 bool is_otr, |
445 const std::string& mime_type, | 478 const std::string& mime_type, |
446 DownloadItem::Observer* observer) { | 479 DownloadItem::Observer* observer) { |
447 net::BoundNetLog bound_net_log = | 480 net::BoundNetLog bound_net_log = |
448 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); | 481 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); |
449 DownloadItem* download = new DownloadItemImpl( | 482 DownloadItem* download = factory_->CreateSavePageItem( |
450 this, | 483 this, |
451 main_file_path, | 484 main_file_path, |
452 page_url, | 485 page_url, |
453 is_otr, | 486 is_otr, |
454 GetNextId(), | 487 GetNextId(), |
455 mime_type, | 488 mime_type, |
456 bound_net_log); | 489 bound_net_log); |
457 | 490 |
458 download->AddObserver(observer); | 491 download->AddObserver(observer); |
459 | 492 |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
673 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 706 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
674 | 707 |
675 VLOG(20) << __FUNCTION__ << "()" | 708 VLOG(20) << __FUNCTION__ << "()" |
676 << " download = " << download->DebugString(true); | 709 << " download = " << download->DebugString(true); |
677 | 710 |
678 RemoveFromActiveList(download); | 711 RemoveFromActiveList(download); |
679 // This function is called from the DownloadItem, so DI state | 712 // This function is called from the DownloadItem, so DI state |
680 // should already have been updated. | 713 // should already have been updated. |
681 AssertStateConsistent(download); | 714 AssertStateConsistent(download); |
682 | 715 |
683 if (file_manager_) | 716 DCHECK(file_manager_); |
684 download->OffThreadCancel(file_manager_); | 717 download->OffThreadCancel(file_manager_); |
685 } | 718 } |
686 | 719 |
687 void DownloadManagerImpl::OnDownloadInterrupted( | 720 void DownloadManagerImpl::OnDownloadInterrupted( |
688 int32 download_id, | 721 int32 download_id, |
689 int64 size, | 722 int64 size, |
690 const std::string& hash_state, | 723 const std::string& hash_state, |
691 content::DownloadInterruptReason reason) { | 724 content::DownloadInterruptReason reason) { |
692 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 725 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
693 | 726 |
694 DownloadItem* download = GetActiveDownload(download_id); | 727 DownloadItem* download = GetActiveDownload(download_id); |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
873 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). | 906 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). |
874 void DownloadManagerImpl::OnPersistentStoreQueryComplete( | 907 void DownloadManagerImpl::OnPersistentStoreQueryComplete( |
875 std::vector<DownloadPersistentStoreInfo>* entries) { | 908 std::vector<DownloadPersistentStoreInfo>* entries) { |
876 for (size_t i = 0; i < entries->size(); ++i) { | 909 for (size_t i = 0; i < entries->size(); ++i) { |
877 int64 db_handle = entries->at(i).db_handle; | 910 int64 db_handle = entries->at(i).db_handle; |
878 base::debug::Alias(&db_handle); | 911 base::debug::Alias(&db_handle); |
879 DCHECK(!ContainsKey(history_downloads_, db_handle)); | 912 DCHECK(!ContainsKey(history_downloads_, db_handle)); |
880 | 913 |
881 net::BoundNetLog bound_net_log = | 914 net::BoundNetLog bound_net_log = |
882 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); | 915 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); |
883 DownloadItem* download = new DownloadItemImpl( | 916 DownloadItem* download = factory_->CreatePersistedItem( |
884 this, GetNextId(), entries->at(i), bound_net_log); | 917 this, GetNextId(), entries->at(i), bound_net_log); |
885 downloads_.insert(download); | 918 downloads_.insert(download); |
886 history_downloads_[download->GetDbHandle()] = download; | 919 history_downloads_[download->GetDbHandle()] = download; |
887 VLOG(20) << __FUNCTION__ << "()" << i << ">" | 920 VLOG(20) << __FUNCTION__ << "()" << i << ">" |
888 << " download = " << download->DebugString(true); | 921 << " download = " << download->DebugString(true); |
889 } | 922 } |
890 NotifyModelChanged(); | 923 NotifyModelChanged(); |
891 CheckForHistoryFilesRemoval(); | 924 CheckForHistoryFilesRemoval(); |
892 } | 925 } |
893 | 926 |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1143 void DownloadManagerImpl::DownloadRenamedToFinalName( | 1176 void DownloadManagerImpl::DownloadRenamedToFinalName( |
1144 DownloadItem* download) { | 1177 DownloadItem* download) { |
1145 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1178 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1146 // If the rename failed, we receive an OnDownloadInterrupted() call before we | 1179 // If the rename failed, we receive an OnDownloadInterrupted() call before we |
1147 // receive the DownloadRenamedToFinalName() call. | 1180 // receive the DownloadRenamedToFinalName() call. |
1148 if (delegate_) { | 1181 if (delegate_) { |
1149 delegate_->UpdatePathForItemInPersistentStore( | 1182 delegate_->UpdatePathForItemInPersistentStore( |
1150 download, download->GetFullPath()); | 1183 download, download->GetFullPath()); |
1151 } | 1184 } |
1152 } | 1185 } |
1153 | |
1154 void DownloadManagerImpl::SetFileManagerForTesting( | |
1155 DownloadFileManager* file_manager) { | |
1156 file_manager_ = file_manager; | |
1157 } | |
OLD | NEW |