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 | 5 // File method ordering: Methods in this file are in the same order as |
6 // as 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, and | 7 // interfaces Start, DelayedDownloadOpened, and OnDownloadCompleting |
8 // OnDownloadCompleting are placed in chronological order with the other | 8 // are placed in chronological order with the other (private) routines |
9 // (private) routines that together define a DownloadItem's state transitions | 9 // that together define a DownloadItem's state transitions as the |
10 // as the download progresses. See "Download progression cascade" later in | 10 // download progresses. See "Download progression cascade" later in |
11 // 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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
342 VLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); | 363 VLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); |
343 if (state_ != IN_PROGRESS_INTERNAL) { | 364 if (state_ != IN_PROGRESS_INTERNAL) { |
344 // Small downloads might be complete before this method has | 365 // Small downloads might be complete before this method has |
345 // a chance to run. | 366 // a chance to run. |
346 return; | 367 return; |
347 } | 368 } |
348 | 369 |
349 download_stats::RecordDownloadCount(download_stats::CANCELLED_COUNT); | 370 download_stats::RecordDownloadCount(download_stats::CANCELLED_COUNT); |
350 | 371 |
351 TransitionTo(CANCELLED_INTERNAL); | 372 TransitionTo(CANCELLED_INTERNAL); |
373 | |
374 // Cancel and remove the download file. | |
375 // TODO(rdsmith/benjhayden): Remove condition as part of | |
376 // SavePackage integration. | |
377 if (!is_save_package_download_) { | |
378 CHECK(download_file_.get()); | |
379 BrowserThread::PostTask( | |
380 BrowserThread::FILE, FROM_HERE, | |
381 // Will be deleted at end of task execution. | |
382 base::Bind(&DownloadFileCancel, base::Passed(download_file_.Pass()))); | |
383 } | |
384 | |
385 // Cancel the originating URL request. | |
386 request_handle_->CancelRequest(); | |
387 | |
352 if (user_cancel) | 388 if (user_cancel) |
353 delegate_->DownloadStopped(this); | 389 delegate_->DownloadStopped(this); |
354 } | 390 } |
355 | 391 |
356 void DownloadItemImpl::Delete(DeleteReason reason) { | 392 void DownloadItemImpl::Delete(DeleteReason reason) { |
357 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 393 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
358 | 394 |
359 switch (reason) { | 395 switch (reason) { |
360 case DELETE_DUE_TO_USER_DISCARD: | 396 case DELETE_DUE_TO_USER_DISCARD: |
361 UMA_HISTOGRAM_ENUMERATION( | 397 UMA_HISTOGRAM_ENUMERATION( |
362 "Download.UserDiscard", GetDangerType(), | 398 "Download.UserDiscard", GetDangerType(), |
363 content::DOWNLOAD_DANGER_TYPE_MAX); | 399 content::DOWNLOAD_DANGER_TYPE_MAX); |
364 break; | 400 break; |
365 case DELETE_DUE_TO_BROWSER_SHUTDOWN: | 401 case DELETE_DUE_TO_BROWSER_SHUTDOWN: |
366 UMA_HISTOGRAM_ENUMERATION( | 402 UMA_HISTOGRAM_ENUMERATION( |
367 "Download.Discard", GetDangerType(), | 403 "Download.Discard", GetDangerType(), |
368 content::DOWNLOAD_DANGER_TYPE_MAX); | 404 content::DOWNLOAD_DANGER_TYPE_MAX); |
369 break; | 405 break; |
370 default: | 406 default: |
371 NOTREACHED(); | 407 NOTREACHED(); |
372 } | 408 } |
373 | 409 |
374 // TODO(asanka): Avoid deleting a file that is still owned by DownloadFile. | 410 // TODO(asanka): Avoid deleting a file that is still owned by DownloadFile. |
375 if (!current_path_.empty()) | 411 if (!current_path_.empty()) |
376 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 412 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
377 base::Bind(&DeleteDownloadedFile, current_path_)); | 413 base::Bind(&DeleteDownloadedFile, current_path_)); |
asanka
2012/09/28 20:22:42
Since we can now readily tell whether the Download
Randy Smith (Not in Mondays)
2012/10/09 20:20:19
Done.
| |
378 Remove(); | 414 Remove(); |
379 // We have now been deleted. | 415 // We have now been deleted. |
380 } | 416 } |
381 | 417 |
382 void DownloadItemImpl::Remove() { | 418 void DownloadItemImpl::Remove() { |
383 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 419 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
384 | 420 |
385 delegate_->AssertStateConsistent(this); | 421 delegate_->AssertStateConsistent(this); |
386 Cancel(true); | 422 Cancel(true); |
387 delegate_->AssertStateConsistent(this); | 423 delegate_->AssertStateConsistent(this); |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
755 " db_handle = %" PRId64 | 791 " db_handle = %" PRId64 |
756 " total = %" PRId64 | 792 " total = %" PRId64 |
757 " received = %" PRId64 | 793 " received = %" PRId64 |
758 " reason = %s" | 794 " reason = %s" |
759 " paused = %c" | 795 " paused = %c" |
760 " safety = %s" | 796 " safety = %s" |
761 " last_modified = '%s'" | 797 " last_modified = '%s'" |
762 " etag = '%s'" | 798 " etag = '%s'" |
763 " url_chain = \n\t\"%s\"\n\t" | 799 " url_chain = \n\t\"%s\"\n\t" |
764 " full_path = \"%" PRFilePath "\"" | 800 " full_path = \"%" PRFilePath "\"" |
765 " target_path = \"%" PRFilePath "\"", | 801 " target_path = \"%" PRFilePath "\"" |
802 " has download file = %s", | |
766 GetDbHandle(), | 803 GetDbHandle(), |
767 GetTotalBytes(), | 804 GetTotalBytes(), |
768 GetReceivedBytes(), | 805 GetReceivedBytes(), |
769 InterruptReasonDebugString(last_reason_).c_str(), | 806 InterruptReasonDebugString(last_reason_).c_str(), |
770 IsPaused() ? 'T' : 'F', | 807 IsPaused() ? 'T' : 'F', |
771 DebugSafetyStateString(GetSafetyState()), | 808 DebugSafetyStateString(GetSafetyState()), |
772 GetLastModifiedTime().c_str(), | 809 GetLastModifiedTime().c_str(), |
773 GetETag().c_str(), | 810 GetETag().c_str(), |
774 url_list.c_str(), | 811 url_list.c_str(), |
775 GetFullPath().value().c_str(), | 812 GetFullPath().value().c_str(), |
776 GetTargetFilePath().value().c_str()); | 813 GetTargetFilePath().value().c_str(), |
814 download_file_.get() ? "true" : "false"); | |
777 } else { | 815 } else { |
778 description += base::StringPrintf(" url = \"%s\"", url_list.c_str()); | 816 description += base::StringPrintf(" url = \"%s\"", url_list.c_str()); |
779 } | 817 } |
780 | 818 |
781 description += " }"; | 819 description += " }"; |
782 | 820 |
783 return description; | 821 return description; |
784 } | 822 } |
785 | 823 |
786 void DownloadItemImpl::MockDownloadOpenForTesting() { | 824 void DownloadItemImpl::MockDownloadOpenForTesting() { |
787 open_enabled_ = false; | 825 open_enabled_ = false; |
788 } | 826 } |
789 | 827 |
790 void DownloadItemImpl::NotifyRemoved() { | 828 void DownloadItemImpl::NotifyRemoved() { |
791 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadRemoved(this)); | 829 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadRemoved(this)); |
792 } | 830 } |
793 | 831 |
794 void DownloadItemImpl::OnDownloadedFileRemoved() { | 832 void DownloadItemImpl::OnDownloadedFileRemoved() { |
795 file_externally_removed_ = true; | 833 file_externally_removed_ = true; |
796 UpdateObservers(); | 834 UpdateObservers(); |
797 } | 835 } |
798 | 836 |
799 void DownloadItemImpl::OffThreadCancel() { | |
800 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
801 request_handle_->CancelRequest(); | |
802 | |
803 BrowserThread::PostTask( | |
804 BrowserThread::FILE, FROM_HERE, | |
805 base::Bind(&DownloadFileManager::CancelDownload, | |
806 delegate_->GetDownloadFileManager(), download_id_)); | |
807 } | |
808 | |
809 // An error occurred somewhere. | 837 // An error occurred somewhere. |
810 void DownloadItemImpl::Interrupt(content::DownloadInterruptReason reason) { | 838 void DownloadItemImpl::Interrupt(content::DownloadInterruptReason reason) { |
811 // Somewhat counter-intuitively, it is possible for us to receive an | 839 // Somewhat counter-intuitively, it is possible for us to receive an |
812 // interrupt after we've already been interrupted. The generation of | 840 // interrupt after we've already been interrupted. The generation of |
813 // interrupts from the file thread Renames and the generation of | 841 // interrupts from the file thread Renames and the generation of |
814 // interrupts from disk writes go through two different mechanisms (driven | 842 // interrupts from disk writes go through two different mechanisms (driven |
815 // by rename requests from UI thread and by write requests from IO thread, | 843 // by rename requests from UI thread and by write requests from IO thread, |
816 // respectively), and since we choose not to keep state on the File thread, | 844 // respectively), and since we choose not to keep state on the File thread, |
817 // this is the place where the races collide. It's also possible for | 845 // this is the place where the races collide. It's also possible for |
818 // interrupts to race with cancels. | 846 // interrupts to race with cancels. |
819 | 847 |
820 // Whatever happens, the first one to hit the UI thread wins. | 848 // Whatever happens, the first one to hit the UI thread wins. |
821 if (state_ != IN_PROGRESS_INTERNAL) | 849 if (state_ != IN_PROGRESS_INTERNAL) |
822 return; | 850 return; |
823 | 851 |
824 last_reason_ = reason; | 852 last_reason_ = reason; |
825 TransitionTo(INTERRUPTED_INTERNAL); | 853 TransitionTo(INTERRUPTED_INTERNAL); |
854 | |
855 // Cancel and remove the download file. | |
856 // TODO(rdsmith/benjhayden): Remove condition as part of | |
857 // SavePackage integration. | |
858 if (!is_save_package_download_) { | |
benjhayden
2012/09/28 20:49:42
Factor this out into a method and share with Cance
Randy Smith (Not in Mondays)
2012/10/09 20:20:19
Done.
| |
859 CHECK(download_file_.get()); | |
860 BrowserThread::PostTask( | |
861 BrowserThread::FILE, FROM_HERE, | |
862 // Will be deleted at end of task execution. | |
863 base::Bind(&DownloadFileCancel, base::Passed(download_file_.Pass()))); | |
864 } | |
865 | |
866 // Cancel the originating URL request. | |
867 request_handle_->CancelRequest(); | |
868 | |
826 download_stats::RecordDownloadInterrupted( | 869 download_stats::RecordDownloadInterrupted( |
827 reason, received_bytes_, total_bytes_); | 870 reason, received_bytes_, total_bytes_); |
828 delegate_->DownloadStopped(this); | 871 delegate_->DownloadStopped(this); |
829 } | 872 } |
830 | 873 |
874 base::WeakPtr<content::DownloadDestinationObserver> | |
875 DownloadItemImpl::DestinationObserverAsWeakPtr() { | |
876 return weak_ptr_factory_.GetWeakPtr(); | |
877 } | |
878 | |
879 bool DownloadItemImpl::IsSavePackageDownload() const { | |
880 return is_save_package_download_; | |
881 } | |
882 | |
831 void DownloadItemImpl::SetTotalBytes(int64 total_bytes) { | 883 void DownloadItemImpl::SetTotalBytes(int64 total_bytes) { |
832 total_bytes_ = total_bytes; | 884 total_bytes_ = total_bytes; |
833 } | 885 } |
834 | 886 |
835 // Updates from the download thread may have been posted while this download | 887 // Updates from the download thread may have been posted while this download |
836 // was being cancelled in the UI thread, so we'll accept them unless we're | 888 // was being cancelled in the UI thread, so we'll accept them unless we're |
837 // complete. | 889 // complete. |
838 void DownloadItemImpl::UpdateProgress(int64 bytes_so_far, | 890 void DownloadItemImpl::UpdateProgress(int64 bytes_so_far, |
839 int64 bytes_per_sec, | 891 int64 bytes_per_sec, |
840 const std::string& hash_state) { | 892 const std::string& hash_state) { |
(...skipping 22 matching lines...) Expand all Loading... | |
863 | 915 |
864 if (bound_net_log_.IsLoggingAllEvents()) { | 916 if (bound_net_log_.IsLoggingAllEvents()) { |
865 bound_net_log_.AddEvent( | 917 bound_net_log_.AddEvent( |
866 net::NetLog::TYPE_DOWNLOAD_ITEM_UPDATED, | 918 net::NetLog::TYPE_DOWNLOAD_ITEM_UPDATED, |
867 net::NetLog::Int64Callback("bytes_so_far", received_bytes_)); | 919 net::NetLog::Int64Callback("bytes_so_far", received_bytes_)); |
868 } | 920 } |
869 | 921 |
870 UpdateObservers(); | 922 UpdateObservers(); |
871 } | 923 } |
872 | 924 |
873 void DownloadItemImpl::OnAllDataSaved( | 925 void DownloadItemImpl::OnAllDataSaved(const std::string& final_hash) { |
874 int64 size, const std::string& final_hash) { | |
875 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 926 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
876 | 927 |
928 DCHECK_EQ(IN_PROGRESS_INTERNAL, state_); | |
877 DCHECK(!all_data_saved_); | 929 DCHECK(!all_data_saved_); |
878 all_data_saved_ = true; | 930 all_data_saved_ = true; |
879 ProgressComplete(size, final_hash); | 931 |
932 // Store final hash and null out intermediate serialized hash state. | |
933 hash_ = final_hash; | |
934 hash_state_ = ""; | |
935 | |
880 UpdateObservers(); | 936 UpdateObservers(); |
881 } | 937 } |
882 | 938 |
883 void DownloadItemImpl::MarkAsComplete() { | 939 void DownloadItemImpl::MarkAsComplete() { |
884 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 940 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
885 | 941 |
886 DCHECK(all_data_saved_); | 942 DCHECK(all_data_saved_); |
887 end_time_ = base::Time::Now(); | 943 end_time_ = base::Time::Now(); |
888 TransitionTo(COMPLETE_INTERNAL); | 944 TransitionTo(COMPLETE_INTERNAL); |
889 } | 945 } |
890 | 946 |
891 void DownloadItemImpl::SetIsPersisted() { | 947 void DownloadItemImpl::SetIsPersisted() { |
892 is_persisted_ = true; | 948 is_persisted_ = true; |
893 UpdateObservers(); | 949 UpdateObservers(); |
894 } | 950 } |
895 | 951 |
896 void DownloadItemImpl::SetDbHandle(int64 handle) { | 952 void DownloadItemImpl::SetDbHandle(int64 handle) { |
897 db_handle_ = handle; | 953 db_handle_ = handle; |
898 | 954 |
899 bound_net_log_.AddEvent( | 955 bound_net_log_.AddEvent( |
900 net::NetLog::TYPE_DOWNLOAD_ITEM_IN_HISTORY, | 956 net::NetLog::TYPE_DOWNLOAD_ITEM_IN_HISTORY, |
901 net::NetLog::Int64Callback("db_handle", db_handle_)); | 957 net::NetLog::Int64Callback("db_handle", db_handle_)); |
902 } | 958 } |
903 | 959 |
960 void DownloadItemImpl::DestinationUpdate(int64 bytes_so_far, | |
961 int64 bytes_per_sec, | |
962 const std::string& hash_state) { | |
963 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
964 | |
965 if (!IsInProgress()) { | |
966 // Ignore if we're no longer in-progress. This can happen if we race a | |
967 // Cancel on the UI thread with an update on the FILE thread. | |
968 // | |
969 // TODO(rdsmith): Arguably we should let this go through, as this means | |
970 // the download really did get further than we know before it was | |
971 // cancelled. But the gain isn't very large, and the code is more | |
972 // fragile if it has to support in progress updates in a non-in-progress | |
973 // state. This issue should be readdressed when we revamp performance | |
974 // reporting. | |
975 return; | |
976 } | |
977 bytes_per_sec_ = bytes_per_sec; | |
978 hash_state_ = hash_state; | |
979 received_bytes_ = bytes_so_far; | |
980 | |
981 // If we've received more data than we were expecting (bad server info?), | |
982 // revert to 'unknown size mode'. | |
983 if (received_bytes_ > total_bytes_) | |
984 total_bytes_ = 0; | |
985 | |
986 if (bound_net_log_.IsLoggingAllEvents()) { | |
987 bound_net_log_.AddEvent( | |
988 net::NetLog::TYPE_DOWNLOAD_ITEM_UPDATED, | |
989 net::NetLog::Int64Callback("bytes_so_far", received_bytes_)); | |
990 } | |
991 | |
992 UpdateObservers(); | |
993 } | |
994 | |
995 void DownloadItemImpl::DestinationError( | |
996 content::DownloadInterruptReason reason) { | |
997 // The DestinationError and Interrupt routines are being kept separate | |
998 // to allow for a future merging of the Cancel and Interrupt routines.. | |
999 Interrupt(reason); | |
1000 } | |
1001 | |
1002 void DownloadItemImpl::DestinationCompleted(const std::string& final_hash) { | |
1003 if (!IsInProgress()) | |
1004 return; | |
1005 OnAllDataSaved(final_hash); | |
1006 delegate_->MaybeCompleteDownload(this); | |
1007 } | |
1008 | |
904 // **** Download progression cascade | 1009 // **** Download progression cascade |
905 | 1010 |
906 void DownloadItemImpl::Init(bool active, | 1011 void DownloadItemImpl::Init(bool active, |
907 download_net_logs::DownloadType download_type) { | 1012 download_net_logs::DownloadType download_type) { |
908 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1013 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
909 | 1014 |
910 if (active) | 1015 if (active) |
911 download_stats::RecordDownloadCount(download_stats::START_COUNT); | 1016 download_stats::RecordDownloadCount(download_stats::START_COUNT); |
912 | 1017 |
913 if (target_path_.empty()) | 1018 if (target_path_.empty()) |
(...skipping 23 matching lines...) Expand all Loading... | |
937 bound_net_log_.AddEvent( | 1042 bound_net_log_.AddEvent( |
938 net::NetLog::TYPE_DOWNLOAD_ITEM_IN_HISTORY, | 1043 net::NetLog::TYPE_DOWNLOAD_ITEM_IN_HISTORY, |
939 net::NetLog::Int64Callback("db_handle", db_handle_)); | 1044 net::NetLog::Int64Callback("db_handle", db_handle_)); |
940 | 1045 |
941 bound_net_log_.EndEvent(net::NetLog::TYPE_DOWNLOAD_ITEM_ACTIVE); | 1046 bound_net_log_.EndEvent(net::NetLog::TYPE_DOWNLOAD_ITEM_ACTIVE); |
942 } | 1047 } |
943 | 1048 |
944 VLOG(20) << __FUNCTION__ << "() " << DebugString(true); | 1049 VLOG(20) << __FUNCTION__ << "() " << DebugString(true); |
945 } | 1050 } |
946 | 1051 |
947 // Called by DownloadManagerImpl when the download target path has been | 1052 // We're starting the download. |
1053 void DownloadItemImpl::Start(scoped_ptr<content::DownloadFile> file) { | |
1054 DCHECK(!download_file_.get()); | |
1055 DCHECK(file.get()); | |
1056 download_file_ = file.Pass(); | |
1057 | |
1058 BrowserThread::PostTask( | |
1059 BrowserThread::FILE, FROM_HERE, | |
1060 base::Bind(&DownloadFile::Initialize, | |
1061 // Safe because we control download file lifetime. | |
1062 base::Unretained(download_file_.get()), | |
1063 base::Bind(&DownloadItemImpl::OnDownloadFileInitialized, | |
1064 weak_ptr_factory_.GetWeakPtr()))); | |
1065 } | |
1066 | |
1067 void DownloadItemImpl::OnDownloadFileInitialized( | |
1068 content::DownloadInterruptReason result) { | |
1069 if (result != content::DOWNLOAD_INTERRUPT_REASON_NONE) { | |
1070 Interrupt(result); | |
1071 // TODO(rdsmith): It makes no sense to continue along the | |
1072 // regular download path after we've gotten an error. But it's | |
1073 // the way the code has historically worked, and this allows us | |
1074 // to get the download persisted and observers of the download manager | |
1075 // notified, so tests work. When we execute all side effects of cancel | |
1076 // (including queue removal) immedately rather than waiting for | |
1077 // persistence we should replace this comment with a "return;". | |
1078 } | |
1079 | |
1080 delegate_->DetermineDownloadTarget( | |
1081 this, base::Bind(&DownloadItemImpl::OnDownloadTargetDetermined, | |
1082 weak_ptr_factory_.GetWeakPtr())); | |
1083 } | |
1084 | |
1085 // Called by delegate_ when the download target path has been | |
948 // determined. | 1086 // determined. |
949 void DownloadItemImpl::OnDownloadTargetDetermined( | 1087 void DownloadItemImpl::OnDownloadTargetDetermined( |
950 const FilePath& target_path, | 1088 const FilePath& target_path, |
951 TargetDisposition disposition, | 1089 TargetDisposition disposition, |
952 content::DownloadDangerType danger_type, | 1090 content::DownloadDangerType danger_type, |
953 const FilePath& intermediate_path) { | 1091 const FilePath& intermediate_path) { |
954 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1092 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
955 | 1093 |
956 // If the |target_path| is empty, then we consider this download to be | 1094 // If the |target_path| is empty, then we consider this download to be |
957 // canceled. | 1095 // canceled. |
(...skipping 20 matching lines...) Expand all Loading... | |
978 // whatever was recorded for consistency. | 1116 // whatever was recorded for consistency. |
979 OnDownloadRenamedToIntermediateName(last_reason_, FilePath()); | 1117 OnDownloadRenamedToIntermediateName(last_reason_, FilePath()); |
980 return; | 1118 return; |
981 } | 1119 } |
982 | 1120 |
983 // Rename to intermediate name. | 1121 // Rename to intermediate name. |
984 // TODO(asanka): Skip this rename if AllDataSaved() is true. This avoids a | 1122 // TODO(asanka): Skip this rename if AllDataSaved() is true. This avoids a |
985 // spurious rename when we can just rename to the final | 1123 // spurious rename when we can just rename to the final |
986 // filename. Unnecessary renames may cause bugs like | 1124 // filename. Unnecessary renames may cause bugs like |
987 // http://crbug.com/74187. | 1125 // http://crbug.com/74187. |
988 DownloadFileManager::RenameCompletionCallback callback = | 1126 DCHECK(!is_save_package_download_); |
1127 CHECK(download_file_.get()); | |
1128 DownloadFile::RenameCompletionCallback callback = | |
989 base::Bind(&DownloadItemImpl::OnDownloadRenamedToIntermediateName, | 1129 base::Bind(&DownloadItemImpl::OnDownloadRenamedToIntermediateName, |
990 weak_ptr_factory_.GetWeakPtr()); | 1130 weak_ptr_factory_.GetWeakPtr()); |
991 BrowserThread::PostTask( | 1131 BrowserThread::PostTask( |
992 BrowserThread::FILE, FROM_HERE, | 1132 BrowserThread::FILE, FROM_HERE, |
993 base::Bind(&DownloadFileManager::RenameDownloadFile, | 1133 base::Bind(&DownloadFile::Rename, |
994 delegate_->GetDownloadFileManager(), GetGlobalId(), | 1134 // Safe because we control download file lifetime. |
1135 base::Unretained(download_file_.get()), | |
995 intermediate_path, false, callback)); | 1136 intermediate_path, false, callback)); |
996 } | 1137 } |
997 | 1138 |
998 void DownloadItemImpl::OnDownloadRenamedToIntermediateName( | 1139 void DownloadItemImpl::OnDownloadRenamedToIntermediateName( |
999 content::DownloadInterruptReason reason, | 1140 content::DownloadInterruptReason reason, |
1000 const FilePath& full_path) { | 1141 const FilePath& full_path) { |
1001 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1142 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1002 if (content::DOWNLOAD_INTERRUPT_REASON_NONE != reason) { | 1143 if (content::DOWNLOAD_INTERRUPT_REASON_NONE != reason) { |
1003 Interrupt(reason); | 1144 Interrupt(reason); |
1004 } else { | 1145 } else { |
(...skipping 16 matching lines...) Expand all Loading... | |
1021 | 1162 |
1022 if (state_ != IN_PROGRESS_INTERNAL) | 1163 if (state_ != IN_PROGRESS_INTERNAL) |
1023 return; | 1164 return; |
1024 | 1165 |
1025 VLOG(20) << __FUNCTION__ << "()" | 1166 VLOG(20) << __FUNCTION__ << "()" |
1026 << " needs rename = " << NeedsRename() | 1167 << " needs rename = " << NeedsRename() |
1027 << " " << DebugString(true); | 1168 << " " << DebugString(true); |
1028 DCHECK(!GetTargetFilePath().empty()); | 1169 DCHECK(!GetTargetFilePath().empty()); |
1029 DCHECK_NE(DANGEROUS, GetSafetyState()); | 1170 DCHECK_NE(DANGEROUS, GetSafetyState()); |
1030 | 1171 |
1172 // TODO(rdsmith/benjhayden): Remove as part of SavePackage integration. | |
1173 if (is_save_package_download_) { | |
1174 // Avoid doing anything on the file thread; there's nothing we control | |
1175 // there. | |
1176 OnDownloadFileReleased(); | |
1177 return; | |
1178 } | |
1179 | |
1180 CHECK(download_file_.get()); | |
1031 if (NeedsRename()) { | 1181 if (NeedsRename()) { |
1032 DownloadFileManager::RenameCompletionCallback callback = | 1182 content::DownloadFile::RenameCompletionCallback callback = |
1033 base::Bind(&DownloadItemImpl::OnDownloadRenamedToFinalName, | 1183 base::Bind(&DownloadItemImpl::OnDownloadRenamedToFinalName, |
1034 weak_ptr_factory_.GetWeakPtr()); | 1184 weak_ptr_factory_.GetWeakPtr()); |
1035 BrowserThread::PostTask( | 1185 BrowserThread::PostTask( |
1036 BrowserThread::FILE, FROM_HERE, | 1186 BrowserThread::FILE, FROM_HERE, |
1037 base::Bind(&DownloadFileManager::RenameDownloadFile, | 1187 base::Bind(&DownloadFile::Rename, |
1038 delegate_->GetDownloadFileManager(), GetGlobalId(), | 1188 base::Unretained(download_file_.get()), |
1039 GetTargetFilePath(), true, callback)); | 1189 GetTargetFilePath(), true, callback)); |
1040 } else { | 1190 } else { |
1041 // Complete the download and release the DownloadFile. | 1191 ReleaseDownloadFile(); |
1042 BrowserThread::PostTask( | |
1043 BrowserThread::FILE, FROM_HERE, | |
1044 base::Bind(&DownloadFileManager::CompleteDownload, | |
1045 delegate_->GetDownloadFileManager(), GetGlobalId(), | |
1046 base::Bind(&DownloadItemImpl::OnDownloadFileReleased, | |
1047 weak_ptr_factory_.GetWeakPtr()))); | |
1048 TransitionTo(COMPLETING_INTERNAL); | |
1049 } | 1192 } |
1050 } | 1193 } |
1051 | 1194 |
1052 void DownloadItemImpl::OnDownloadRenamedToFinalName( | 1195 void DownloadItemImpl::OnDownloadRenamedToFinalName( |
1053 content::DownloadInterruptReason reason, | 1196 content::DownloadInterruptReason reason, |
1054 const FilePath& full_path) { | 1197 const FilePath& full_path) { |
1055 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1198 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1056 | 1199 |
1057 // If a cancel or interrupt hit, we'll cancel the DownloadFile, which | 1200 // If a cancel or interrupt hit, we'll cancel the DownloadFile, which |
1058 // will result in deleting the file on the file thread. So we don't | 1201 // will result in deleting the file on the file thread. So we don't |
(...skipping 11 matching lines...) Expand all Loading... | |
1070 Interrupt(reason); | 1213 Interrupt(reason); |
1071 return; | 1214 return; |
1072 } | 1215 } |
1073 | 1216 |
1074 // full_path is now the current and target file path. | 1217 // full_path is now the current and target file path. |
1075 DCHECK(!full_path.empty()); | 1218 DCHECK(!full_path.empty()); |
1076 target_path_ = full_path; | 1219 target_path_ = full_path; |
1077 SetFullPath(full_path); | 1220 SetFullPath(full_path); |
1078 delegate_->DownloadRenamedToFinalName(this); | 1221 delegate_->DownloadRenamedToFinalName(this); |
1079 | 1222 |
1223 ReleaseDownloadFile(); | |
1224 } | |
1225 | |
1226 void DownloadItemImpl::ReleaseDownloadFile() { | |
1080 // Complete the download and release the DownloadFile. | 1227 // Complete the download and release the DownloadFile. |
1228 DCHECK(!is_save_package_download_); | |
1229 CHECK(download_file_.get()); | |
1081 BrowserThread::PostTask( | 1230 BrowserThread::PostTask( |
1082 BrowserThread::FILE, FROM_HERE, | 1231 BrowserThread::FILE, FROM_HERE, |
1083 base::Bind(&DownloadFileManager::CompleteDownload, | 1232 base::Bind(&DownloadFileDetach, base::Passed(download_file_.Pass()), |
1084 delegate_->GetDownloadFileManager(), GetGlobalId(), | |
1085 base::Bind(&DownloadItemImpl::OnDownloadFileReleased, | 1233 base::Bind(&DownloadItemImpl::OnDownloadFileReleased, |
1086 weak_ptr_factory_.GetWeakPtr()))); | 1234 weak_ptr_factory_.GetWeakPtr()))); |
1235 | |
1236 // We're not completely done with the download item yet, but at this | |
1237 // point we're committed to complete the download. Cancels (or Interrupts, | |
1238 // though it's not clear how they could happen) after this point will be | |
1239 // ignored. | |
1087 TransitionTo(COMPLETING_INTERNAL); | 1240 TransitionTo(COMPLETING_INTERNAL); |
1088 } | 1241 } |
1089 | 1242 |
1090 void DownloadItemImpl::OnDownloadFileReleased() { | 1243 void DownloadItemImpl::OnDownloadFileReleased() { |
1091 if (delegate_->ShouldOpenDownload(this)) | 1244 if (delegate_->ShouldOpenDownload(this)) |
1092 Completed(); | 1245 Completed(); |
1093 else | 1246 else |
1094 delegate_delayed_complete_ = true; | 1247 delegate_delayed_complete_ = true; |
1095 } | 1248 } |
1096 | 1249 |
1097 void DownloadItemImpl::DelayedDownloadOpened(bool auto_opened) { | 1250 void DownloadItemImpl::DelayedDownloadOpened(bool auto_opened) { |
1098 auto_opened_ = auto_opened; | 1251 auto_opened_ = auto_opened; |
1099 Completed(); | 1252 Completed(); |
1253 UpdateObservers(); | |
asanka
2012/09/28 20:22:42
Why is this call necessary?
Randy Smith (Not in Mondays)
2012/10/09 20:20:19
Hmmm. I think it's left-over from before the inte
| |
1100 } | 1254 } |
1101 | 1255 |
1102 void DownloadItemImpl::Completed() { | 1256 void DownloadItemImpl::Completed() { |
1103 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1257 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1104 | 1258 |
1105 VLOG(20) << __FUNCTION__ << "() " << DebugString(false); | 1259 VLOG(20) << __FUNCTION__ << "() " << DebugString(false); |
1106 | 1260 |
1107 DCHECK(all_data_saved_); | 1261 DCHECK(all_data_saved_); |
1108 end_time_ = base::Time::Now(); | 1262 end_time_ = base::Time::Now(); |
1109 TransitionTo(COMPLETE_INTERNAL); | 1263 TransitionTo(COMPLETE_INTERNAL); |
(...skipping 16 matching lines...) Expand all Loading... | |
1126 } | 1280 } |
1127 } | 1281 } |
1128 | 1282 |
1129 // **** End of Download progression cascade | 1283 // **** End of Download progression cascade |
1130 | 1284 |
1131 bool DownloadItemImpl::NeedsRename() const { | 1285 bool DownloadItemImpl::NeedsRename() const { |
1132 DCHECK(target_path_.DirName() == current_path_.DirName()); | 1286 DCHECK(target_path_.DirName() == current_path_.DirName()); |
1133 return target_path_ != current_path_; | 1287 return target_path_ != current_path_; |
1134 } | 1288 } |
1135 | 1289 |
1136 void DownloadItemImpl::ProgressComplete(int64 bytes_so_far, | |
1137 const std::string& final_hash) { | |
1138 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
1139 | |
1140 hash_ = final_hash; | |
1141 hash_state_ = ""; | |
1142 | |
1143 received_bytes_ = bytes_so_far; | |
1144 | |
1145 // If we've received more data than we were expecting (bad server info?), | |
1146 // revert to 'unknown size mode'. | |
1147 if (received_bytes_ > total_bytes_) | |
1148 total_bytes_ = 0; | |
1149 } | |
1150 | |
1151 void DownloadItemImpl::TransitionTo(DownloadInternalState new_state) { | 1290 void DownloadItemImpl::TransitionTo(DownloadInternalState new_state) { |
1152 if (state_ == new_state) | 1291 if (state_ == new_state) |
1153 return; | 1292 return; |
1154 | 1293 |
1155 DownloadInternalState old_state = state_; | 1294 DownloadInternalState old_state = state_; |
1156 state_ = new_state; | 1295 state_ = new_state; |
1157 | 1296 |
1158 switch (state_) { | 1297 switch (state_) { |
1159 case COMPLETING_INTERNAL: | 1298 case COMPLETING_INTERNAL: |
1160 bound_net_log_.AddEvent( | 1299 bound_net_log_.AddEvent( |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1277 return "COMPLETE"; | 1416 return "COMPLETE"; |
1278 case CANCELLED_INTERNAL: | 1417 case CANCELLED_INTERNAL: |
1279 return "CANCELLED"; | 1418 return "CANCELLED"; |
1280 case INTERRUPTED_INTERNAL: | 1419 case INTERRUPTED_INTERNAL: |
1281 return "INTERRUPTED"; | 1420 return "INTERRUPTED"; |
1282 default: | 1421 default: |
1283 NOTREACHED() << "Unknown download state " << state; | 1422 NOTREACHED() << "Unknown download state " << state; |
1284 return "unknown"; | 1423 return "unknown"; |
1285 }; | 1424 }; |
1286 } | 1425 } |
OLD | NEW |