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 // File method ordering: Methods in this file are in the same order as | 5 // File method ordering: Methods in this file are in the same order as |
6 // in download_item_impl.h, with the following exception: The public | 6 // in download_item_impl.h, with the following exception: The public |
7 // interfaces DelayedDownloadOpened, OnDownloadTargetDetermined, | 7 // interfaces Start, DelayedDownloadOpened, MaybeCompleteDownload, and |
8 // MaybeCompleteDownload, and OnDownloadCompleting are placed in | 8 // OnDownloadCompleting are placed in chronological order with the other |
9 // chronological order with the other (private) routines that together | 9 // (private) routines that together define a DownloadItem's state transitions |
10 // define a DownloadItem's state transitions as the download | 10 // as the download progresses. See "Download progression cascade" later in |
11 // progresses. See "Download progression cascade" later in this file. | 11 // this file. |
12 | 12 |
13 // A regular DownloadItem (created for a download in this session of the | 13 // A regular DownloadItem (created for a download in this session of the |
14 // browser) normally goes through the following states: | 14 // browser) normally goes through the following states: |
15 // * Created (when download starts) | 15 // * Created (when download starts) |
16 // * Destination filename determined | 16 // * Destination filename determined |
17 // * Entered into the history database. | 17 // * Entered into the history database. |
18 // * Made visible in the download shelf. | 18 // * Made visible in the download shelf. |
19 // * All the data is saved. Note that the actual data download occurs | 19 // * All the data is saved. Note that the actual data download occurs |
20 // in parallel with the above steps, but until those steps are | 20 // in parallel with the above steps, but until those steps are |
21 // complete, the state of the data save will be ignored. | 21 // complete, the state of the data save will be ignored. |
22 // * Download file is renamed to its final name, and possibly | 22 // * Download file is renamed to its final name, and possibly |
23 // auto-opened. | 23 // auto-opened. |
24 | 24 |
25 #include "content/browser/download/download_item_impl.h" | 25 #include "content/browser/download/download_item_impl.h" |
26 | 26 |
27 #include <vector> | 27 #include <vector> |
28 | 28 |
29 #include "base/basictypes.h" | 29 #include "base/basictypes.h" |
30 #include "base/bind.h" | 30 #include "base/bind.h" |
31 #include "base/file_util.h" | 31 #include "base/file_util.h" |
32 #include "base/format_macros.h" | 32 #include "base/format_macros.h" |
33 #include "base/logging.h" | 33 #include "base/logging.h" |
34 #include "base/metrics/histogram.h" | 34 #include "base/metrics/histogram.h" |
35 #include "base/stl_util.h" | 35 #include "base/stl_util.h" |
36 #include "base/stringprintf.h" | 36 #include "base/stringprintf.h" |
37 #include "base/utf_string_conversions.h" | 37 #include "base/utf_string_conversions.h" |
38 #include "content/browser/download/download_create_info.h" | 38 #include "content/browser/download/download_create_info.h" |
39 #include "content/browser/download/download_file.h" | 39 #include "content/browser/download/download_file.h" |
40 #include "content/browser/download/download_file_manager.h" | |
41 #include "content/browser/download/download_interrupt_reasons_impl.h" | 40 #include "content/browser/download/download_interrupt_reasons_impl.h" |
42 #include "content/browser/download/download_item_impl_delegate.h" | 41 #include "content/browser/download/download_item_impl_delegate.h" |
43 #include "content/browser/download/download_request_handle.h" | 42 #include "content/browser/download/download_request_handle.h" |
44 #include "content/browser/download/download_stats.h" | 43 #include "content/browser/download/download_stats.h" |
45 #include "content/browser/web_contents/web_contents_impl.h" | 44 #include "content/browser/web_contents/web_contents_impl.h" |
46 #include "content/public/browser/browser_thread.h" | 45 #include "content/public/browser/browser_thread.h" |
47 #include "content/public/browser/content_browser_client.h" | 46 #include "content/public/browser/content_browser_client.h" |
48 #include "content/public/browser/download_persistent_store_info.h" | 47 #include "content/public/browser/download_persistent_store_info.h" |
49 #include "net/base/net_util.h" | 48 #include "net/base/net_util.h" |
50 | 49 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 return NULL; | 96 return NULL; |
98 } | 97 } |
99 virtual void PauseRequest() const OVERRIDE {} | 98 virtual void PauseRequest() const OVERRIDE {} |
100 virtual void ResumeRequest() const OVERRIDE {} | 99 virtual void ResumeRequest() const OVERRIDE {} |
101 virtual void CancelRequest() const OVERRIDE {} | 100 virtual void CancelRequest() const OVERRIDE {} |
102 virtual std::string DebugString() const OVERRIDE { | 101 virtual std::string DebugString() const OVERRIDE { |
103 return "Null DownloadRequestHandle"; | 102 return "Null DownloadRequestHandle"; |
104 } | 103 } |
105 }; | 104 }; |
106 | 105 |
| 106 // Wrapper around DownloadFile::Detach and DownloadFile::Cancel that |
| 107 // takes ownership of the DownloadFile and hence implicitly destroys it |
| 108 // at the end of the function. |
| 109 static void DownloadFileDetach( |
| 110 scoped_ptr<DownloadFile> download_file, base::Closure callback) { |
| 111 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 112 download_file->Detach(callback); |
| 113 } |
| 114 |
| 115 static void DownloadFileCancel(scoped_ptr<DownloadFile> download_file) { |
| 116 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 117 download_file->Cancel(); |
| 118 } |
| 119 |
107 } // namespace | 120 } // namespace |
108 | 121 |
109 namespace content { | 122 namespace content { |
110 | 123 |
111 // Our download table ID starts at 1, so we use 0 to represent a download that | 124 // Our download table ID starts at 1, so we use 0 to represent a download that |
112 // has started, but has not yet had its data persisted in the table. We use fake | 125 // has started, but has not yet had its data persisted in the table. We use fake |
113 // database handles in incognito mode starting at -1 and progressively getting | 126 // database handles in incognito mode starting at -1 and progressively getting |
114 // more negative. | 127 // more negative. |
115 // static | 128 // static |
116 const int DownloadItem::kUninitializedHandle = 0; | 129 const int DownloadItem::kUninitializedHandle = 0; |
117 | 130 |
118 const char DownloadItem::kEmptyFileHash[] = ""; | 131 const char DownloadItem::kEmptyFileHash[] = ""; |
119 | 132 |
120 } | 133 } |
121 | 134 |
122 // Our download table ID starts at 1, so we use 0 to represent a download that | 135 // Our download table ID starts at 1, so we use 0 to represent a download that |
123 // has started, but has not yet had its data persisted in the table. We use fake | 136 // has started, but has not yet had its data persisted in the table. We use fake |
124 // database handles in incognito mode starting at -1 and progressively getting | 137 // database handles in incognito mode starting at -1 and progressively getting |
125 // more negative. | 138 // more negative. |
126 | 139 |
127 // Constructor for reading from the history service. | 140 // Constructor for reading from the history service. |
128 DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate, | 141 DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate, |
129 DownloadId download_id, | 142 DownloadId download_id, |
130 const DownloadPersistentStoreInfo& info, | 143 const DownloadPersistentStoreInfo& info, |
131 const net::BoundNetLog& bound_net_log) | 144 const net::BoundNetLog& bound_net_log) |
132 : download_id_(download_id), | 145 : is_save_package_download_(false), |
| 146 download_id_(download_id), |
133 current_path_(info.path), | 147 current_path_(info.path), |
134 target_path_(info.path), | 148 target_path_(info.path), |
135 target_disposition_(TARGET_DISPOSITION_OVERWRITE), | 149 target_disposition_(TARGET_DISPOSITION_OVERWRITE), |
136 url_chain_(1, info.url), | 150 url_chain_(1, info.url), |
137 referrer_url_(info.referrer_url), | 151 referrer_url_(info.referrer_url), |
138 transition_type_(content::PAGE_TRANSITION_LINK), | 152 transition_type_(content::PAGE_TRANSITION_LINK), |
139 has_user_gesture_(false), | 153 has_user_gesture_(false), |
140 total_bytes_(info.total_bytes), | 154 total_bytes_(info.total_bytes), |
141 received_bytes_(info.received_bytes), | 155 received_bytes_(info.received_bytes), |
142 bytes_per_sec_(0), | 156 bytes_per_sec_(0), |
(...skipping 26 matching lines...) Expand all Loading... |
169 Init(false /* not actively downloading */, | 183 Init(false /* not actively downloading */, |
170 download_net_logs::SRC_HISTORY_IMPORT); | 184 download_net_logs::SRC_HISTORY_IMPORT); |
171 } | 185 } |
172 | 186 |
173 // Constructing for a regular download: | 187 // Constructing for a regular download: |
174 DownloadItemImpl::DownloadItemImpl( | 188 DownloadItemImpl::DownloadItemImpl( |
175 DownloadItemImplDelegate* delegate, | 189 DownloadItemImplDelegate* delegate, |
176 const DownloadCreateInfo& info, | 190 const DownloadCreateInfo& info, |
177 scoped_ptr<DownloadRequestHandleInterface> request_handle, | 191 scoped_ptr<DownloadRequestHandleInterface> request_handle, |
178 const net::BoundNetLog& bound_net_log) | 192 const net::BoundNetLog& bound_net_log) |
179 : request_handle_(request_handle.Pass()), | 193 : is_save_package_download_(false), |
| 194 request_handle_(request_handle.Pass()), |
180 download_id_(info.download_id), | 195 download_id_(info.download_id), |
181 target_disposition_( | 196 target_disposition_( |
182 (info.prompt_user_for_save_location) ? | 197 (info.prompt_user_for_save_location) ? |
183 TARGET_DISPOSITION_PROMPT : TARGET_DISPOSITION_OVERWRITE), | 198 TARGET_DISPOSITION_PROMPT : TARGET_DISPOSITION_OVERWRITE), |
184 url_chain_(info.url_chain), | 199 url_chain_(info.url_chain), |
185 referrer_url_(info.referrer_url), | 200 referrer_url_(info.referrer_url), |
186 suggested_filename_(UTF16ToUTF8(info.save_info->suggested_name)), | 201 suggested_filename_(UTF16ToUTF8(info.save_info->suggested_name)), |
187 forced_file_path_(info.save_info->file_path), | 202 forced_file_path_(info.save_info->file_path), |
188 transition_type_(info.transition_type), | 203 transition_type_(info.transition_type), |
189 has_user_gesture_(info.has_user_gesture), | 204 has_user_gesture_(info.has_user_gesture), |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 bound_net_log_.source().ToEventParametersCallback()); | 244 bound_net_log_.source().ToEventParametersCallback()); |
230 } | 245 } |
231 | 246 |
232 // Constructing for the "Save Page As..." feature: | 247 // Constructing for the "Save Page As..." feature: |
233 DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate, | 248 DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate, |
234 const FilePath& path, | 249 const FilePath& path, |
235 const GURL& url, | 250 const GURL& url, |
236 DownloadId download_id, | 251 DownloadId download_id, |
237 const std::string& mime_type, | 252 const std::string& mime_type, |
238 const net::BoundNetLog& bound_net_log) | 253 const net::BoundNetLog& bound_net_log) |
239 : request_handle_(new NullDownloadRequestHandle()), | 254 : is_save_package_download_(true), |
| 255 request_handle_(new NullDownloadRequestHandle()), |
240 download_id_(download_id), | 256 download_id_(download_id), |
241 current_path_(path), | 257 current_path_(path), |
242 target_path_(path), | 258 target_path_(path), |
243 target_disposition_(TARGET_DISPOSITION_OVERWRITE), | 259 target_disposition_(TARGET_DISPOSITION_OVERWRITE), |
244 url_chain_(1, url), | 260 url_chain_(1, url), |
245 referrer_url_(GURL()), | 261 referrer_url_(GURL()), |
246 transition_type_(content::PAGE_TRANSITION_LINK), | 262 transition_type_(content::PAGE_TRANSITION_LINK), |
247 has_user_gesture_(false), | 263 has_user_gesture_(false), |
248 mime_type_(mime_type), | 264 mime_type_(mime_type), |
249 original_mime_type_(mime_type), | 265 original_mime_type_(mime_type), |
(...skipping 20 matching lines...) Expand all Loading... |
270 delegate_delayed_complete_(false), | 286 delegate_delayed_complete_(false), |
271 bound_net_log_(bound_net_log), | 287 bound_net_log_(bound_net_log), |
272 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { | 288 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { |
273 delegate_->Attach(); | 289 delegate_->Attach(); |
274 Init(true /* actively downloading */, | 290 Init(true /* actively downloading */, |
275 download_net_logs::SRC_SAVE_PAGE_AS); | 291 download_net_logs::SRC_SAVE_PAGE_AS); |
276 } | 292 } |
277 | 293 |
278 DownloadItemImpl::~DownloadItemImpl() { | 294 DownloadItemImpl::~DownloadItemImpl() { |
279 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 295 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 296 |
| 297 // Should always have been nuked before now, at worst in |
| 298 // DownloadManager shutdown. |
| 299 DCHECK(!download_file_.get()); |
| 300 |
280 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadDestroyed(this)); | 301 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadDestroyed(this)); |
281 delegate_->AssertStateConsistent(this); | 302 delegate_->AssertStateConsistent(this); |
282 delegate_->Detach(); | 303 delegate_->Detach(); |
283 } | 304 } |
284 | 305 |
285 void DownloadItemImpl::AddObserver(Observer* observer) { | 306 void DownloadItemImpl::AddObserver(Observer* observer) { |
286 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 307 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
287 | 308 |
288 observers_.AddObserver(observer); | 309 observers_.AddObserver(observer); |
289 } | 310 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 | 342 |
322 UpdateObservers(); | 343 UpdateObservers(); |
323 | 344 |
324 MaybeCompleteDownload(); | 345 MaybeCompleteDownload(); |
325 } | 346 } |
326 | 347 |
327 void DownloadItemImpl::TogglePause() { | 348 void DownloadItemImpl::TogglePause() { |
328 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 349 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
329 | 350 |
330 DCHECK(state_ == IN_PROGRESS_INTERNAL || state_ == COMPLETING_INTERNAL); | 351 DCHECK(state_ == IN_PROGRESS_INTERNAL || state_ == COMPLETING_INTERNAL); |
| 352 |
| 353 // Ignore pauses when we've passed the commit point. |
| 354 if (state_ == COMPLETING_INTERNAL) |
| 355 return; |
| 356 |
331 if (is_paused_) | 357 if (is_paused_) |
332 request_handle_->ResumeRequest(); | 358 request_handle_->ResumeRequest(); |
333 else | 359 else |
334 request_handle_->PauseRequest(); | 360 request_handle_->PauseRequest(); |
335 is_paused_ = !is_paused_; | 361 is_paused_ = !is_paused_; |
336 UpdateObservers(); | 362 UpdateObservers(); |
337 } | 363 } |
338 | 364 |
339 void DownloadItemImpl::Cancel(bool user_cancel) { | 365 void DownloadItemImpl::Cancel(bool user_cancel) { |
340 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 366 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
341 | 367 |
342 last_reason_ = user_cancel ? | 368 last_reason_ = user_cancel ? |
343 content::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED : | 369 content::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED : |
344 content::DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN; | 370 content::DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN; |
345 | 371 |
346 VLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); | 372 VLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); |
347 if (state_ != IN_PROGRESS_INTERNAL) { | 373 if (state_ != IN_PROGRESS_INTERNAL) { |
348 // Small downloads might be complete before this method has | 374 // Small downloads might be complete before this method has |
349 // a chance to run. | 375 // a chance to run. |
350 return; | 376 return; |
351 } | 377 } |
352 | 378 |
353 download_stats::RecordDownloadCount(download_stats::CANCELLED_COUNT); | 379 download_stats::RecordDownloadCount(download_stats::CANCELLED_COUNT); |
354 | 380 |
355 TransitionTo(CANCELLED_INTERNAL); | 381 TransitionTo(CANCELLED_INTERNAL); |
| 382 |
| 383 CancelDownloadFile(); |
| 384 |
| 385 // Cancel the originating URL request. |
| 386 request_handle_->CancelRequest(); |
| 387 |
356 delegate_->DownloadStopped(this); | 388 delegate_->DownloadStopped(this); |
357 } | 389 } |
358 | 390 |
359 void DownloadItemImpl::Delete(DeleteReason reason) { | 391 void DownloadItemImpl::Delete(DeleteReason reason) { |
360 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 392 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
361 | 393 |
362 switch (reason) { | 394 switch (reason) { |
363 case DELETE_DUE_TO_USER_DISCARD: | 395 case DELETE_DUE_TO_USER_DISCARD: |
364 UMA_HISTOGRAM_ENUMERATION( | 396 UMA_HISTOGRAM_ENUMERATION( |
365 "Download.UserDiscard", GetDangerType(), | 397 "Download.UserDiscard", GetDangerType(), |
366 content::DOWNLOAD_DANGER_TYPE_MAX); | 398 content::DOWNLOAD_DANGER_TYPE_MAX); |
367 break; | 399 break; |
368 case DELETE_DUE_TO_BROWSER_SHUTDOWN: | 400 case DELETE_DUE_TO_BROWSER_SHUTDOWN: |
369 UMA_HISTOGRAM_ENUMERATION( | 401 UMA_HISTOGRAM_ENUMERATION( |
370 "Download.Discard", GetDangerType(), | 402 "Download.Discard", GetDangerType(), |
371 content::DOWNLOAD_DANGER_TYPE_MAX); | 403 content::DOWNLOAD_DANGER_TYPE_MAX); |
372 break; | 404 break; |
373 default: | 405 default: |
374 NOTREACHED(); | 406 NOTREACHED(); |
375 } | 407 } |
376 | 408 |
377 // TODO(asanka): Avoid deleting a file that is still owned by DownloadFile. | 409 // Delete the file if it exists and is not owned by a DownloadFile object. |
378 if (!current_path_.empty()) | 410 // (In the latter case the DownloadFile object will delete it on cancel.) |
| 411 if (!current_path_.empty() && download_file_.get() == NULL) { |
379 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 412 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
380 base::Bind(&DeleteDownloadedFile, current_path_)); | 413 base::Bind(&DeleteDownloadedFile, current_path_)); |
| 414 } |
381 Remove(); | 415 Remove(); |
382 // We have now been deleted. | 416 // We have now been deleted. |
383 } | 417 } |
384 | 418 |
385 void DownloadItemImpl::Remove() { | 419 void DownloadItemImpl::Remove() { |
386 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 420 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
387 | 421 |
388 delegate_->AssertStateConsistent(this); | 422 delegate_->AssertStateConsistent(this); |
389 Cancel(true); | 423 Cancel(true); |
390 delegate_->AssertStateConsistent(this); | 424 delegate_->AssertStateConsistent(this); |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
758 " db_handle = %" PRId64 | 792 " db_handle = %" PRId64 |
759 " total = %" PRId64 | 793 " total = %" PRId64 |
760 " received = %" PRId64 | 794 " received = %" PRId64 |
761 " reason = %s" | 795 " reason = %s" |
762 " paused = %c" | 796 " paused = %c" |
763 " safety = %s" | 797 " safety = %s" |
764 " last_modified = '%s'" | 798 " last_modified = '%s'" |
765 " etag = '%s'" | 799 " etag = '%s'" |
766 " url_chain = \n\t\"%s\"\n\t" | 800 " url_chain = \n\t\"%s\"\n\t" |
767 " full_path = \"%" PRFilePath "\"" | 801 " full_path = \"%" PRFilePath "\"" |
768 " target_path = \"%" PRFilePath "\"", | 802 " target_path = \"%" PRFilePath "\"" |
| 803 " has download file = %s", |
769 GetDbHandle(), | 804 GetDbHandle(), |
770 GetTotalBytes(), | 805 GetTotalBytes(), |
771 GetReceivedBytes(), | 806 GetReceivedBytes(), |
772 InterruptReasonDebugString(last_reason_).c_str(), | 807 InterruptReasonDebugString(last_reason_).c_str(), |
773 IsPaused() ? 'T' : 'F', | 808 IsPaused() ? 'T' : 'F', |
774 DebugSafetyStateString(GetSafetyState()), | 809 DebugSafetyStateString(GetSafetyState()), |
775 GetLastModifiedTime().c_str(), | 810 GetLastModifiedTime().c_str(), |
776 GetETag().c_str(), | 811 GetETag().c_str(), |
777 url_list.c_str(), | 812 url_list.c_str(), |
778 GetFullPath().value().c_str(), | 813 GetFullPath().value().c_str(), |
779 GetTargetFilePath().value().c_str()); | 814 GetTargetFilePath().value().c_str(), |
| 815 download_file_.get() ? "true" : "false"); |
780 } else { | 816 } else { |
781 description += base::StringPrintf(" url = \"%s\"", url_list.c_str()); | 817 description += base::StringPrintf(" url = \"%s\"", url_list.c_str()); |
782 } | 818 } |
783 | 819 |
784 description += " }"; | 820 description += " }"; |
785 | 821 |
786 return description; | 822 return description; |
787 } | 823 } |
788 | 824 |
789 void DownloadItemImpl::MockDownloadOpenForTesting() { | 825 void DownloadItemImpl::MockDownloadOpenForTesting() { |
790 open_enabled_ = false; | 826 open_enabled_ = false; |
791 } | 827 } |
792 | 828 |
793 void DownloadItemImpl::NotifyRemoved() { | 829 void DownloadItemImpl::NotifyRemoved() { |
794 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadRemoved(this)); | 830 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadRemoved(this)); |
795 } | 831 } |
796 | 832 |
797 void DownloadItemImpl::OnDownloadedFileRemoved() { | 833 void DownloadItemImpl::OnDownloadedFileRemoved() { |
798 file_externally_removed_ = true; | 834 file_externally_removed_ = true; |
799 UpdateObservers(); | 835 UpdateObservers(); |
800 } | 836 } |
801 | 837 |
802 void DownloadItemImpl::OffThreadCancel() { | |
803 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
804 request_handle_->CancelRequest(); | |
805 | |
806 BrowserThread::PostTask( | |
807 BrowserThread::FILE, FROM_HERE, | |
808 base::Bind(&DownloadFileManager::CancelDownload, | |
809 delegate_->GetDownloadFileManager(), download_id_)); | |
810 } | |
811 | |
812 // An error occurred somewhere. | 838 // An error occurred somewhere. |
813 void DownloadItemImpl::Interrupt(content::DownloadInterruptReason reason) { | 839 void DownloadItemImpl::Interrupt(content::DownloadInterruptReason reason) { |
814 // Somewhat counter-intuitively, it is possible for us to receive an | 840 // Somewhat counter-intuitively, it is possible for us to receive an |
815 // interrupt after we've already been interrupted. The generation of | 841 // interrupt after we've already been interrupted. The generation of |
816 // interrupts from the file thread Renames and the generation of | 842 // interrupts from the file thread Renames and the generation of |
817 // interrupts from disk writes go through two different mechanisms (driven | 843 // interrupts from disk writes go through two different mechanisms (driven |
818 // by rename requests from UI thread and by write requests from IO thread, | 844 // by rename requests from UI thread and by write requests from IO thread, |
819 // respectively), and since we choose not to keep state on the File thread, | 845 // respectively), and since we choose not to keep state on the File thread, |
820 // this is the place where the races collide. It's also possible for | 846 // this is the place where the races collide. It's also possible for |
821 // interrupts to race with cancels. | 847 // interrupts to race with cancels. |
822 | 848 |
823 // Whatever happens, the first one to hit the UI thread wins. | 849 // Whatever happens, the first one to hit the UI thread wins. |
824 if (state_ != IN_PROGRESS_INTERNAL) | 850 if (state_ != IN_PROGRESS_INTERNAL) |
825 return; | 851 return; |
826 | 852 |
827 last_reason_ = reason; | 853 last_reason_ = reason; |
828 TransitionTo(INTERRUPTED_INTERNAL); | 854 TransitionTo(INTERRUPTED_INTERNAL); |
| 855 |
| 856 CancelDownloadFile(); |
| 857 |
| 858 // Cancel the originating URL request. |
| 859 request_handle_->CancelRequest(); |
| 860 |
829 download_stats::RecordDownloadInterrupted( | 861 download_stats::RecordDownloadInterrupted( |
830 reason, received_bytes_, total_bytes_); | 862 reason, received_bytes_, total_bytes_); |
831 delegate_->DownloadStopped(this); | 863 delegate_->DownloadStopped(this); |
832 } | 864 } |
833 | 865 |
| 866 base::WeakPtr<content::DownloadDestinationObserver> |
| 867 DownloadItemImpl::DestinationObserverAsWeakPtr() { |
| 868 return weak_ptr_factory_.GetWeakPtr(); |
| 869 } |
| 870 |
| 871 bool DownloadItemImpl::IsSavePackageDownload() const { |
| 872 return is_save_package_download_; |
| 873 } |
| 874 |
834 void DownloadItemImpl::SetTotalBytes(int64 total_bytes) { | 875 void DownloadItemImpl::SetTotalBytes(int64 total_bytes) { |
835 total_bytes_ = total_bytes; | 876 total_bytes_ = total_bytes; |
836 } | 877 } |
837 | 878 |
838 // Updates from the download thread may have been posted while this download | 879 // Updates from the download thread may have been posted while this download |
839 // was being cancelled in the UI thread, so we'll accept them unless we're | 880 // was being cancelled in the UI thread, so we'll accept them unless we're |
840 // complete. | 881 // complete. |
841 void DownloadItemImpl::UpdateProgress(int64 bytes_so_far, | 882 void DownloadItemImpl::UpdateProgress(int64 bytes_so_far, |
842 int64 bytes_per_sec, | 883 int64 bytes_per_sec, |
843 const std::string& hash_state) { | 884 const std::string& hash_state) { |
(...skipping 22 matching lines...) Expand all Loading... |
866 | 907 |
867 if (bound_net_log_.IsLoggingAllEvents()) { | 908 if (bound_net_log_.IsLoggingAllEvents()) { |
868 bound_net_log_.AddEvent( | 909 bound_net_log_.AddEvent( |
869 net::NetLog::TYPE_DOWNLOAD_ITEM_UPDATED, | 910 net::NetLog::TYPE_DOWNLOAD_ITEM_UPDATED, |
870 net::NetLog::Int64Callback("bytes_so_far", received_bytes_)); | 911 net::NetLog::Int64Callback("bytes_so_far", received_bytes_)); |
871 } | 912 } |
872 | 913 |
873 UpdateObservers(); | 914 UpdateObservers(); |
874 } | 915 } |
875 | 916 |
876 void DownloadItemImpl::OnAllDataSaved( | 917 void DownloadItemImpl::OnAllDataSaved(const std::string& final_hash) { |
877 int64 size, const std::string& final_hash) { | |
878 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 918 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
879 | 919 |
| 920 DCHECK_EQ(IN_PROGRESS_INTERNAL, state_); |
880 DCHECK(!all_data_saved_); | 921 DCHECK(!all_data_saved_); |
881 all_data_saved_ = true; | 922 all_data_saved_ = true; |
882 ProgressComplete(size, final_hash); | 923 |
| 924 // Store final hash and null out intermediate serialized hash state. |
| 925 hash_ = final_hash; |
| 926 hash_state_ = ""; |
| 927 |
883 UpdateObservers(); | 928 UpdateObservers(); |
884 } | 929 } |
885 | 930 |
886 void DownloadItemImpl::MarkAsComplete() { | 931 void DownloadItemImpl::MarkAsComplete() { |
887 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 932 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
888 | 933 |
889 DCHECK(all_data_saved_); | 934 DCHECK(all_data_saved_); |
890 end_time_ = base::Time::Now(); | 935 end_time_ = base::Time::Now(); |
891 TransitionTo(COMPLETE_INTERNAL); | 936 TransitionTo(COMPLETE_INTERNAL); |
892 } | 937 } |
893 | 938 |
894 void DownloadItemImpl::SetIsPersisted() { | 939 void DownloadItemImpl::SetIsPersisted() { |
895 is_persisted_ = true; | 940 is_persisted_ = true; |
896 UpdateObservers(); | 941 UpdateObservers(); |
897 } | 942 } |
898 | 943 |
899 void DownloadItemImpl::SetDbHandle(int64 handle) { | 944 void DownloadItemImpl::SetDbHandle(int64 handle) { |
900 db_handle_ = handle; | 945 db_handle_ = handle; |
901 | 946 |
902 bound_net_log_.AddEvent( | 947 bound_net_log_.AddEvent( |
903 net::NetLog::TYPE_DOWNLOAD_ITEM_IN_HISTORY, | 948 net::NetLog::TYPE_DOWNLOAD_ITEM_IN_HISTORY, |
904 net::NetLog::Int64Callback("db_handle", db_handle_)); | 949 net::NetLog::Int64Callback("db_handle", db_handle_)); |
905 } | 950 } |
906 | 951 |
| 952 void DownloadItemImpl::DestinationUpdate(int64 bytes_so_far, |
| 953 int64 bytes_per_sec, |
| 954 const std::string& hash_state) { |
| 955 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 956 |
| 957 if (!IsInProgress()) { |
| 958 // Ignore if we're no longer in-progress. This can happen if we race a |
| 959 // Cancel on the UI thread with an update on the FILE thread. |
| 960 // |
| 961 // TODO(rdsmith): Arguably we should let this go through, as this means |
| 962 // the download really did get further than we know before it was |
| 963 // cancelled. But the gain isn't very large, and the code is more |
| 964 // fragile if it has to support in progress updates in a non-in-progress |
| 965 // state. This issue should be readdressed when we revamp performance |
| 966 // reporting. |
| 967 return; |
| 968 } |
| 969 bytes_per_sec_ = bytes_per_sec; |
| 970 hash_state_ = hash_state; |
| 971 received_bytes_ = bytes_so_far; |
| 972 |
| 973 // If we've received more data than we were expecting (bad server info?), |
| 974 // revert to 'unknown size mode'. |
| 975 if (received_bytes_ > total_bytes_) |
| 976 total_bytes_ = 0; |
| 977 |
| 978 if (bound_net_log_.IsLoggingAllEvents()) { |
| 979 bound_net_log_.AddEvent( |
| 980 net::NetLog::TYPE_DOWNLOAD_ITEM_UPDATED, |
| 981 net::NetLog::Int64Callback("bytes_so_far", received_bytes_)); |
| 982 } |
| 983 |
| 984 UpdateObservers(); |
| 985 } |
| 986 |
| 987 void DownloadItemImpl::DestinationError( |
| 988 content::DownloadInterruptReason reason) { |
| 989 // The DestinationError and Interrupt routines are being kept separate |
| 990 // to allow for a future merging of the Cancel and Interrupt routines.. |
| 991 Interrupt(reason); |
| 992 } |
| 993 |
| 994 void DownloadItemImpl::DestinationCompleted(const std::string& final_hash) { |
| 995 if (!IsInProgress()) |
| 996 return; |
| 997 OnAllDataSaved(final_hash); |
| 998 MaybeCompleteDownload(); |
| 999 } |
| 1000 |
907 // **** Download progression cascade | 1001 // **** Download progression cascade |
908 | 1002 |
909 void DownloadItemImpl::Init(bool active, | 1003 void DownloadItemImpl::Init(bool active, |
910 download_net_logs::DownloadType download_type) { | 1004 download_net_logs::DownloadType download_type) { |
911 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1005 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
912 | 1006 |
913 if (active) | 1007 if (active) |
914 download_stats::RecordDownloadCount(download_stats::START_COUNT); | 1008 download_stats::RecordDownloadCount(download_stats::START_COUNT); |
915 | 1009 |
916 if (target_path_.empty()) | 1010 if (target_path_.empty()) |
(...skipping 23 matching lines...) Expand all Loading... |
940 bound_net_log_.AddEvent( | 1034 bound_net_log_.AddEvent( |
941 net::NetLog::TYPE_DOWNLOAD_ITEM_IN_HISTORY, | 1035 net::NetLog::TYPE_DOWNLOAD_ITEM_IN_HISTORY, |
942 net::NetLog::Int64Callback("db_handle", db_handle_)); | 1036 net::NetLog::Int64Callback("db_handle", db_handle_)); |
943 | 1037 |
944 bound_net_log_.EndEvent(net::NetLog::TYPE_DOWNLOAD_ITEM_ACTIVE); | 1038 bound_net_log_.EndEvent(net::NetLog::TYPE_DOWNLOAD_ITEM_ACTIVE); |
945 } | 1039 } |
946 | 1040 |
947 VLOG(20) << __FUNCTION__ << "() " << DebugString(true); | 1041 VLOG(20) << __FUNCTION__ << "() " << DebugString(true); |
948 } | 1042 } |
949 | 1043 |
950 // Called by DownloadManagerImpl when the download target path has been | 1044 // We're starting the download. |
| 1045 void DownloadItemImpl::Start(scoped_ptr<content::DownloadFile> file) { |
| 1046 DCHECK(!download_file_.get()); |
| 1047 DCHECK(file.get()); |
| 1048 download_file_ = file.Pass(); |
| 1049 |
| 1050 BrowserThread::PostTask( |
| 1051 BrowserThread::FILE, FROM_HERE, |
| 1052 base::Bind(&DownloadFile::Initialize, |
| 1053 // Safe because we control download file lifetime. |
| 1054 base::Unretained(download_file_.get()), |
| 1055 base::Bind(&DownloadItemImpl::OnDownloadFileInitialized, |
| 1056 weak_ptr_factory_.GetWeakPtr()))); |
| 1057 } |
| 1058 |
| 1059 void DownloadItemImpl::OnDownloadFileInitialized( |
| 1060 content::DownloadInterruptReason result) { |
| 1061 if (result != content::DOWNLOAD_INTERRUPT_REASON_NONE) { |
| 1062 Interrupt(result); |
| 1063 // TODO(rdsmith): It makes no sense to continue along the |
| 1064 // regular download path after we've gotten an error. But it's |
| 1065 // the way the code has historically worked, and this allows us |
| 1066 // to get the download persisted and observers of the download manager |
| 1067 // notified, so tests work. When we execute all side effects of cancel |
| 1068 // (including queue removal) immedately rather than waiting for |
| 1069 // persistence we should replace this comment with a "return;". |
| 1070 } |
| 1071 |
| 1072 delegate_->DetermineDownloadTarget( |
| 1073 this, base::Bind(&DownloadItemImpl::OnDownloadTargetDetermined, |
| 1074 weak_ptr_factory_.GetWeakPtr())); |
| 1075 } |
| 1076 |
| 1077 // Called by delegate_ when the download target path has been |
951 // determined. | 1078 // determined. |
952 void DownloadItemImpl::OnDownloadTargetDetermined( | 1079 void DownloadItemImpl::OnDownloadTargetDetermined( |
953 const FilePath& target_path, | 1080 const FilePath& target_path, |
954 TargetDisposition disposition, | 1081 TargetDisposition disposition, |
955 content::DownloadDangerType danger_type, | 1082 content::DownloadDangerType danger_type, |
956 const FilePath& intermediate_path) { | 1083 const FilePath& intermediate_path) { |
957 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1084 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
958 | 1085 |
959 // If the |target_path| is empty, then we consider this download to be | 1086 // If the |target_path| is empty, then we consider this download to be |
960 // canceled. | 1087 // canceled. |
(...skipping 20 matching lines...) Expand all Loading... |
981 // whatever was recorded for consistency. | 1108 // whatever was recorded for consistency. |
982 OnDownloadRenamedToIntermediateName(last_reason_, FilePath()); | 1109 OnDownloadRenamedToIntermediateName(last_reason_, FilePath()); |
983 return; | 1110 return; |
984 } | 1111 } |
985 | 1112 |
986 // Rename to intermediate name. | 1113 // Rename to intermediate name. |
987 // TODO(asanka): Skip this rename if AllDataSaved() is true. This avoids a | 1114 // TODO(asanka): Skip this rename if AllDataSaved() is true. This avoids a |
988 // spurious rename when we can just rename to the final | 1115 // spurious rename when we can just rename to the final |
989 // filename. Unnecessary renames may cause bugs like | 1116 // filename. Unnecessary renames may cause bugs like |
990 // http://crbug.com/74187. | 1117 // http://crbug.com/74187. |
991 DownloadFileManager::RenameCompletionCallback callback = | 1118 DCHECK(!is_save_package_download_); |
| 1119 CHECK(download_file_.get()); |
| 1120 DownloadFile::RenameCompletionCallback callback = |
992 base::Bind(&DownloadItemImpl::OnDownloadRenamedToIntermediateName, | 1121 base::Bind(&DownloadItemImpl::OnDownloadRenamedToIntermediateName, |
993 weak_ptr_factory_.GetWeakPtr()); | 1122 weak_ptr_factory_.GetWeakPtr()); |
994 BrowserThread::PostTask( | 1123 BrowserThread::PostTask( |
995 BrowserThread::FILE, FROM_HERE, | 1124 BrowserThread::FILE, FROM_HERE, |
996 base::Bind(&DownloadFileManager::RenameDownloadFile, | 1125 base::Bind(&DownloadFile::Rename, |
997 delegate_->GetDownloadFileManager(), GetGlobalId(), | 1126 // Safe because we control download file lifetime. |
| 1127 base::Unretained(download_file_.get()), |
998 intermediate_path, false, callback)); | 1128 intermediate_path, false, callback)); |
999 } | 1129 } |
1000 | 1130 |
1001 void DownloadItemImpl::OnDownloadRenamedToIntermediateName( | 1131 void DownloadItemImpl::OnDownloadRenamedToIntermediateName( |
1002 content::DownloadInterruptReason reason, | 1132 content::DownloadInterruptReason reason, |
1003 const FilePath& full_path) { | 1133 const FilePath& full_path) { |
1004 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1134 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1005 if (content::DOWNLOAD_INTERRUPT_REASON_NONE != reason) { | 1135 if (content::DOWNLOAD_INTERRUPT_REASON_NONE != reason) { |
1006 Interrupt(reason); | 1136 Interrupt(reason); |
1007 } else { | 1137 } else { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1060 void DownloadItemImpl::ReadyForDownloadCompletionDone() { | 1190 void DownloadItemImpl::ReadyForDownloadCompletionDone() { |
1061 if (state_ != IN_PROGRESS_INTERNAL) | 1191 if (state_ != IN_PROGRESS_INTERNAL) |
1062 return; | 1192 return; |
1063 | 1193 |
1064 VLOG(20) << __FUNCTION__ << "()" | 1194 VLOG(20) << __FUNCTION__ << "()" |
1065 << " needs rename = " << NeedsRename() | 1195 << " needs rename = " << NeedsRename() |
1066 << " " << DebugString(true); | 1196 << " " << DebugString(true); |
1067 DCHECK(!GetTargetFilePath().empty()); | 1197 DCHECK(!GetTargetFilePath().empty()); |
1068 DCHECK_NE(DANGEROUS, GetSafetyState()); | 1198 DCHECK_NE(DANGEROUS, GetSafetyState()); |
1069 | 1199 |
| 1200 // TODO(rdsmith/benjhayden): Remove as part of SavePackage integration. |
| 1201 if (is_save_package_download_) { |
| 1202 // Avoid doing anything on the file thread; there's nothing we control |
| 1203 // there. |
| 1204 OnDownloadFileReleased(); |
| 1205 return; |
| 1206 } |
| 1207 |
| 1208 CHECK(download_file_.get()); |
1070 if (NeedsRename()) { | 1209 if (NeedsRename()) { |
1071 DownloadFileManager::RenameCompletionCallback callback = | 1210 content::DownloadFile::RenameCompletionCallback callback = |
1072 base::Bind(&DownloadItemImpl::OnDownloadRenamedToFinalName, | 1211 base::Bind(&DownloadItemImpl::OnDownloadRenamedToFinalName, |
1073 weak_ptr_factory_.GetWeakPtr()); | 1212 weak_ptr_factory_.GetWeakPtr()); |
1074 BrowserThread::PostTask( | 1213 BrowserThread::PostTask( |
1075 BrowserThread::FILE, FROM_HERE, | 1214 BrowserThread::FILE, FROM_HERE, |
1076 base::Bind(&DownloadFileManager::RenameDownloadFile, | 1215 base::Bind(&DownloadFile::Rename, |
1077 delegate_->GetDownloadFileManager(), GetGlobalId(), | 1216 base::Unretained(download_file_.get()), |
1078 GetTargetFilePath(), true, callback)); | 1217 GetTargetFilePath(), true, callback)); |
1079 } else { | 1218 } else { |
1080 // Complete the download and release the DownloadFile. | 1219 ReleaseDownloadFile(); |
1081 BrowserThread::PostTask( | |
1082 BrowserThread::FILE, FROM_HERE, | |
1083 base::Bind(&DownloadFileManager::CompleteDownload, | |
1084 delegate_->GetDownloadFileManager(), GetGlobalId(), | |
1085 base::Bind(&DownloadItemImpl::OnDownloadFileReleased, | |
1086 weak_ptr_factory_.GetWeakPtr()))); | |
1087 TransitionTo(COMPLETING_INTERNAL); | |
1088 } | 1220 } |
1089 } | 1221 } |
1090 | 1222 |
1091 void DownloadItemImpl::OnDownloadRenamedToFinalName( | 1223 void DownloadItemImpl::OnDownloadRenamedToFinalName( |
1092 content::DownloadInterruptReason reason, | 1224 content::DownloadInterruptReason reason, |
1093 const FilePath& full_path) { | 1225 const FilePath& full_path) { |
1094 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1226 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1095 | 1227 |
1096 // If a cancel or interrupt hit, we'll cancel the DownloadFile, which | 1228 // If a cancel or interrupt hit, we'll cancel the DownloadFile, which |
1097 // will result in deleting the file on the file thread. So we don't | 1229 // will result in deleting the file on the file thread. So we don't |
(...skipping 11 matching lines...) Expand all Loading... |
1109 Interrupt(reason); | 1241 Interrupt(reason); |
1110 return; | 1242 return; |
1111 } | 1243 } |
1112 | 1244 |
1113 // full_path is now the current and target file path. | 1245 // full_path is now the current and target file path. |
1114 DCHECK(!full_path.empty()); | 1246 DCHECK(!full_path.empty()); |
1115 target_path_ = full_path; | 1247 target_path_ = full_path; |
1116 SetFullPath(full_path); | 1248 SetFullPath(full_path); |
1117 delegate_->DownloadRenamedToFinalName(this); | 1249 delegate_->DownloadRenamedToFinalName(this); |
1118 | 1250 |
| 1251 ReleaseDownloadFile(); |
| 1252 } |
| 1253 |
| 1254 void DownloadItemImpl::ReleaseDownloadFile() { |
1119 // Complete the download and release the DownloadFile. | 1255 // Complete the download and release the DownloadFile. |
| 1256 DCHECK(!is_save_package_download_); |
| 1257 CHECK(download_file_.get()); |
1120 BrowserThread::PostTask( | 1258 BrowserThread::PostTask( |
1121 BrowserThread::FILE, FROM_HERE, | 1259 BrowserThread::FILE, FROM_HERE, |
1122 base::Bind(&DownloadFileManager::CompleteDownload, | 1260 base::Bind(&DownloadFileDetach, base::Passed(download_file_.Pass()), |
1123 delegate_->GetDownloadFileManager(), GetGlobalId(), | |
1124 base::Bind(&DownloadItemImpl::OnDownloadFileReleased, | 1261 base::Bind(&DownloadItemImpl::OnDownloadFileReleased, |
1125 weak_ptr_factory_.GetWeakPtr()))); | 1262 weak_ptr_factory_.GetWeakPtr()))); |
| 1263 |
| 1264 // We're not completely done with the download item yet, but at this |
| 1265 // point we're committed to complete the download. Cancels (or Interrupts, |
| 1266 // though it's not clear how they could happen) after this point will be |
| 1267 // ignored. |
1126 TransitionTo(COMPLETING_INTERNAL); | 1268 TransitionTo(COMPLETING_INTERNAL); |
1127 } | 1269 } |
1128 | 1270 |
1129 void DownloadItemImpl::OnDownloadFileReleased() { | 1271 void DownloadItemImpl::OnDownloadFileReleased() { |
1130 if (delegate_->ShouldOpenDownload(this)) | 1272 if (delegate_->ShouldOpenDownload(this)) |
1131 Completed(); | 1273 Completed(); |
1132 else | 1274 else |
1133 delegate_delayed_complete_ = true; | 1275 delegate_delayed_complete_ = true; |
1134 } | 1276 } |
1135 | 1277 |
(...skipping 24 matching lines...) Expand all Loading... |
1160 if (!IsTemporary()) | 1302 if (!IsTemporary()) |
1161 OpenDownload(); | 1303 OpenDownload(); |
1162 | 1304 |
1163 auto_opened_ = true; | 1305 auto_opened_ = true; |
1164 UpdateObservers(); | 1306 UpdateObservers(); |
1165 } | 1307 } |
1166 } | 1308 } |
1167 | 1309 |
1168 // **** End of Download progression cascade | 1310 // **** End of Download progression cascade |
1169 | 1311 |
| 1312 void DownloadItemImpl::CancelDownloadFile() { |
| 1313 // TODO(rdsmith/benjhayden): Remove condition as part of |
| 1314 // SavePackage integration. |
| 1315 if (!is_save_package_download_) { |
| 1316 CHECK(download_file_.get()); |
| 1317 BrowserThread::PostTask( |
| 1318 BrowserThread::FILE, FROM_HERE, |
| 1319 // Will be deleted at end of task execution. |
| 1320 base::Bind(&DownloadFileCancel, base::Passed(download_file_.Pass()))); |
| 1321 } |
| 1322 } |
| 1323 |
1170 bool DownloadItemImpl::IsDownloadReadyForCompletion() { | 1324 bool DownloadItemImpl::IsDownloadReadyForCompletion() { |
1171 // If we don't have all the data, the download is not ready for | 1325 // If we don't have all the data, the download is not ready for |
1172 // completion. | 1326 // completion. |
1173 if (!AllDataSaved()) | 1327 if (!AllDataSaved()) |
1174 return false; | 1328 return false; |
1175 | 1329 |
1176 // If the download is dangerous, but not yet validated, it's not ready for | 1330 // If the download is dangerous, but not yet validated, it's not ready for |
1177 // completion. | 1331 // completion. |
1178 if (GetSafetyState() == DownloadItem::DANGEROUS) | 1332 if (GetSafetyState() == DownloadItem::DANGEROUS) |
1179 return false; | 1333 return false; |
(...skipping 10 matching lines...) Expand all Loading... |
1190 return false; | 1344 return false; |
1191 | 1345 |
1192 return true; | 1346 return true; |
1193 } | 1347 } |
1194 | 1348 |
1195 bool DownloadItemImpl::NeedsRename() const { | 1349 bool DownloadItemImpl::NeedsRename() const { |
1196 DCHECK(target_path_.DirName() == current_path_.DirName()); | 1350 DCHECK(target_path_.DirName() == current_path_.DirName()); |
1197 return target_path_ != current_path_; | 1351 return target_path_ != current_path_; |
1198 } | 1352 } |
1199 | 1353 |
1200 void DownloadItemImpl::ProgressComplete(int64 bytes_so_far, | |
1201 const std::string& final_hash) { | |
1202 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
1203 | |
1204 hash_ = final_hash; | |
1205 hash_state_ = ""; | |
1206 | |
1207 received_bytes_ = bytes_so_far; | |
1208 | |
1209 // If we've received more data than we were expecting (bad server info?), | |
1210 // revert to 'unknown size mode'. | |
1211 if (received_bytes_ > total_bytes_) | |
1212 total_bytes_ = 0; | |
1213 } | |
1214 | |
1215 void DownloadItemImpl::TransitionTo(DownloadInternalState new_state) { | 1354 void DownloadItemImpl::TransitionTo(DownloadInternalState new_state) { |
1216 if (state_ == new_state) | 1355 if (state_ == new_state) |
1217 return; | 1356 return; |
1218 | 1357 |
1219 DownloadInternalState old_state = state_; | 1358 DownloadInternalState old_state = state_; |
1220 state_ = new_state; | 1359 state_ = new_state; |
1221 | 1360 |
1222 switch (state_) { | 1361 switch (state_) { |
1223 case COMPLETING_INTERNAL: | 1362 case COMPLETING_INTERNAL: |
1224 bound_net_log_.AddEvent( | 1363 bound_net_log_.AddEvent( |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1341 return "COMPLETE"; | 1480 return "COMPLETE"; |
1342 case CANCELLED_INTERNAL: | 1481 case CANCELLED_INTERNAL: |
1343 return "CANCELLED"; | 1482 return "CANCELLED"; |
1344 case INTERRUPTED_INTERNAL: | 1483 case INTERRUPTED_INTERNAL: |
1345 return "INTERRUPTED"; | 1484 return "INTERRUPTED"; |
1346 default: | 1485 default: |
1347 NOTREACHED() << "Unknown download state " << state; | 1486 NOTREACHED() << "Unknown download state " << state; |
1348 return "unknown"; | 1487 return "unknown"; |
1349 }; | 1488 }; |
1350 } | 1489 } |
OLD | NEW |