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

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

Issue 10872102: Revert 153563 - Remove DownloadFileManager in favor of direct ownership of DownloadFiles. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 3 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/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_factory.h"
26 #include "content/browser/download/download_item_impl.h" 25 #include "content/browser/download/download_item_impl.h"
27 #include "content/browser/download/download_stats.h" 26 #include "content/browser/download/download_stats.h"
28 #include "content/browser/renderer_host/render_view_host_impl.h" 27 #include "content/browser/renderer_host/render_view_host_impl.h"
29 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h" 28 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h"
30 #include "content/browser/web_contents/web_contents_impl.h" 29 #include "content/browser/web_contents/web_contents_impl.h"
31 #include "content/public/browser/browser_context.h" 30 #include "content/public/browser/browser_context.h"
32 #include "content/public/browser/browser_thread.h" 31 #include "content/public/browser/browser_thread.h"
33 #include "content/public/browser/content_browser_client.h" 32 #include "content/public/browser/content_browser_client.h"
34 #include "content/public/browser/download_interrupt_reasons.h" 33 #include "content/public/browser/download_interrupt_reasons.h"
35 #include "content/public/browser/download_manager_delegate.h" 34 #include "content/public/browser/download_manager_delegate.h"
(...skipping 10 matching lines...) Expand all
46 45
47 using content::BrowserThread; 46 using content::BrowserThread;
48 using content::DownloadId; 47 using content::DownloadId;
49 using content::DownloadItem; 48 using content::DownloadItem;
50 using content::DownloadPersistentStoreInfo; 49 using content::DownloadPersistentStoreInfo;
51 using content::ResourceDispatcherHostImpl; 50 using content::ResourceDispatcherHostImpl;
52 using content::WebContents; 51 using content::WebContents;
53 52
54 namespace { 53 namespace {
55 54
55 // This is just used to remember which DownloadItems come from SavePage.
56 class SavePageData : public base::SupportsUserData::Data {
57 public:
58 // A spoonful of syntactic sugar.
59 static bool Get(DownloadItem* item) {
60 return item->GetUserData(kKey) != NULL;
61 }
62
63 explicit SavePageData(DownloadItem* item) {
64 item->SetUserData(kKey, this);
65 }
66
67 virtual ~SavePageData() {}
68
69 private:
70 static const char kKey[];
71
72 DISALLOW_COPY_AND_ASSIGN(SavePageData);
73 };
74
75 const char SavePageData::kKey[] = "DownloadItem SavePageData";
76
56 void BeginDownload(content::DownloadUrlParameters* params) { 77 void BeginDownload(content::DownloadUrlParameters* params) {
57 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 78 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
58 // ResourceDispatcherHost{Base} is-not-a URLRequest::Delegate, and 79 // ResourceDispatcherHost{Base} is-not-a URLRequest::Delegate, and
59 // DownloadUrlParameters can-not include resource_dispatcher_host_impl.h, so 80 // DownloadUrlParameters can-not include resource_dispatcher_host_impl.h, so
60 // we must down cast. RDHI is the only subclass of RDH as of 2012 May 4. 81 // we must down cast. RDHI is the only subclass of RDH as of 2012 May 4.
61 scoped_ptr<net::URLRequest> request(new net::URLRequest( 82 scoped_ptr<net::URLRequest> request(new net::URLRequest(
62 params->url(), 83 params->url(),
63 NULL, 84 NULL,
64 params->resource_context()->GetRequestContext())); 85 params->resource_context()->GetRequestContext()));
65 request->set_referrer(params->referrer().url.spec()); 86 request->set_referrer(params->referrer().url.spec());
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 137
117 bool operator!=(const MapValueIteratorAdapter& that) const { 138 bool operator!=(const MapValueIteratorAdapter& that) const {
118 return iter_ != that.iter_; 139 return iter_ != that.iter_;
119 } 140 }
120 141
121 private: 142 private:
122 base::hash_map<int64, DownloadItem*>::const_iterator iter_; 143 base::hash_map<int64, DownloadItem*>::const_iterator iter_;
123 // Allow copy and assign. 144 // Allow copy and assign.
124 }; 145 };
125 146
126 void EnsureNoPendingDownloadJobsOnFile(bool* result) { 147 void EnsureNoPendingDownloadsOnFile(scoped_refptr<DownloadFileManager> dfm,
127 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 148 bool* result) {
128 *result = (content::DownloadFile::GetNumberOfDownloadFiles() == 0); 149 if (dfm->NumberOfActiveDownloads())
150 *result = false;
129 BrowserThread::PostTask( 151 BrowserThread::PostTask(
130 BrowserThread::UI, FROM_HERE, MessageLoop::QuitClosure()); 152 BrowserThread::UI, FROM_HERE, MessageLoop::QuitClosure());
131 } 153 }
132 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
133 class DownloadItemFactoryImpl : public content::DownloadItemFactory { 164 class DownloadItemFactoryImpl : public content::DownloadItemFactory {
134 public: 165 public:
135 DownloadItemFactoryImpl() {} 166 DownloadItemFactoryImpl() {}
136 virtual ~DownloadItemFactoryImpl() {} 167 virtual ~DownloadItemFactoryImpl() {}
137 168
138 virtual DownloadItemImpl* CreatePersistedItem( 169 virtual DownloadItemImpl* CreatePersistedItem(
139 DownloadItemImplDelegate* delegate, 170 DownloadItemImplDelegate* delegate,
140 content::DownloadId download_id, 171 content::DownloadId download_id,
141 const content::DownloadPersistentStoreInfo& info, 172 const content::DownloadPersistentStoreInfo& info,
142 const net::BoundNetLog& bound_net_log) OVERRIDE { 173 const net::BoundNetLog& bound_net_log) OVERRIDE {
(...skipping 22 matching lines...) Expand all
165 }; 196 };
166 197
167 } // namespace 198 } // namespace
168 199
169 namespace content { 200 namespace content {
170 201
171 bool DownloadManager::EnsureNoPendingDownloadsForTesting() { 202 bool DownloadManager::EnsureNoPendingDownloadsForTesting() {
172 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 203 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
173 bool result = true; 204 bool result = true;
174 BrowserThread::PostTask( 205 BrowserThread::PostTask(
175 BrowserThread::FILE, FROM_HERE, 206 BrowserThread::IO, FROM_HERE,
176 base::Bind(&EnsureNoPendingDownloadJobsOnFile, &result)); 207 base::Bind(&EnsureNoPendingDownloadJobsOnIO, &result));
177 MessageLoop::current()->Run(); 208 MessageLoop::current()->Run();
178 return result; 209 return result;
179 } 210 }
180 211
181 } // namespace content 212 } // namespace content
182 213
183 DownloadManagerImpl::DownloadManagerImpl( 214 DownloadManagerImpl::DownloadManagerImpl(
184 scoped_ptr<content::DownloadItemFactory> item_factory, 215 DownloadFileManager* file_manager,
185 scoped_ptr<content::DownloadFileFactory> file_factory, 216 scoped_ptr<content::DownloadItemFactory> factory,
186 net::NetLog* net_log) 217 net::NetLog* net_log)
187 : item_factory_(item_factory.Pass()), 218 : factory_(factory.Pass()),
188 file_factory_(file_factory.Pass()),
189 history_size_(0), 219 history_size_(0),
190 shutdown_needed_(false), 220 shutdown_needed_(false),
191 browser_context_(NULL), 221 browser_context_(NULL),
222 file_manager_(file_manager),
192 delegate_(NULL), 223 delegate_(NULL),
193 net_log_(net_log) { 224 net_log_(net_log) {
194 if (!item_factory_.get()) 225 DCHECK(file_manager);
195 item_factory_.reset(new DownloadItemFactoryImpl()); 226 if (!factory_.get())
196 if (!file_factory_.get()) 227 factory_.reset(new DownloadItemFactoryImpl());
197 file_factory_.reset(new content::DownloadFileFactory());
198 } 228 }
199 229
200 DownloadManagerImpl::~DownloadManagerImpl() { 230 DownloadManagerImpl::~DownloadManagerImpl() {
201 DCHECK(!shutdown_needed_); 231 DCHECK(!shutdown_needed_);
202 } 232 }
203 233
204 DownloadId DownloadManagerImpl::GetNextId() { 234 DownloadId DownloadManagerImpl::GetNextId() {
205 DownloadId id; 235 DownloadId id;
206 if (delegate_) 236 if (delegate_)
207 id = delegate_->GetNextId(); 237 id = delegate_->GetNextId();
208 if (!id.IsValid()) { 238 if (!id.IsValid()) {
209 static int next_id; 239 static int next_id;
210 id = DownloadId(browser_context_, ++next_id); 240 id = DownloadId(browser_context_, ++next_id);
211 } 241 }
212 242
213 return id; 243 return id;
214 } 244 }
215 245
216 void DownloadManagerImpl::DelegateStart(DownloadItemImpl* item) { 246 DownloadFileManager* DownloadManagerImpl::GetDownloadFileManager() {
217 content::DownloadTargetCallback callback = 247 return file_manager_;
218 base::Bind(&DownloadManagerImpl::OnDownloadTargetDetermined,
219 this, item->GetId());
220 if (!delegate_ || !delegate_->DetermineDownloadTarget(item, callback)) {
221 FilePath target_path = item->GetForcedFilePath();
222 // TODO(asanka): Determine a useful path if |target_path| is empty.
223 callback.Run(target_path,
224 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
225 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
226 target_path);
227 }
228 } 248 }
229 249
230 bool DownloadManagerImpl::ShouldOpenDownload(DownloadItemImpl* item) { 250 bool DownloadManagerImpl::ShouldOpenDownload(DownloadItemImpl* item) {
231 if (!delegate_) 251 if (!delegate_)
232 return true; 252 return true;
233 253
234 return delegate_->ShouldOpenDownload(item); 254 return delegate_->ShouldOpenDownload(item);
235 } 255 }
236 256
237 bool DownloadManagerImpl::ShouldOpenFileBasedOnExtension(const FilePath& path) { 257 bool DownloadManagerImpl::ShouldOpenFileBasedOnExtension(const FilePath& path) {
(...skipping 15 matching lines...) Expand all
253 void DownloadManagerImpl::Shutdown() { 273 void DownloadManagerImpl::Shutdown() {
254 VLOG(20) << __FUNCTION__ << "()" 274 VLOG(20) << __FUNCTION__ << "()"
255 << " shutdown_needed_ = " << shutdown_needed_; 275 << " shutdown_needed_ = " << shutdown_needed_;
256 if (!shutdown_needed_) 276 if (!shutdown_needed_)
257 return; 277 return;
258 shutdown_needed_ = false; 278 shutdown_needed_ = false;
259 279
260 FOR_EACH_OBSERVER(Observer, observers_, ManagerGoingDown(this)); 280 FOR_EACH_OBSERVER(Observer, observers_, ManagerGoingDown(this));
261 // TODO(benjhayden): Consider clearing observers_. 281 // TODO(benjhayden): Consider clearing observers_.
262 282
263 // The DownloadFiles will be canceled and deleted by their DownloadItems. 283 DCHECK(file_manager_);
284 BrowserThread::PostTask(
285 BrowserThread::FILE, FROM_HERE,
286 base::Bind(&DownloadFileManager::OnDownloadManagerShutdown,
287 file_manager_, make_scoped_refptr(this)));
264 288
265 AssertContainersConsistent(); 289 AssertContainersConsistent();
266 290
267 // Go through all downloads in downloads_. Dangerous ones we need to 291 // Go through all downloads in downloads_. Dangerous ones we need to
268 // remove on disk, and in progress ones we need to cancel. 292 // remove on disk, and in progress ones we need to cancel.
269 for (DownloadMap::iterator it = downloads_.begin(); it != downloads_.end();) { 293 for (DownloadMap::iterator it = downloads_.begin(); it != downloads_.end();) {
270 DownloadItemImpl* download = it->second; 294 DownloadItemImpl* download = it->second;
271 295
272 // Save iterator from potential erases in this set done by called code. 296 // Save iterator from potential erases in this set done by called code.
273 // Iterators after an erasure point are still valid for lists and 297 // Iterators after an erasure point are still valid for lists and
(...skipping 22 matching lines...) Expand all
296 // and all in progress downloads have been cancelled. We can now delete 320 // and all in progress downloads have been cancelled. We can now delete
297 // anything left. 321 // anything left.
298 322
299 active_downloads_.clear(); 323 active_downloads_.clear();
300 STLDeleteValues(&downloads_); 324 STLDeleteValues(&downloads_);
301 downloads_.clear(); 325 downloads_.clear();
302 326
303 // We'll have nothing more to report to the observers after this point. 327 // We'll have nothing more to report to the observers after this point.
304 observers_.Clear(); 328 observers_.Clear();
305 329
330 file_manager_ = NULL;
306 if (delegate_) 331 if (delegate_)
307 delegate_->Shutdown(); 332 delegate_->Shutdown();
308 delegate_ = NULL; 333 delegate_ = NULL;
309 } 334 }
310 335
311 void DownloadManagerImpl::GetTemporaryDownloads( 336 void DownloadManagerImpl::GetTemporaryDownloads(
312 const FilePath& dir_path, DownloadVector* result) { 337 const FilePath& dir_path, DownloadVector* result) {
313 DCHECK(result); 338 DCHECK(result);
314 339
315 for (DownloadMap::iterator it = downloads_.begin(); 340 for (DownloadMap::iterator it = downloads_.begin();
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 bool DownloadManagerImpl::Init(content::BrowserContext* browser_context) { 384 bool DownloadManagerImpl::Init(content::BrowserContext* browser_context) {
360 DCHECK(browser_context); 385 DCHECK(browser_context);
361 DCHECK(!shutdown_needed_) << "DownloadManager already initialized."; 386 DCHECK(!shutdown_needed_) << "DownloadManager already initialized.";
362 shutdown_needed_ = true; 387 shutdown_needed_ = true;
363 388
364 browser_context_ = browser_context; 389 browser_context_ = browser_context;
365 390
366 return true; 391 return true;
367 } 392 }
368 393
394 // We have received a message from DownloadFileManager about a new download.
369 content::DownloadId DownloadManagerImpl::StartDownload( 395 content::DownloadId DownloadManagerImpl::StartDownload(
370 scoped_ptr<DownloadCreateInfo> info, 396 scoped_ptr<DownloadCreateInfo> info,
371 scoped_ptr<content::ByteStreamReader> stream) { 397 scoped_ptr<content::ByteStreamReader> stream) {
372 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 398 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
373 399
374 net::BoundNetLog bound_net_log = 400 // |bound_net_log| will be used for logging both the download item's and
375 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); 401 // the download file's events.
402 net::BoundNetLog bound_net_log = CreateDownloadItem(info.get());
376 403
377 // We create the DownloadItem before the DownloadFile because the 404 // If info->download_id was unknown on entry to this function, it was
378 // DownloadItem already needs to handle a state in which there is 405 // assigned in CreateDownloadItem.
379 // no associated DownloadFile (history downloads, !IN_PROGRESS downloads) 406 DownloadId download_id = info->download_id;
380 DownloadItemImpl* download =
381 CreateDownloadItem(info.get(), bound_net_log);
382 scoped_ptr<content::DownloadFile> download_file(
383 file_factory_->CreateFile(
384 info->save_info, info->url(), info->referrer_url,
385 info->received_bytes, GenerateFileHash(),
386 stream.Pass(), bound_net_log,
387 download->DestinationObserverAsWeakPtr()));
388 download->Start(download_file.Pass());
389 407
390 return download->GetGlobalId(); 408 DownloadFileManager::CreateDownloadFileCallback callback(
409 base::Bind(&DownloadManagerImpl::OnDownloadFileCreated,
410 this, download_id.local()));
411
412 BrowserThread::PostTask(
413 BrowserThread::FILE, FROM_HERE,
414 base::Bind(&DownloadFileManager::CreateDownloadFile,
415 file_manager_, base::Passed(info.Pass()),
416 base::Passed(stream.Pass()),
417 make_scoped_refptr(this),
418 GenerateFileHash(), bound_net_log,
419 callback));
420
421 return download_id;
422 }
423
424 void DownloadManagerImpl::OnDownloadFileCreated(
425 int32 download_id, content::DownloadInterruptReason reason) {
426 if (reason != content::DOWNLOAD_INTERRUPT_REASON_NONE) {
427 OnDownloadInterrupted(download_id, reason);
428 // TODO(rdsmith): It makes no sense to continue along the
429 // regular download path after we've gotten an error. But it's
430 // the way the code has historically worked, and this allows us
431 // to get the download persisted and observers of the download manager
432 // notified, so tests work. When we execute all side effects of cancel
433 // (including queue removal) immedately rather than waiting for
434 // persistence we should replace this comment with a "return;".
435 }
436
437 DownloadMap::iterator download_iter = active_downloads_.find(download_id);
438 if (download_iter == active_downloads_.end())
439 return;
440
441 DownloadItemImpl* download = download_iter->second;
442 content::DownloadTargetCallback callback =
443 base::Bind(&DownloadManagerImpl::OnDownloadTargetDetermined,
444 this, download_id);
445 if (!delegate_ || !delegate_->DetermineDownloadTarget(download, callback)) {
446 FilePath target_path = download->GetForcedFilePath();
447 // TODO(asanka): Determine a useful path if |target_path| is empty.
448 callback.Run(target_path,
449 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
450 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
451 target_path);
452 }
391 } 453 }
392 454
393 void DownloadManagerImpl::OnDownloadTargetDetermined( 455 void DownloadManagerImpl::OnDownloadTargetDetermined(
394 int32 download_id, 456 int32 download_id,
395 const FilePath& target_path, 457 const FilePath& target_path,
396 DownloadItem::TargetDisposition disposition, 458 DownloadItem::TargetDisposition disposition,
397 content::DownloadDangerType danger_type, 459 content::DownloadDangerType danger_type,
398 const FilePath& intermediate_path) { 460 const FilePath& intermediate_path) {
399 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 461 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
400 DownloadMap::iterator download_iter = active_downloads_.find(download_id); 462 DownloadMap::iterator download_iter = active_downloads_.find(download_id);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 void DownloadManagerImpl::OnFileRemovalDetected(int32 download_id) { 506 void DownloadManagerImpl::OnFileRemovalDetected(int32 download_id) {
445 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 507 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
446 if (ContainsKey(downloads_, download_id)) 508 if (ContainsKey(downloads_, download_id))
447 downloads_[download_id]->OnDownloadedFileRemoved(); 509 downloads_[download_id]->OnDownloadedFileRemoved();
448 } 510 }
449 511
450 content::BrowserContext* DownloadManagerImpl::GetBrowserContext() const { 512 content::BrowserContext* DownloadManagerImpl::GetBrowserContext() const {
451 return browser_context_; 513 return browser_context_;
452 } 514 }
453 515
454 DownloadItemImpl* DownloadManagerImpl::CreateDownloadItem( 516 net::BoundNetLog DownloadManagerImpl::CreateDownloadItem(
455 DownloadCreateInfo* info, const net::BoundNetLog& bound_net_log) { 517 DownloadCreateInfo* info) {
456 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 518 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
457 519
520 net::BoundNetLog bound_net_log =
521 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD);
458 if (!info->download_id.IsValid()) 522 if (!info->download_id.IsValid())
459 info->download_id = GetNextId(); 523 info->download_id = GetNextId();
460 DownloadItemImpl* download = item_factory_->CreateActiveItem( 524 DownloadItemImpl* download = factory_->CreateActiveItem(
461 this, *info, 525 this, *info,
462 scoped_ptr<DownloadRequestHandleInterface>( 526 scoped_ptr<DownloadRequestHandleInterface>(
463 new DownloadRequestHandle(info->request_handle)).Pass(), 527 new DownloadRequestHandle(info->request_handle)).Pass(),
464 bound_net_log); 528 bound_net_log);
465 529
466 DCHECK(!ContainsKey(downloads_, download->GetId())); 530 DCHECK(!ContainsKey(downloads_, download->GetId()));
467 downloads_[download->GetId()] = download; 531 downloads_[download->GetId()] = download;
468 DCHECK(!ContainsKey(active_downloads_, download->GetId())); 532 DCHECK(!ContainsKey(active_downloads_, download->GetId()));
469 active_downloads_[download->GetId()] = download; 533 active_downloads_[download->GetId()] = download;
470 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); 534 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download));
471 535
472 return download; 536 return bound_net_log;
473 } 537 }
474 538
475 DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem( 539 DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem(
476 const FilePath& main_file_path, 540 const FilePath& main_file_path,
477 const GURL& page_url, 541 const GURL& page_url,
478 const std::string& mime_type, 542 const std::string& mime_type,
479 DownloadItem::Observer* observer) { 543 DownloadItem::Observer* observer) {
480 net::BoundNetLog bound_net_log = 544 net::BoundNetLog bound_net_log =
481 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); 545 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD);
482 DownloadItemImpl* download = item_factory_->CreateSavePageItem( 546 DownloadItemImpl* download = factory_->CreateSavePageItem(
483 this, 547 this,
484 main_file_path, 548 main_file_path,
485 page_url, 549 page_url,
486 GetNextId(), 550 GetNextId(),
487 mime_type, 551 mime_type,
488 bound_net_log); 552 bound_net_log);
489 553
490 download->AddObserver(observer); 554 download->AddObserver(observer);
491 555
492 DCHECK(!ContainsKey(downloads_, download->GetId())); 556 DCHECK(!ContainsKey(downloads_, download->GetId()));
493 downloads_[download->GetId()] = download; 557 downloads_[download->GetId()] = download;
558 DCHECK(!SavePageData::Get(download));
559 new SavePageData(download);
560 DCHECK(SavePageData::Get(download));
494 561
495 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); 562 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download));
496 563
497 // Will notify the observer in the callback. 564 // Will notify the observer in the callback.
498 if (delegate_) 565 if (delegate_)
499 delegate_->AddItemToPersistentStore(download); 566 delegate_->AddItemToPersistentStore(download);
500 567
501 return download; 568 return download;
502 } 569 }
503 570
571 void DownloadManagerImpl::UpdateDownload(int32 download_id,
572 int64 bytes_so_far,
573 int64 bytes_per_sec,
574 const std::string& hash_state) {
575 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
576 DownloadMap::iterator it = active_downloads_.find(download_id);
577 if (it != active_downloads_.end()) {
578 DownloadItemImpl* download = it->second;
579 if (download->IsInProgress()) {
580 download->UpdateProgress(bytes_so_far, bytes_per_sec, hash_state);
581 if (delegate_)
582 delegate_->UpdateItemInPersistentStore(download);
583 }
584 }
585 }
586
587 void DownloadManagerImpl::OnResponseCompleted(int32 download_id,
588 int64 size,
589 const std::string& hash) {
590 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
591 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id
592 << " size = " << size;
593 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
594
595 // If it's not in active_downloads_, that means it was cancelled; just
596 // ignore the notification.
597 if (active_downloads_.count(download_id) == 0)
598 return;
599
600 DownloadItemImpl* download = active_downloads_[download_id];
601 download->OnAllDataSaved(size, hash);
602 MaybeCompleteDownload(download);
603 }
604
504 void DownloadManagerImpl::AssertStateConsistent( 605 void DownloadManagerImpl::AssertStateConsistent(
505 DownloadItemImpl* download) const { 606 DownloadItemImpl* download) const {
506 CHECK(ContainsKey(downloads_, download->GetId())); 607 CHECK(ContainsKey(downloads_, download->GetId()));
507 608
508 int64 state = download->GetState(); 609 int64 state = download->GetState();
509 base::debug::Alias(&state); 610 base::debug::Alias(&state);
510 if (ContainsKey(active_downloads_, download->GetId())) { 611 if (ContainsKey(active_downloads_, download->GetId())) {
511 if (download->IsPersisted()) 612 if (download->IsPersisted())
512 CHECK_EQ(DownloadItem::IN_PROGRESS, download->GetState()); 613 CHECK_EQ(DownloadItem::IN_PROGRESS, download->GetState());
513 if (DownloadItem::IN_PROGRESS != download->GetState()) 614 if (DownloadItem::IN_PROGRESS != download->GetState())
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 void DownloadManagerImpl::DownloadStopped(DownloadItemImpl* download) { 716 void DownloadManagerImpl::DownloadStopped(DownloadItemImpl* download) {
616 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 717 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
617 718
618 VLOG(20) << __FUNCTION__ << "()" 719 VLOG(20) << __FUNCTION__ << "()"
619 << " download = " << download->DebugString(true); 720 << " download = " << download->DebugString(true);
620 721
621 RemoveFromActiveList(download); 722 RemoveFromActiveList(download);
622 // This function is called from the DownloadItem, so DI state 723 // This function is called from the DownloadItem, so DI state
623 // should already have been updated. 724 // should already have been updated.
624 AssertStateConsistent(download); 725 AssertStateConsistent(download);
726
727 DCHECK(file_manager_);
728 download->OffThreadCancel();
729 }
730
731 void DownloadManagerImpl::OnDownloadInterrupted(
732 int32 download_id,
733 content::DownloadInterruptReason reason) {
734 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
735
736 if (!ContainsKey(active_downloads_, download_id))
737 return;
738 active_downloads_[download_id]->Interrupt(reason);
625 } 739 }
626 740
627 void DownloadManagerImpl::RemoveFromActiveList(DownloadItemImpl* download) { 741 void DownloadManagerImpl::RemoveFromActiveList(DownloadItemImpl* download) {
628 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 742 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
629 DCHECK(download); 743 DCHECK(download);
630 744
631 // Clean up will happen when the history system create callback runs if we 745 // Clean up will happen when the history system create callback runs if we
632 // don't have a valid db_handle yet. 746 // don't have a valid db_handle yet.
633 if (download->IsPersisted()) { 747 if (download->IsPersisted()) {
634 active_downloads_.erase(download->GetId()); 748 active_downloads_.erase(download->GetId());
635 if (delegate_) 749 if (delegate_)
636 delegate_->UpdateItemInPersistentStore(download); 750 delegate_->UpdateItemInPersistentStore(download);
637 } 751 }
638 } 752 }
639 753
640 bool DownloadManagerImpl::GenerateFileHash() { 754 bool DownloadManagerImpl::GenerateFileHash() {
641 return delegate_ && delegate_->GenerateFileHash(); 755 return delegate_ && delegate_->GenerateFileHash();
642 } 756 }
643 757
644 void DownloadManagerImpl::SetDownloadFileFactoryForTesting(
645 scoped_ptr<content::DownloadFileFactory> file_factory) {
646 file_factory_ = file_factory.Pass();
647 }
648
649 content::DownloadFileFactory*
650 DownloadManagerImpl::GetDownloadFileFactoryForTesting() {
651 return file_factory_.get();
652 }
653
654 int DownloadManagerImpl::RemoveDownloadItems( 758 int DownloadManagerImpl::RemoveDownloadItems(
655 const DownloadItemImplVector& pending_deletes) { 759 const DownloadItemImplVector& pending_deletes) {
656 if (pending_deletes.empty()) 760 if (pending_deletes.empty())
657 return 0; 761 return 0;
658 762
659 // Delete from internal maps. 763 // Delete from internal maps.
660 for (DownloadItemImplVector::const_iterator it = pending_deletes.begin(); 764 for (DownloadItemImplVector::const_iterator it = pending_deletes.begin();
661 it != pending_deletes.end(); 765 it != pending_deletes.end();
662 ++it) { 766 ++it) {
663 DownloadItemImpl* download = *it; 767 DownloadItemImpl* download = *it;
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
751 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). 855 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time).
752 void DownloadManagerImpl::OnPersistentStoreQueryComplete( 856 void DownloadManagerImpl::OnPersistentStoreQueryComplete(
753 std::vector<DownloadPersistentStoreInfo>* entries) { 857 std::vector<DownloadPersistentStoreInfo>* entries) {
754 history_size_ = entries->size(); 858 history_size_ = entries->size();
755 for (size_t i = 0; i < entries->size(); ++i) { 859 for (size_t i = 0; i < entries->size(); ++i) {
756 int64 db_handle = entries->at(i).db_handle; 860 int64 db_handle = entries->at(i).db_handle;
757 base::debug::Alias(&db_handle); 861 base::debug::Alias(&db_handle);
758 862
759 net::BoundNetLog bound_net_log = 863 net::BoundNetLog bound_net_log =
760 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); 864 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD);
761 DownloadItemImpl* download = item_factory_->CreatePersistedItem( 865 DownloadItemImpl* download = factory_->CreatePersistedItem(
762 this, GetNextId(), entries->at(i), bound_net_log); 866 this, GetNextId(), entries->at(i), bound_net_log);
763 DCHECK(!ContainsKey(downloads_, download->GetId())); 867 DCHECK(!ContainsKey(downloads_, download->GetId()));
764 downloads_[download->GetId()] = download; 868 downloads_[download->GetId()] = download;
765 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); 869 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download));
766 VLOG(20) << __FUNCTION__ << "()" << i << ">" 870 VLOG(20) << __FUNCTION__ << "()" << i << ">"
767 << " download = " << download->DebugString(true); 871 << " download = " << download->DebugString(true);
768 } 872 }
769 NotifyModelChanged(); 873 NotifyModelChanged();
770 CheckForHistoryFilesRemoval(); 874 CheckForHistoryFilesRemoval();
771 } 875 }
(...skipping 20 matching lines...) Expand all
792 896
793 897
794 void DownloadManagerImpl::OnItemAddedToPersistentStore(int32 download_id, 898 void DownloadManagerImpl::OnItemAddedToPersistentStore(int32 download_id,
795 int64 db_handle) { 899 int64 db_handle) {
796 // It's valid that we don't find a matching item, i.e. on shutdown. 900 // It's valid that we don't find a matching item, i.e. on shutdown.
797 if (!ContainsKey(downloads_, download_id)) 901 if (!ContainsKey(downloads_, download_id))
798 return; 902 return;
799 903
800 DownloadItemImpl* item = downloads_[download_id]; 904 DownloadItemImpl* item = downloads_[download_id];
801 AddDownloadItemToHistory(item, db_handle); 905 AddDownloadItemToHistory(item, db_handle);
802 if (item->IsSavePackageDownload()) { 906 if (SavePageData::Get(item)) {
803 OnSavePageItemAddedToPersistentStore(item); 907 OnSavePageItemAddedToPersistentStore(item);
804 } else { 908 } else {
805 OnDownloadItemAddedToPersistentStore(item); 909 OnDownloadItemAddedToPersistentStore(item);
806 } 910 }
807 } 911 }
808 912
809 // Once the new DownloadItem has been committed to the persistent store, 913 // Once the new DownloadItem has been committed to the persistent store,
810 // associate it with its db_handle (TODO(benjhayden) merge db_handle with id), 914 // associate it with its db_handle (TODO(benjhayden) merge db_handle with id),
811 // show it in the browser (TODO(benjhayden) the ui should observe us instead), 915 // show it in the browser (TODO(benjhayden) the ui should observe us instead),
812 // and notify observers (TODO(benjhayden) observers should be able to see the 916 // and notify observers (TODO(benjhayden) observers should be able to see the
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
939 // Finalize this download if it finished before the history callback. 1043 // Finalize this download if it finished before the history callback.
940 if (!item->IsInProgress()) 1044 if (!item->IsInProgress())
941 SavePageDownloadFinished(item); 1045 SavePageDownloadFinished(item);
942 } 1046 }
943 1047
944 void DownloadManagerImpl::SavePageDownloadFinished( 1048 void DownloadManagerImpl::SavePageDownloadFinished(
945 content::DownloadItem* download) { 1049 content::DownloadItem* download) {
946 if (download->IsPersisted()) { 1050 if (download->IsPersisted()) {
947 if (delegate_) 1051 if (delegate_)
948 delegate_->UpdateItemInPersistentStore(download); 1052 delegate_->UpdateItemInPersistentStore(download);
1053 if (download->IsComplete())
1054 content::NotificationService::current()->Notify(
1055 content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED,
1056 content::Source<DownloadManager>(this),
1057 content::Details<DownloadItem>(download));
949 } 1058 }
950 } 1059 }
951 1060
952 void DownloadManagerImpl::DownloadOpened(DownloadItemImpl* download) { 1061 void DownloadManagerImpl::DownloadOpened(DownloadItemImpl* download) {
953 if (delegate_) 1062 if (delegate_)
954 delegate_->UpdateItemInPersistentStore(download); 1063 delegate_->UpdateItemInPersistentStore(download);
955 int num_unopened = 0; 1064 int num_unopened = 0;
956 for (DownloadMap::iterator it = downloads_.begin(); 1065 for (DownloadMap::iterator it = downloads_.begin();
957 it != downloads_.end(); ++it) { 1066 it != downloads_.end(); ++it) {
958 DownloadItemImpl* item = it->second; 1067 DownloadItemImpl* item = it->second;
959 if (item->IsComplete() && 1068 if (item->IsComplete() &&
960 !item->GetOpened()) 1069 !item->GetOpened())
961 ++num_unopened; 1070 ++num_unopened;
962 } 1071 }
963 download_stats::RecordOpensOutstanding(num_unopened); 1072 download_stats::RecordOpensOutstanding(num_unopened);
964 } 1073 }
965 1074
966 void DownloadManagerImpl::DownloadRenamedToIntermediateName( 1075 void DownloadManagerImpl::DownloadRenamedToIntermediateName(
967 DownloadItemImpl* download) { 1076 DownloadItemImpl* download) {
968 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1077 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
969 // download->GetFullPath() is only expected to be meaningful after this 1078 // download->GetFullPath() is only expected to be meaningful after this
970 // callback is received. Therefore we can now add the download to a persistent 1079 // callback is received. Therefore we can now add the download to a persistent
971 // store. If the rename failed, we processed an interrupt 1080 // store. If the rename failed, we receive an OnDownloadInterrupted() call
972 // before we receive the DownloadRenamedToIntermediateName() call. 1081 // before we receive the DownloadRenamedToIntermediateName() call.
973 if (delegate_) { 1082 if (delegate_) {
974 delegate_->AddItemToPersistentStore(download); 1083 delegate_->AddItemToPersistentStore(download);
975 } else { 1084 } else {
976 OnItemAddedToPersistentStore(download->GetId(), 1085 OnItemAddedToPersistentStore(download->GetId(),
977 DownloadItem::kUninitializedHandle); 1086 DownloadItem::kUninitializedHandle);
978 } 1087 }
979 } 1088 }
980 1089
981 void DownloadManagerImpl::DownloadRenamedToFinalName( 1090 void DownloadManagerImpl::DownloadRenamedToFinalName(
982 DownloadItemImpl* download) { 1091 DownloadItemImpl* download) {
983 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1092 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
984 // If the rename failed, we processed an interrupt before we get here. 1093 // If the rename failed, we receive an OnDownloadInterrupted() call before we
1094 // receive the DownloadRenamedToFinalName() call.
985 if (delegate_) { 1095 if (delegate_) {
986 delegate_->UpdatePathForItemInPersistentStore( 1096 delegate_->UpdatePathForItemInPersistentStore(
987 download, download->GetFullPath()); 1097 download, download->GetFullPath());
988 } 1098 }
989 } 1099 }
OLDNEW
« no previous file with comments | « content/browser/download/download_manager_impl.h ('k') | content/browser/download/download_manager_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698