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