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_manager.h" | 24 #include "content/browser/download/download_file_factory.h" |
25 #include "content/browser/download/download_item_factory.h" | |
25 #include "content/browser/download/download_item_impl.h" | 26 #include "content/browser/download/download_item_impl.h" |
26 #include "content/browser/download/download_stats.h" | 27 #include "content/browser/download/download_stats.h" |
27 #include "content/browser/renderer_host/render_view_host_impl.h" | 28 #include "content/browser/renderer_host/render_view_host_impl.h" |
28 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h" | 29 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h" |
29 #include "content/browser/web_contents/web_contents_impl.h" | 30 #include "content/browser/web_contents/web_contents_impl.h" |
30 #include "content/public/browser/browser_context.h" | 31 #include "content/public/browser/browser_context.h" |
31 #include "content/public/browser/browser_thread.h" | 32 #include "content/public/browser/browser_thread.h" |
32 #include "content/public/browser/content_browser_client.h" | 33 #include "content/public/browser/content_browser_client.h" |
33 #include "content/public/browser/download_interrupt_reasons.h" | 34 #include "content/public/browser/download_interrupt_reasons.h" |
34 #include "content/public/browser/download_manager_delegate.h" | 35 #include "content/public/browser/download_manager_delegate.h" |
(...skipping 11 matching lines...) Expand all Loading... | |
46 | 47 |
47 using content::BrowserThread; | 48 using content::BrowserThread; |
48 using content::DownloadId; | 49 using content::DownloadId; |
49 using content::DownloadItem; | 50 using content::DownloadItem; |
50 using content::DownloadPersistentStoreInfo; | 51 using content::DownloadPersistentStoreInfo; |
51 using content::ResourceDispatcherHostImpl; | 52 using content::ResourceDispatcherHostImpl; |
52 using content::WebContents; | 53 using content::WebContents; |
53 | 54 |
54 namespace { | 55 namespace { |
55 | 56 |
56 // This is just used to remember which DownloadItems come from SavePage. | |
57 class SavePageData : public base::SupportsUserData::Data { | |
58 public: | |
59 // A spoonful of syntactic sugar. | |
60 static bool Get(DownloadItem* item) { | |
61 return item->GetUserData(kKey) != NULL; | |
62 } | |
63 | |
64 explicit SavePageData(DownloadItem* item) { | |
65 item->SetUserData(kKey, this); | |
66 } | |
67 | |
68 virtual ~SavePageData() {} | |
69 | |
70 private: | |
71 static const char kKey[]; | |
72 | |
73 DISALLOW_COPY_AND_ASSIGN(SavePageData); | |
74 }; | |
75 | |
76 const char SavePageData::kKey[] = "DownloadItem SavePageData"; | |
77 | |
78 void BeginDownload(content::DownloadUrlParameters* params) { | 57 void BeginDownload(content::DownloadUrlParameters* params) { |
79 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 58 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
80 // ResourceDispatcherHost{Base} is-not-a URLRequest::Delegate, and | 59 // ResourceDispatcherHost{Base} is-not-a URLRequest::Delegate, and |
81 // DownloadUrlParameters can-not include resource_dispatcher_host_impl.h, so | 60 // DownloadUrlParameters can-not include resource_dispatcher_host_impl.h, so |
82 // we must down cast. RDHI is the only subclass of RDH as of 2012 May 4. | 61 // we must down cast. RDHI is the only subclass of RDH as of 2012 May 4. |
83 scoped_ptr<net::URLRequest> request( | 62 scoped_ptr<net::URLRequest> request( |
84 params->resource_context()->GetRequestContext()->CreateRequest( | 63 params->resource_context()->GetRequestContext()->CreateRequest( |
85 params->url(), NULL)); | 64 params->url(), NULL)); |
86 request->set_referrer(params->referrer().url.spec()); | 65 request->set_referrer(params->referrer().url.spec()); |
87 webkit_glue::ConfigureURLRequestForReferrerPolicy( | 66 webkit_glue::ConfigureURLRequestForReferrerPolicy( |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
137 | 116 |
138 bool operator!=(const MapValueIteratorAdapter& that) const { | 117 bool operator!=(const MapValueIteratorAdapter& that) const { |
139 return iter_ != that.iter_; | 118 return iter_ != that.iter_; |
140 } | 119 } |
141 | 120 |
142 private: | 121 private: |
143 base::hash_map<int64, DownloadItem*>::const_iterator iter_; | 122 base::hash_map<int64, DownloadItem*>::const_iterator iter_; |
144 // Allow copy and assign. | 123 // Allow copy and assign. |
145 }; | 124 }; |
146 | 125 |
147 void EnsureNoPendingDownloadsOnFile(scoped_refptr<DownloadFileManager> dfm, | 126 void EnsureNoPendingDownloadJobsOnFile(bool* result) { |
148 bool* result) { | 127 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
149 if (dfm->NumberOfActiveDownloads()) | 128 *result = (content::DownloadFile::GetNumberOfDownloadFiles() == 0); |
150 *result = false; | |
151 BrowserThread::PostTask( | 129 BrowserThread::PostTask( |
152 BrowserThread::UI, FROM_HERE, MessageLoop::QuitClosure()); | 130 BrowserThread::UI, FROM_HERE, MessageLoop::QuitClosure()); |
153 } | 131 } |
154 | 132 |
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 | |
164 class DownloadItemFactoryImpl : public content::DownloadItemFactory { | 133 class DownloadItemFactoryImpl : public content::DownloadItemFactory { |
165 public: | 134 public: |
166 DownloadItemFactoryImpl() {} | 135 DownloadItemFactoryImpl() {} |
167 virtual ~DownloadItemFactoryImpl() {} | 136 virtual ~DownloadItemFactoryImpl() {} |
168 | 137 |
169 virtual DownloadItemImpl* CreatePersistedItem( | 138 virtual DownloadItemImpl* CreatePersistedItem( |
170 DownloadItemImplDelegate* delegate, | 139 DownloadItemImplDelegate* delegate, |
171 content::DownloadId download_id, | 140 content::DownloadId download_id, |
172 const content::DownloadPersistentStoreInfo& info, | 141 const content::DownloadPersistentStoreInfo& info, |
173 const net::BoundNetLog& bound_net_log) OVERRIDE { | 142 const net::BoundNetLog& bound_net_log) OVERRIDE { |
(...skipping 22 matching lines...) Expand all Loading... | |
196 }; | 165 }; |
197 | 166 |
198 } // namespace | 167 } // namespace |
199 | 168 |
200 namespace content { | 169 namespace content { |
201 | 170 |
202 bool DownloadManager::EnsureNoPendingDownloadsForTesting() { | 171 bool DownloadManager::EnsureNoPendingDownloadsForTesting() { |
203 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 172 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
204 bool result = true; | 173 bool result = true; |
205 BrowserThread::PostTask( | 174 BrowserThread::PostTask( |
206 BrowserThread::IO, FROM_HERE, | 175 BrowserThread::FILE, FROM_HERE, |
207 base::Bind(&EnsureNoPendingDownloadJobsOnIO, &result)); | 176 base::Bind(&EnsureNoPendingDownloadJobsOnFile, &result)); |
208 MessageLoop::current()->Run(); | 177 MessageLoop::current()->Run(); |
209 return result; | 178 return result; |
210 } | 179 } |
211 | 180 |
212 } // namespace content | 181 } // namespace content |
213 | 182 |
214 DownloadManagerImpl::DownloadManagerImpl( | 183 DownloadManagerImpl::DownloadManagerImpl( |
215 DownloadFileManager* file_manager, | 184 scoped_ptr<content::DownloadItemFactory> item_factory, |
216 scoped_ptr<content::DownloadItemFactory> factory, | 185 scoped_ptr<content::DownloadFileFactory> file_factory, |
217 net::NetLog* net_log) | 186 net::NetLog* net_log) |
218 : factory_(factory.Pass()), | 187 : item_factory_(item_factory.Pass()), |
188 file_factory_(file_factory.Pass()), | |
219 history_size_(0), | 189 history_size_(0), |
220 shutdown_needed_(false), | 190 shutdown_needed_(false), |
221 browser_context_(NULL), | 191 browser_context_(NULL), |
222 file_manager_(file_manager), | |
223 delegate_(NULL), | 192 delegate_(NULL), |
224 net_log_(net_log) { | 193 net_log_(net_log) { |
225 DCHECK(file_manager); | 194 if (!item_factory_.get()) |
226 if (!factory_.get()) | 195 item_factory_.reset(new DownloadItemFactoryImpl()); |
227 factory_.reset(new DownloadItemFactoryImpl()); | 196 if (!file_factory_.get()) |
197 file_factory_.reset(new content::DownloadFileFactory()); | |
228 } | 198 } |
229 | 199 |
230 DownloadManagerImpl::~DownloadManagerImpl() { | 200 DownloadManagerImpl::~DownloadManagerImpl() { |
231 DCHECK(!shutdown_needed_); | 201 DCHECK(!shutdown_needed_); |
232 } | 202 } |
233 | 203 |
234 DownloadId DownloadManagerImpl::GetNextId() { | 204 DownloadId DownloadManagerImpl::GetNextId() { |
235 DownloadId id; | 205 DownloadId id; |
236 if (delegate_) | 206 if (delegate_) |
237 id = delegate_->GetNextId(); | 207 id = delegate_->GetNextId(); |
238 if (!id.IsValid()) { | 208 if (!id.IsValid()) { |
239 static int next_id; | 209 static int next_id; |
240 id = DownloadId(browser_context_, ++next_id); | 210 id = DownloadId(browser_context_, ++next_id); |
241 } | 211 } |
242 | 212 |
243 return id; | 213 return id; |
244 } | 214 } |
245 | 215 |
246 DownloadFileManager* DownloadManagerImpl::GetDownloadFileManager() { | 216 void DownloadManagerImpl::DelegateStart(DownloadItemImpl* item) { |
247 return file_manager_; | 217 content::DownloadTargetCallback callback = |
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 } | |
248 } | 228 } |
249 | 229 |
250 bool DownloadManagerImpl::ShouldOpenDownload(DownloadItemImpl* item) { | 230 bool DownloadManagerImpl::ShouldOpenDownload(DownloadItemImpl* item) { |
251 if (!delegate_) | 231 if (!delegate_) |
252 return true; | 232 return true; |
253 | 233 |
254 return delegate_->ShouldOpenDownload(item); | 234 return delegate_->ShouldOpenDownload(item); |
255 } | 235 } |
256 | 236 |
257 bool DownloadManagerImpl::ShouldOpenFileBasedOnExtension(const FilePath& path) { | 237 bool DownloadManagerImpl::ShouldOpenFileBasedOnExtension(const FilePath& path) { |
(...skipping 15 matching lines...) Expand all Loading... | |
273 void DownloadManagerImpl::Shutdown() { | 253 void DownloadManagerImpl::Shutdown() { |
274 VLOG(20) << __FUNCTION__ << "()" | 254 VLOG(20) << __FUNCTION__ << "()" |
275 << " shutdown_needed_ = " << shutdown_needed_; | 255 << " shutdown_needed_ = " << shutdown_needed_; |
276 if (!shutdown_needed_) | 256 if (!shutdown_needed_) |
277 return; | 257 return; |
278 shutdown_needed_ = false; | 258 shutdown_needed_ = false; |
279 | 259 |
280 FOR_EACH_OBSERVER(Observer, observers_, ManagerGoingDown(this)); | 260 FOR_EACH_OBSERVER(Observer, observers_, ManagerGoingDown(this)); |
281 // TODO(benjhayden): Consider clearing observers_. | 261 // TODO(benjhayden): Consider clearing observers_. |
282 | 262 |
283 DCHECK(file_manager_); | 263 // The DownloadFiles will be canceled and deleted by their DownloadItems. |
284 BrowserThread::PostTask( | |
285 BrowserThread::FILE, FROM_HERE, | |
286 base::Bind(&DownloadFileManager::OnDownloadManagerShutdown, | |
287 file_manager_, make_scoped_refptr(this))); | |
288 | 264 |
289 AssertContainersConsistent(); | 265 AssertContainersConsistent(); |
290 | 266 |
291 // Go through all downloads in downloads_. Dangerous ones we need to | 267 // Go through all downloads in downloads_. Dangerous ones we need to |
292 // remove on disk, and in progress ones we need to cancel. | 268 // remove on disk, and in progress ones we need to cancel. |
293 for (DownloadMap::iterator it = downloads_.begin(); it != downloads_.end();) { | 269 for (DownloadMap::iterator it = downloads_.begin(); it != downloads_.end();) { |
294 DownloadItemImpl* download = it->second; | 270 DownloadItemImpl* download = it->second; |
295 | 271 |
296 // Save iterator from potential erases in this set done by called code. | 272 // Save iterator from potential erases in this set done by called code. |
297 // Iterators after an erasure point are still valid for lists and | 273 // Iterators after an erasure point are still valid for lists and |
(...skipping 22 matching lines...) Expand all Loading... | |
320 // and all in progress downloads have been cancelled. We can now delete | 296 // and all in progress downloads have been cancelled. We can now delete |
321 // anything left. | 297 // anything left. |
322 | 298 |
323 active_downloads_.clear(); | 299 active_downloads_.clear(); |
324 STLDeleteValues(&downloads_); | 300 STLDeleteValues(&downloads_); |
325 downloads_.clear(); | 301 downloads_.clear(); |
326 | 302 |
327 // We'll have nothing more to report to the observers after this point. | 303 // We'll have nothing more to report to the observers after this point. |
328 observers_.Clear(); | 304 observers_.Clear(); |
329 | 305 |
330 file_manager_ = NULL; | |
331 if (delegate_) | 306 if (delegate_) |
332 delegate_->Shutdown(); | 307 delegate_->Shutdown(); |
333 delegate_ = NULL; | 308 delegate_ = NULL; |
334 } | 309 } |
335 | 310 |
336 void DownloadManagerImpl::SearchDownloads(const string16& query, | 311 void DownloadManagerImpl::SearchDownloads(const string16& query, |
337 DownloadVector* result) { | 312 DownloadVector* result) { |
338 string16 query_lower(base::i18n::ToLower(query)); | 313 string16 query_lower(base::i18n::ToLower(query)); |
339 | 314 |
340 for (DownloadMap::iterator it = downloads_.begin(); | 315 for (DownloadMap::iterator it = downloads_.begin(); |
(...skipping 11 matching lines...) Expand all Loading... | |
352 bool DownloadManagerImpl::Init(content::BrowserContext* browser_context) { | 327 bool DownloadManagerImpl::Init(content::BrowserContext* browser_context) { |
353 DCHECK(browser_context); | 328 DCHECK(browser_context); |
354 DCHECK(!shutdown_needed_) << "DownloadManager already initialized."; | 329 DCHECK(!shutdown_needed_) << "DownloadManager already initialized."; |
355 shutdown_needed_ = true; | 330 shutdown_needed_ = true; |
356 | 331 |
357 browser_context_ = browser_context; | 332 browser_context_ = browser_context; |
358 | 333 |
359 return true; | 334 return true; |
360 } | 335 } |
361 | 336 |
362 // We have received a message from DownloadFileManager about a new download. | |
363 content::DownloadId DownloadManagerImpl::StartDownload( | 337 content::DownloadId DownloadManagerImpl::StartDownload( |
364 scoped_ptr<DownloadCreateInfo> info, | 338 scoped_ptr<DownloadCreateInfo> info, |
365 scoped_ptr<content::ByteStreamReader> stream) { | 339 scoped_ptr<content::ByteStreamReader> stream) { |
366 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 340 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
367 | 341 |
368 // |bound_net_log| will be used for logging both the download item's and | 342 net::BoundNetLog bound_net_log = |
369 // the download file's events. | 343 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); |
370 net::BoundNetLog bound_net_log = CreateDownloadItem(info.get()); | |
371 | 344 |
372 // If info->download_id was unknown on entry to this function, it was | 345 // We create the DownloadItem before the DownloadFile because the |
373 // assigned in CreateDownloadItem. | 346 // DownloadItem already needs to handle a state in which there is |
374 DownloadId download_id = info->download_id; | 347 // no associated DownloadFile (history downloads, !IN_PROGRESS downloads) |
348 DownloadItemImpl* download = | |
349 CreateDownloadItem(info.get(), bound_net_log); | |
benjhayden
2012/09/12 21:01:01
If this is the only caller of CreateDownloadItem,
Randy Smith (Not in Mondays)
2012/09/13 20:15:12
It's currently used in the unit tests for creating
| |
350 scoped_ptr<content::DownloadFile> download_file( | |
351 file_factory_->CreateFile( | |
352 info->save_info, info->url(), info->referrer_url, | |
353 info->received_bytes, delegate_->GenerateFileHash(), | |
354 stream.Pass(), bound_net_log, | |
355 download->DestinationObserverAsWeakPtr())); | |
356 download->Start(download_file.Pass()); | |
375 | 357 |
376 DownloadFileManager::CreateDownloadFileCallback callback( | 358 // Delay notification until after Start() so that download_file is bound |
377 base::Bind(&DownloadManagerImpl::OnDownloadFileCreated, | 359 // to download and all the usually setters (e.g. Cancel) work. |
benjhayden
2012/09/12 21:01:01
usual*
Randy Smith (Not in Mondays)
2012/09/13 20:15:12
Done.
| |
378 this, download_id.local())); | 360 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); |
379 | 361 |
380 BrowserThread::PostTask( | 362 return download->GetGlobalId(); |
381 BrowserThread::FILE, FROM_HERE, | |
382 base::Bind(&DownloadFileManager::CreateDownloadFile, | |
383 file_manager_, base::Passed(info.Pass()), | |
384 base::Passed(stream.Pass()), make_scoped_refptr(this), | |
385 (delegate_ && delegate_->GenerateFileHash()), bound_net_log, | |
386 callback)); | |
387 | |
388 return download_id; | |
389 } | |
390 | |
391 void DownloadManagerImpl::OnDownloadFileCreated( | |
392 int32 download_id, content::DownloadInterruptReason reason) { | |
393 if (reason != content::DOWNLOAD_INTERRUPT_REASON_NONE) { | |
394 OnDownloadInterrupted(download_id, reason); | |
395 // TODO(rdsmith): It makes no sense to continue along the | |
396 // regular download path after we've gotten an error. But it's | |
397 // the way the code has historically worked, and this allows us | |
398 // to get the download persisted and observers of the download manager | |
399 // notified, so tests work. When we execute all side effects of cancel | |
400 // (including queue removal) immedately rather than waiting for | |
401 // persistence we should replace this comment with a "return;". | |
402 } | |
403 | |
404 DownloadMap::iterator download_iter = active_downloads_.find(download_id); | |
405 if (download_iter == active_downloads_.end()) | |
406 return; | |
407 | |
408 DownloadItemImpl* download = download_iter->second; | |
409 content::DownloadTargetCallback callback = | |
410 base::Bind(&DownloadManagerImpl::OnDownloadTargetDetermined, | |
411 this, download_id); | |
412 if (!delegate_ || !delegate_->DetermineDownloadTarget(download, callback)) { | |
413 FilePath target_path = download->GetForcedFilePath(); | |
414 // TODO(asanka): Determine a useful path if |target_path| is empty. | |
415 callback.Run(target_path, | |
416 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
417 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
418 target_path); | |
419 } | |
420 } | 363 } |
421 | 364 |
422 void DownloadManagerImpl::OnDownloadTargetDetermined( | 365 void DownloadManagerImpl::OnDownloadTargetDetermined( |
423 int32 download_id, | 366 int32 download_id, |
424 const FilePath& target_path, | 367 const FilePath& target_path, |
425 DownloadItem::TargetDisposition disposition, | 368 DownloadItem::TargetDisposition disposition, |
426 content::DownloadDangerType danger_type, | 369 content::DownloadDangerType danger_type, |
427 const FilePath& intermediate_path) { | 370 const FilePath& intermediate_path) { |
428 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 371 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
429 DownloadMap::iterator download_iter = active_downloads_.find(download_id); | 372 DownloadMap::iterator download_iter = active_downloads_.find(download_id); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
473 void DownloadManagerImpl::OnFileRemovalDetected(int32 download_id) { | 416 void DownloadManagerImpl::OnFileRemovalDetected(int32 download_id) { |
474 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 417 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
475 if (ContainsKey(downloads_, download_id)) | 418 if (ContainsKey(downloads_, download_id)) |
476 downloads_[download_id]->OnDownloadedFileRemoved(); | 419 downloads_[download_id]->OnDownloadedFileRemoved(); |
477 } | 420 } |
478 | 421 |
479 content::BrowserContext* DownloadManagerImpl::GetBrowserContext() const { | 422 content::BrowserContext* DownloadManagerImpl::GetBrowserContext() const { |
480 return browser_context_; | 423 return browser_context_; |
481 } | 424 } |
482 | 425 |
483 net::BoundNetLog DownloadManagerImpl::CreateDownloadItem( | 426 DownloadItemImpl* DownloadManagerImpl::CreateDownloadItem( |
484 DownloadCreateInfo* info) { | 427 DownloadCreateInfo* info, const net::BoundNetLog& bound_net_log) { |
485 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 428 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
486 | 429 |
487 net::BoundNetLog bound_net_log = | |
488 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); | |
489 if (!info->download_id.IsValid()) | 430 if (!info->download_id.IsValid()) |
490 info->download_id = GetNextId(); | 431 info->download_id = GetNextId(); |
491 DownloadItemImpl* download = factory_->CreateActiveItem( | 432 DownloadItemImpl* download = item_factory_->CreateActiveItem( |
492 this, *info, | 433 this, *info, |
493 scoped_ptr<DownloadRequestHandleInterface>( | 434 scoped_ptr<DownloadRequestHandleInterface>( |
494 new DownloadRequestHandle(info->request_handle)).Pass(), | 435 new DownloadRequestHandle(info->request_handle)).Pass(), |
495 bound_net_log); | 436 bound_net_log); |
496 | 437 |
497 DCHECK(!ContainsKey(downloads_, download->GetId())); | 438 DCHECK(!ContainsKey(downloads_, download->GetId())); |
498 downloads_[download->GetId()] = download; | 439 downloads_[download->GetId()] = download; |
499 DCHECK(!ContainsKey(active_downloads_, download->GetId())); | 440 DCHECK(!ContainsKey(active_downloads_, download->GetId())); |
500 active_downloads_[download->GetId()] = download; | 441 active_downloads_[download->GetId()] = download; |
501 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); | |
502 | 442 |
503 return bound_net_log; | 443 return download; |
504 } | 444 } |
505 | 445 |
506 DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem( | 446 DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem( |
507 const FilePath& main_file_path, | 447 const FilePath& main_file_path, |
508 const GURL& page_url, | 448 const GURL& page_url, |
509 const std::string& mime_type, | 449 const std::string& mime_type, |
510 DownloadItem::Observer* observer) { | 450 DownloadItem::Observer* observer) { |
511 net::BoundNetLog bound_net_log = | 451 net::BoundNetLog bound_net_log = |
512 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); | 452 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); |
513 DownloadItemImpl* download = factory_->CreateSavePageItem( | 453 DownloadItemImpl* download = item_factory_->CreateSavePageItem( |
514 this, | 454 this, |
515 main_file_path, | 455 main_file_path, |
516 page_url, | 456 page_url, |
517 GetNextId(), | 457 GetNextId(), |
518 mime_type, | 458 mime_type, |
519 bound_net_log); | 459 bound_net_log); |
520 | 460 |
521 download->AddObserver(observer); | 461 download->AddObserver(observer); |
522 | 462 |
523 DCHECK(!ContainsKey(downloads_, download->GetId())); | 463 DCHECK(!ContainsKey(downloads_, download->GetId())); |
524 downloads_[download->GetId()] = download; | 464 downloads_[download->GetId()] = download; |
525 DCHECK(!SavePageData::Get(download)); | |
526 new SavePageData(download); | |
527 DCHECK(SavePageData::Get(download)); | |
528 | 465 |
529 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); | 466 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); |
530 | 467 |
531 // Will notify the observer in the callback. | 468 // Will notify the observer in the callback. |
532 if (delegate_) | 469 if (delegate_) |
533 delegate_->AddItemToPersistentStore(download); | 470 delegate_->AddItemToPersistentStore(download); |
534 | 471 |
535 return download; | 472 return download; |
536 } | 473 } |
537 | 474 |
538 void DownloadManagerImpl::UpdateDownload(int32 download_id, | |
539 int64 bytes_so_far, | |
540 int64 bytes_per_sec, | |
541 const std::string& hash_state) { | |
542 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
543 DownloadMap::iterator it = active_downloads_.find(download_id); | |
544 if (it != active_downloads_.end()) { | |
545 DownloadItemImpl* download = it->second; | |
546 if (download->IsInProgress()) { | |
547 download->UpdateProgress(bytes_so_far, bytes_per_sec, hash_state); | |
548 if (delegate_) | |
549 delegate_->UpdateItemInPersistentStore(download); | |
550 } | |
551 } | |
552 } | |
553 | |
554 void DownloadManagerImpl::OnResponseCompleted(int32 download_id, | |
555 int64 size, | |
556 const std::string& hash) { | |
557 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
558 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id | |
559 << " size = " << size; | |
560 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
561 | |
562 // If it's not in active_downloads_, that means it was cancelled; just | |
563 // ignore the notification. | |
564 if (active_downloads_.count(download_id) == 0) | |
565 return; | |
566 | |
567 DownloadItemImpl* download = active_downloads_[download_id]; | |
568 download->OnAllDataSaved(size, hash); | |
569 MaybeCompleteDownload(download); | |
570 } | |
571 | |
572 void DownloadManagerImpl::AssertStateConsistent( | 475 void DownloadManagerImpl::AssertStateConsistent( |
573 DownloadItemImpl* download) const { | 476 DownloadItemImpl* download) const { |
574 CHECK(ContainsKey(downloads_, download->GetId())); | 477 CHECK(ContainsKey(downloads_, download->GetId())); |
575 | 478 |
576 int64 state = download->GetState(); | 479 int64 state = download->GetState(); |
577 base::debug::Alias(&state); | 480 base::debug::Alias(&state); |
578 if (ContainsKey(active_downloads_, download->GetId())) { | 481 if (ContainsKey(active_downloads_, download->GetId())) { |
579 if (download->IsPersisted()) | 482 if (download->IsPersisted()) |
580 CHECK_EQ(DownloadItem::IN_PROGRESS, download->GetState()); | 483 CHECK_EQ(DownloadItem::IN_PROGRESS, download->GetState()); |
581 if (DownloadItem::IN_PROGRESS != download->GetState()) | 484 if (DownloadItem::IN_PROGRESS != download->GetState()) |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
683 void DownloadManagerImpl::DownloadStopped(DownloadItemImpl* download) { | 586 void DownloadManagerImpl::DownloadStopped(DownloadItemImpl* download) { |
684 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 587 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
685 | 588 |
686 VLOG(20) << __FUNCTION__ << "()" | 589 VLOG(20) << __FUNCTION__ << "()" |
687 << " download = " << download->DebugString(true); | 590 << " download = " << download->DebugString(true); |
688 | 591 |
689 RemoveFromActiveList(download); | 592 RemoveFromActiveList(download); |
690 // This function is called from the DownloadItem, so DI state | 593 // This function is called from the DownloadItem, so DI state |
691 // should already have been updated. | 594 // should already have been updated. |
692 AssertStateConsistent(download); | 595 AssertStateConsistent(download); |
693 | |
694 DCHECK(file_manager_); | |
695 download->OffThreadCancel(); | |
696 } | |
697 | |
698 void DownloadManagerImpl::OnDownloadInterrupted( | |
699 int32 download_id, | |
700 content::DownloadInterruptReason reason) { | |
701 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
702 | |
703 if (!ContainsKey(active_downloads_, download_id)) | |
704 return; | |
705 active_downloads_[download_id]->Interrupt(reason); | |
706 } | 596 } |
707 | 597 |
708 void DownloadManagerImpl::RemoveFromActiveList(DownloadItemImpl* download) { | 598 void DownloadManagerImpl::RemoveFromActiveList(DownloadItemImpl* download) { |
709 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 599 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
710 DCHECK(download); | 600 DCHECK(download); |
711 | 601 |
712 // Clean up will happen when the history system create callback runs if we | 602 // Clean up will happen when the history system create callback runs if we |
713 // don't have a valid db_handle yet. | 603 // don't have a valid db_handle yet. |
714 if (download->IsPersisted()) { | 604 if (download->IsPersisted()) { |
715 active_downloads_.erase(download->GetId()); | 605 active_downloads_.erase(download->GetId()); |
716 if (delegate_) | 606 if (delegate_) |
717 delegate_->UpdateItemInPersistentStore(download); | 607 delegate_->UpdateItemInPersistentStore(download); |
718 } | 608 } |
719 } | 609 } |
720 | 610 |
611 void DownloadManagerImpl::SetDownloadFileFactoryForTesting( | |
612 scoped_ptr<content::DownloadFileFactory> file_factory) { | |
613 file_factory_ = file_factory.Pass(); | |
614 } | |
615 | |
616 content::DownloadFileFactory* | |
617 DownloadManagerImpl::GetDownloadFileFactoryForTesting() { | |
618 return file_factory_.get(); | |
619 } | |
620 | |
721 int DownloadManagerImpl::RemoveDownloadItems( | 621 int DownloadManagerImpl::RemoveDownloadItems( |
722 const DownloadItemImplVector& pending_deletes) { | 622 const DownloadItemImplVector& pending_deletes) { |
723 if (pending_deletes.empty()) | 623 if (pending_deletes.empty()) |
724 return 0; | 624 return 0; |
725 | 625 |
726 // Delete from internal maps. | 626 // Delete from internal maps. |
727 for (DownloadItemImplVector::const_iterator it = pending_deletes.begin(); | 627 for (DownloadItemImplVector::const_iterator it = pending_deletes.begin(); |
728 it != pending_deletes.end(); | 628 it != pending_deletes.end(); |
729 ++it) { | 629 ++it) { |
730 DownloadItemImpl* download = *it; | 630 DownloadItemImpl* download = *it; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
818 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). | 718 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). |
819 void DownloadManagerImpl::OnPersistentStoreQueryComplete( | 719 void DownloadManagerImpl::OnPersistentStoreQueryComplete( |
820 std::vector<DownloadPersistentStoreInfo>* entries) { | 720 std::vector<DownloadPersistentStoreInfo>* entries) { |
821 history_size_ = entries->size(); | 721 history_size_ = entries->size(); |
822 for (size_t i = 0; i < entries->size(); ++i) { | 722 for (size_t i = 0; i < entries->size(); ++i) { |
823 int64 db_handle = entries->at(i).db_handle; | 723 int64 db_handle = entries->at(i).db_handle; |
824 base::debug::Alias(&db_handle); | 724 base::debug::Alias(&db_handle); |
825 | 725 |
826 net::BoundNetLog bound_net_log = | 726 net::BoundNetLog bound_net_log = |
827 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); | 727 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); |
828 DownloadItemImpl* download = factory_->CreatePersistedItem( | 728 DownloadItemImpl* download = item_factory_->CreatePersistedItem( |
829 this, GetNextId(), entries->at(i), bound_net_log); | 729 this, GetNextId(), entries->at(i), bound_net_log); |
830 DCHECK(!ContainsKey(downloads_, download->GetId())); | 730 DCHECK(!ContainsKey(downloads_, download->GetId())); |
831 downloads_[download->GetId()] = download; | 731 downloads_[download->GetId()] = download; |
832 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); | 732 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); |
833 VLOG(20) << __FUNCTION__ << "()" << i << ">" | 733 VLOG(20) << __FUNCTION__ << "()" << i << ">" |
834 << " download = " << download->DebugString(true); | 734 << " download = " << download->DebugString(true); |
835 } | 735 } |
836 NotifyModelChanged(); | 736 NotifyModelChanged(); |
837 CheckForHistoryFilesRemoval(); | 737 CheckForHistoryFilesRemoval(); |
838 } | 738 } |
(...skipping 11 matching lines...) Expand all Loading... | |
850 ++history_size_; | 750 ++history_size_; |
851 | 751 |
852 // Show in the appropriate browser UI. | 752 // Show in the appropriate browser UI. |
853 // This includes buttons to save or cancel, for a dangerous download. | 753 // This includes buttons to save or cancel, for a dangerous download. |
854 ShowDownloadInBrowser(download); | 754 ShowDownloadInBrowser(download); |
855 | 755 |
856 // Inform interested objects about the new download. | 756 // Inform interested objects about the new download. |
857 NotifyModelChanged(); | 757 NotifyModelChanged(); |
858 } | 758 } |
859 | 759 |
860 | |
861 void DownloadManagerImpl::OnItemAddedToPersistentStore(int32 download_id, | 760 void DownloadManagerImpl::OnItemAddedToPersistentStore(int32 download_id, |
862 int64 db_handle) { | 761 int64 db_handle) { |
863 // It's valid that we don't find a matching item, i.e. on shutdown. | 762 // It's valid that we don't find a matching item, i.e. on shutdown. |
864 if (!ContainsKey(downloads_, download_id)) | 763 if (!ContainsKey(downloads_, download_id)) |
865 return; | 764 return; |
866 | 765 |
867 DownloadItemImpl* item = downloads_[download_id]; | 766 DownloadItemImpl* item = downloads_[download_id]; |
868 AddDownloadItemToHistory(item, db_handle); | 767 AddDownloadItemToHistory(item, db_handle); |
869 if (SavePageData::Get(item)) { | 768 if (item->IsSavePackageDownload()) { |
870 OnSavePageItemAddedToPersistentStore(item); | 769 OnSavePageItemAddedToPersistentStore(item); |
871 } else { | 770 } else { |
872 OnDownloadItemAddedToPersistentStore(item); | 771 OnDownloadItemAddedToPersistentStore(item); |
873 } | 772 } |
874 } | 773 } |
875 | 774 |
876 // Once the new DownloadItem has been committed to the persistent store, | 775 // Once the new DownloadItem has been committed to the persistent store, |
877 // associate it with its db_handle (TODO(benjhayden) merge db_handle with id), | 776 // associate it with its db_handle (TODO(benjhayden) merge db_handle with id), |
878 // show it in the browser (TODO(benjhayden) the ui should observe us instead), | 777 // show it in the browser (TODO(benjhayden) the ui should observe us instead), |
879 // and notify observers (TODO(benjhayden) observers should be able to see the | 778 // and notify observers (TODO(benjhayden) observers should be able to see the |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1013 // Finalize this download if it finished before the history callback. | 912 // Finalize this download if it finished before the history callback. |
1014 if (!item->IsInProgress()) | 913 if (!item->IsInProgress()) |
1015 SavePageDownloadFinished(item); | 914 SavePageDownloadFinished(item); |
1016 } | 915 } |
1017 | 916 |
1018 void DownloadManagerImpl::SavePageDownloadFinished( | 917 void DownloadManagerImpl::SavePageDownloadFinished( |
1019 content::DownloadItem* download) { | 918 content::DownloadItem* download) { |
1020 if (download->IsPersisted()) { | 919 if (download->IsPersisted()) { |
1021 if (delegate_) | 920 if (delegate_) |
1022 delegate_->UpdateItemInPersistentStore(download); | 921 delegate_->UpdateItemInPersistentStore(download); |
1023 if (download->IsComplete()) | |
1024 content::NotificationService::current()->Notify( | |
1025 content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED, | |
1026 content::Source<DownloadManager>(this), | |
1027 content::Details<DownloadItem>(download)); | |
1028 } | 922 } |
1029 } | 923 } |
1030 | 924 |
1031 void DownloadManagerImpl::DownloadOpened(DownloadItemImpl* download) { | 925 void DownloadManagerImpl::DownloadOpened(DownloadItemImpl* download) { |
1032 if (delegate_) | 926 if (delegate_) |
1033 delegate_->UpdateItemInPersistentStore(download); | 927 delegate_->UpdateItemInPersistentStore(download); |
1034 int num_unopened = 0; | 928 int num_unopened = 0; |
1035 for (DownloadMap::iterator it = downloads_.begin(); | 929 for (DownloadMap::iterator it = downloads_.begin(); |
1036 it != downloads_.end(); ++it) { | 930 it != downloads_.end(); ++it) { |
1037 DownloadItemImpl* item = it->second; | 931 DownloadItemImpl* item = it->second; |
1038 if (item->IsComplete() && | 932 if (item->IsComplete() && |
1039 !item->GetOpened()) | 933 !item->GetOpened()) |
1040 ++num_unopened; | 934 ++num_unopened; |
1041 } | 935 } |
1042 download_stats::RecordOpensOutstanding(num_unopened); | 936 download_stats::RecordOpensOutstanding(num_unopened); |
1043 } | 937 } |
1044 | 938 |
1045 void DownloadManagerImpl::DownloadRenamedToIntermediateName( | 939 void DownloadManagerImpl::DownloadRenamedToIntermediateName( |
1046 DownloadItemImpl* download) { | 940 DownloadItemImpl* download) { |
1047 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 941 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1048 // download->GetFullPath() is only expected to be meaningful after this | 942 // download->GetFullPath() is only expected to be meaningful after this |
1049 // callback is received. Therefore we can now add the download to a persistent | 943 // callback is received. Therefore we can now add the download to a persistent |
1050 // store. If the rename failed, we receive an OnDownloadInterrupted() call | 944 // store. If the rename failed, we processed an interrupt |
1051 // before we receive the DownloadRenamedToIntermediateName() call. | 945 // before we receive the DownloadRenamedToIntermediateName() call. |
1052 if (delegate_) { | 946 if (delegate_) { |
1053 delegate_->AddItemToPersistentStore(download); | 947 delegate_->AddItemToPersistentStore(download); |
1054 } else { | 948 } else { |
1055 OnItemAddedToPersistentStore(download->GetId(), | 949 OnItemAddedToPersistentStore(download->GetId(), |
1056 DownloadItem::kUninitializedHandle); | 950 DownloadItem::kUninitializedHandle); |
1057 } | 951 } |
1058 } | 952 } |
1059 | 953 |
1060 void DownloadManagerImpl::DownloadRenamedToFinalName( | 954 void DownloadManagerImpl::DownloadRenamedToFinalName( |
1061 DownloadItemImpl* download) { | 955 DownloadItemImpl* download) { |
1062 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 956 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1063 // If the rename failed, we receive an OnDownloadInterrupted() call before we | 957 // If the rename failed, we processed an interrupt before we get here. |
1064 // receive the DownloadRenamedToFinalName() call. | |
1065 if (delegate_) { | 958 if (delegate_) { |
1066 delegate_->UpdatePathForItemInPersistentStore( | 959 delegate_->UpdatePathForItemInPersistentStore( |
1067 download, download->GetFullPath()); | 960 download, download->GetFullPath()); |
1068 } | 961 } |
1069 } | 962 } |
OLD | NEW |