Chromium Code Reviews| 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 // interface Start is placed in chronological order with the other | 7 // interface Start is placed in chronological order with the other |
| 8 // (private) routines that together define a DownloadItem's state | 8 // (private) routines that together define a DownloadItem's state |
| 9 // transitions as the download progresses. See "Download progression | 9 // transitions as the download progresses. See "Download progression |
| 10 // cascade" later in this file. | 10 // cascade" later in this file. |
| 11 | 11 |
| 12 // A regular DownloadItem (created for a download in this session of the | 12 // A regular DownloadItem (created for a download in this session of the |
| 13 // browser) normally goes through the following states: | 13 // browser) normally goes through the following states: |
| 14 // * Created (when download starts) | 14 // * Created (when download starts) |
| 15 // * Destination filename determined | 15 // * Destination filename determined |
| 16 // * Entered into the history database. | 16 // * Entered into the history database. |
| 17 // * Made visible in the download shelf. | 17 // * Made visible in the download shelf. |
| 18 // * All the data is saved. Note that the actual data download occurs | 18 // * All the data is saved. Note that the actual data download occurs |
| 19 // in parallel with the above steps, but until those steps are | 19 // in parallel with the above steps, but until those steps are |
| 20 // complete, the state of the data save will be ignored. | 20 // complete, the state of the data save will be ignored. |
| 21 // * Download file is renamed to its final name, and possibly | 21 // * Download file is renamed to its final name, and possibly |
| 22 // auto-opened. | 22 // auto-opened. |
| 23 | 23 |
| 24 #include "content/browser/download/download_item_impl.h" | 24 #include "content/browser/download/download_item_impl.h" |
| 25 | 25 |
| 26 #include <vector> | 26 #include <vector> |
| 27 | 27 |
| 28 #include "base/basictypes.h" | 28 #include "base/basictypes.h" |
| 29 #include "base/bind.h" | 29 #include "base/bind.h" |
| 30 #include "base/command_line.h" | |
| 30 #include "base/file_util.h" | 31 #include "base/file_util.h" |
| 31 #include "base/format_macros.h" | 32 #include "base/format_macros.h" |
| 32 #include "base/logging.h" | 33 #include "base/logging.h" |
| 33 #include "base/metrics/histogram.h" | 34 #include "base/metrics/histogram.h" |
| 34 #include "base/stl_util.h" | 35 #include "base/stl_util.h" |
| 35 #include "base/stringprintf.h" | 36 #include "base/stringprintf.h" |
| 36 #include "base/utf_string_conversions.h" | 37 #include "base/utf_string_conversions.h" |
| 37 #include "content/browser/download/download_create_info.h" | 38 #include "content/browser/download/download_create_info.h" |
| 38 #include "content/browser/download/download_file.h" | 39 #include "content/browser/download/download_file.h" |
| 39 #include "content/browser/download/download_interrupt_reasons_impl.h" | 40 #include "content/browser/download/download_interrupt_reasons_impl.h" |
| 40 #include "content/browser/download/download_item_impl_delegate.h" | 41 #include "content/browser/download/download_item_impl_delegate.h" |
| 41 #include "content/browser/download/download_request_handle.h" | 42 #include "content/browser/download/download_request_handle.h" |
| 42 #include "content/browser/download/download_stats.h" | 43 #include "content/browser/download/download_stats.h" |
| 44 #include "content/browser/renderer_host/render_view_host_impl.h" | |
| 43 #include "content/browser/web_contents/web_contents_impl.h" | 45 #include "content/browser/web_contents/web_contents_impl.h" |
| 46 #include "content/public/browser/browser_context.h" | |
| 44 #include "content/public/browser/browser_thread.h" | 47 #include "content/public/browser/browser_thread.h" |
| 45 #include "content/public/browser/content_browser_client.h" | 48 #include "content/public/browser/content_browser_client.h" |
| 49 #include "content/public/browser/download_interrupt_reasons.h" | |
| 50 #include "content/public/browser/download_url_parameters.h" | |
| 51 #include "content/public/common/content_switches.h" | |
| 52 #include "content/public/common/referrer.h" | |
| 46 #include "net/base/net_util.h" | 53 #include "net/base/net_util.h" |
| 47 | 54 |
| 48 namespace content { | 55 namespace content { |
| 56 | |
| 49 namespace { | 57 namespace { |
| 50 | 58 |
| 51 static void DeleteDownloadedFile(const FilePath& path) { | 59 void DeleteDownloadedFile(const FilePath& path) { |
| 52 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 60 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 53 | 61 |
| 54 // Make sure we only delete files. | 62 // Make sure we only delete files. |
| 55 if (!file_util::DirectoryExists(path)) | 63 if (!file_util::DirectoryExists(path)) |
| 56 file_util::Delete(path, false); | 64 file_util::Delete(path, false); |
| 57 } | 65 } |
| 58 | 66 |
| 59 const char* DebugSafetyStateString(DownloadItem::SafetyState state) { | 67 const char* DebugSafetyStateString(DownloadItem::SafetyState state) { |
| 60 switch (state) { | 68 switch (state) { |
| 61 case DownloadItem::SAFE: | 69 case DownloadItem::SAFE: |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 104 | 112 |
| 105 static void DownloadFileCancel(scoped_ptr<DownloadFile> download_file) { | 113 static void DownloadFileCancel(scoped_ptr<DownloadFile> download_file) { |
| 106 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 114 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 107 download_file->Cancel(); | 115 download_file->Cancel(); |
| 108 } | 116 } |
| 109 | 117 |
| 110 } // namespace | 118 } // namespace |
| 111 | 119 |
| 112 const char DownloadItem::kEmptyFileHash[] = ""; | 120 const char DownloadItem::kEmptyFileHash[] = ""; |
| 113 | 121 |
| 122 // The maximum number of attempts we will make to resume automatically. | |
| 123 const int DownloadItemImpl::kMaxAutoResumeAttempts = 5; | |
| 124 | |
| 114 // Constructor for reading from the history service. | 125 // Constructor for reading from the history service. |
| 115 DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate, | 126 DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate, |
| 116 DownloadId download_id, | 127 DownloadId download_id, |
| 117 const FilePath& path, | 128 const FilePath& path, |
| 118 const GURL& url, | 129 const GURL& url, |
| 119 const GURL& referrer_url, | 130 const GURL& referrer_url, |
| 120 const base::Time& start_time, | 131 const base::Time& start_time, |
| 121 const base::Time& end_time, | 132 const base::Time& end_time, |
| 122 int64 received_bytes, | 133 int64 received_bytes, |
| 123 int64 total_bytes, | 134 int64 total_bytes, |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 137 received_bytes_(received_bytes), | 148 received_bytes_(received_bytes), |
| 138 bytes_per_sec_(0), | 149 bytes_per_sec_(0), |
| 139 last_reason_(DOWNLOAD_INTERRUPT_REASON_NONE), | 150 last_reason_(DOWNLOAD_INTERRUPT_REASON_NONE), |
| 140 start_tick_(base::TimeTicks()), | 151 start_tick_(base::TimeTicks()), |
| 141 state_(ExternalToInternalState(state)), | 152 state_(ExternalToInternalState(state)), |
| 142 danger_type_(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS), | 153 danger_type_(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS), |
| 143 start_time_(start_time), | 154 start_time_(start_time), |
| 144 end_time_(end_time), | 155 end_time_(end_time), |
| 145 delegate_(delegate), | 156 delegate_(delegate), |
| 146 is_paused_(false), | 157 is_paused_(false), |
| 158 auto_resume_count_(0), | |
| 147 open_when_complete_(false), | 159 open_when_complete_(false), |
| 148 file_externally_removed_(false), | 160 file_externally_removed_(false), |
| 149 safety_state_(SAFE), | 161 safety_state_(SAFE), |
| 150 auto_opened_(false), | 162 auto_opened_(false), |
| 151 is_temporary_(false), | 163 is_temporary_(false), |
| 152 all_data_saved_(false), | 164 all_data_saved_(false), |
| 153 opened_(opened), | 165 opened_(opened), |
| 154 open_enabled_(true), | 166 open_enabled_(true), |
| 155 delegate_delayed_complete_(false), | 167 delegate_delayed_complete_(false), |
| 156 bound_net_log_(bound_net_log), | 168 bound_net_log_(bound_net_log), |
| 157 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { | 169 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { |
| 158 delegate_->Attach(); | 170 delegate_->Attach(); |
| 159 if (state_ == IN_PROGRESS_INTERNAL) | 171 if (state_ == IN_PROGRESS_INTERNAL) |
| 160 state_ = CANCELLED_INTERNAL; | 172 state_ = CANCELLED_INTERNAL; |
| 161 if (state_ == COMPLETE_INTERNAL) | 173 if (state_ == COMPLETE_INTERNAL) |
| 162 all_data_saved_ = true; | 174 all_data_saved_ = true; |
| 163 Init(false /* not actively downloading */, SRC_HISTORY_IMPORT); | 175 Init(false /* not actively downloading */, SRC_HISTORY_IMPORT); |
| 164 } | 176 } |
| 165 | 177 |
| 166 // Constructing for a regular download: | 178 // Constructing for a regular download: |
| 167 DownloadItemImpl::DownloadItemImpl( | 179 DownloadItemImpl::DownloadItemImpl( |
| 168 DownloadItemImplDelegate* delegate, | 180 DownloadItemImplDelegate* delegate, |
| 169 const DownloadCreateInfo& info, | 181 const DownloadCreateInfo& info, |
| 170 scoped_ptr<DownloadRequestHandleInterface> request_handle, | |
| 171 const net::BoundNetLog& bound_net_log) | 182 const net::BoundNetLog& bound_net_log) |
| 172 : is_save_package_download_(false), | 183 : is_save_package_download_(false), |
| 173 request_handle_(request_handle.Pass()), | |
| 174 download_id_(info.download_id), | 184 download_id_(info.download_id), |
| 175 target_disposition_( | 185 target_disposition_( |
| 176 (info.save_info->prompt_for_save_location) ? | 186 (info.save_info->prompt_for_save_location) ? |
| 177 TARGET_DISPOSITION_PROMPT : TARGET_DISPOSITION_OVERWRITE), | 187 TARGET_DISPOSITION_PROMPT : TARGET_DISPOSITION_OVERWRITE), |
| 178 url_chain_(info.url_chain), | 188 url_chain_(info.url_chain), |
| 179 referrer_url_(info.referrer_url), | 189 referrer_url_(info.referrer_url), |
| 180 suggested_filename_(UTF16ToUTF8(info.save_info->suggested_name)), | 190 suggested_filename_(UTF16ToUTF8(info.save_info->suggested_name)), |
| 181 forced_file_path_(info.save_info->file_path), | 191 forced_file_path_(info.save_info->file_path), |
| 182 transition_type_(info.transition_type), | 192 transition_type_(info.transition_type), |
| 183 has_user_gesture_(info.has_user_gesture), | 193 has_user_gesture_(info.has_user_gesture), |
| 184 content_disposition_(info.content_disposition), | 194 content_disposition_(info.content_disposition), |
| 185 mime_type_(info.mime_type), | 195 mime_type_(info.mime_type), |
| 186 original_mime_type_(info.original_mime_type), | 196 original_mime_type_(info.original_mime_type), |
| 187 remote_address_(info.remote_address), | 197 remote_address_(info.remote_address), |
| 188 total_bytes_(info.total_bytes), | 198 total_bytes_(info.total_bytes), |
| 189 received_bytes_(0), | 199 received_bytes_(0), |
| 190 bytes_per_sec_(0), | 200 bytes_per_sec_(0), |
| 191 last_reason_(DOWNLOAD_INTERRUPT_REASON_NONE), | 201 last_reason_(DOWNLOAD_INTERRUPT_REASON_NONE), |
| 192 start_tick_(base::TimeTicks::Now()), | 202 start_tick_(base::TimeTicks::Now()), |
| 193 state_(IN_PROGRESS_INTERNAL), | 203 state_(IN_PROGRESS_INTERNAL), |
| 194 danger_type_(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS), | 204 danger_type_(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS), |
| 195 start_time_(info.start_time), | 205 start_time_(info.start_time), |
| 196 delegate_(delegate), | 206 delegate_(delegate), |
| 197 is_paused_(false), | 207 is_paused_(false), |
| 208 auto_resume_count_(0), | |
| 198 open_when_complete_(false), | 209 open_when_complete_(false), |
| 199 file_externally_removed_(false), | 210 file_externally_removed_(false), |
| 200 safety_state_(SAFE), | 211 safety_state_(SAFE), |
| 201 auto_opened_(false), | 212 auto_opened_(false), |
| 202 is_temporary_(!info.save_info->file_path.empty()), | 213 is_temporary_(!info.save_info->file_path.empty()), |
| 203 all_data_saved_(false), | 214 all_data_saved_(false), |
| 204 opened_(false), | 215 opened_(false), |
| 205 open_enabled_(true), | 216 open_enabled_(true), |
| 206 delegate_delayed_complete_(false), | 217 delegate_delayed_complete_(false), |
| 207 bound_net_log_(bound_net_log), | 218 bound_net_log_(bound_net_log), |
| 208 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { | 219 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { |
| 209 delegate_->Attach(); | 220 delegate_->Attach(); |
| 210 Init(true /* actively downloading */, SRC_NEW_DOWNLOAD); | 221 Init(true /* actively downloading */, SRC_ACTIVE_DOWNLOAD); |
| 211 | 222 |
| 212 // Link the event sources. | 223 // Link the event sources. |
| 213 bound_net_log_.AddEvent( | 224 bound_net_log_.AddEvent( |
| 214 net::NetLog::TYPE_DOWNLOAD_URL_REQUEST, | 225 net::NetLog::TYPE_DOWNLOAD_URL_REQUEST, |
| 215 info.request_bound_net_log.source().ToEventParametersCallback()); | 226 info.request_bound_net_log.source().ToEventParametersCallback()); |
| 216 | 227 |
| 217 info.request_bound_net_log.AddEvent( | 228 info.request_bound_net_log.AddEvent( |
| 218 net::NetLog::TYPE_DOWNLOAD_STARTED, | 229 net::NetLog::TYPE_DOWNLOAD_STARTED, |
| 219 bound_net_log_.source().ToEventParametersCallback()); | 230 bound_net_log_.source().ToEventParametersCallback()); |
| 220 } | 231 } |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 241 total_bytes_(0), | 252 total_bytes_(0), |
| 242 received_bytes_(0), | 253 received_bytes_(0), |
| 243 bytes_per_sec_(0), | 254 bytes_per_sec_(0), |
| 244 last_reason_(DOWNLOAD_INTERRUPT_REASON_NONE), | 255 last_reason_(DOWNLOAD_INTERRUPT_REASON_NONE), |
| 245 start_tick_(base::TimeTicks::Now()), | 256 start_tick_(base::TimeTicks::Now()), |
| 246 state_(IN_PROGRESS_INTERNAL), | 257 state_(IN_PROGRESS_INTERNAL), |
| 247 danger_type_(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS), | 258 danger_type_(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS), |
| 248 start_time_(base::Time::Now()), | 259 start_time_(base::Time::Now()), |
| 249 delegate_(delegate), | 260 delegate_(delegate), |
| 250 is_paused_(false), | 261 is_paused_(false), |
| 262 auto_resume_count_(0), | |
| 251 open_when_complete_(false), | 263 open_when_complete_(false), |
| 252 file_externally_removed_(false), | 264 file_externally_removed_(false), |
| 253 safety_state_(SAFE), | 265 safety_state_(SAFE), |
| 254 auto_opened_(false), | 266 auto_opened_(false), |
| 255 is_temporary_(false), | 267 is_temporary_(false), |
| 256 all_data_saved_(false), | 268 all_data_saved_(false), |
| 257 opened_(false), | 269 opened_(false), |
| 258 open_enabled_(true), | 270 open_enabled_(true), |
| 259 delegate_delayed_complete_(false), | 271 delegate_delayed_complete_(false), |
| 260 bound_net_log_(bound_net_log), | 272 bound_net_log_(bound_net_log), |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 314 base::Bind(&ItemCheckedNetLogCallback, | 326 base::Bind(&ItemCheckedNetLogCallback, |
| 315 GetDangerType(), GetSafetyState())); | 327 GetDangerType(), GetSafetyState())); |
| 316 | 328 |
| 317 UpdateObservers(); | 329 UpdateObservers(); |
| 318 | 330 |
| 319 MaybeCompleteDownload(); | 331 MaybeCompleteDownload(); |
| 320 } | 332 } |
| 321 | 333 |
| 322 void DownloadItemImpl::TogglePause() { | 334 void DownloadItemImpl::TogglePause() { |
| 323 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 335 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 324 DCHECK(state_ == IN_PROGRESS_INTERNAL || state_ == COMPLETING_INTERNAL); | 336 DCHECK(IsPartialDownload()); |
| 325 VLOG(20) << __FUNCTION__ << " download=" << DebugString(true); | 337 VLOG(20) << __FUNCTION__ << " download=" << DebugString(true); |
| 326 | 338 |
| 327 // Ignore pauses when we've passed the commit point. | 339 // Ignore pauses when we've passed the commit point. |
| 328 if (state_ == COMPLETING_INTERNAL) | 340 if (state_ == COMPLETING_INTERNAL) |
| 329 return; | 341 return; |
| 330 | 342 |
| 331 if (is_paused_) | 343 if (IsInProgress()) { |
| 332 request_handle_->ResumeRequest(); | 344 if (is_paused_) |
| 333 else | 345 request_handle_->ResumeRequest(); |
| 334 request_handle_->PauseRequest(); | 346 else |
| 335 is_paused_ = !is_paused_; | 347 request_handle_->PauseRequest(); |
| 348 is_paused_ = !is_paused_; | |
| 349 } else if (IsInterrupted()) { | |
| 350 auto_resume_count_ = 0; // User input resets the counter. | |
| 351 ResumeInterruptedDownload(); | |
| 352 } | |
| 353 | |
| 336 UpdateObservers(); | 354 UpdateObservers(); |
|
benjhayden
2013/01/06 15:46:04
Do we want to UpdateObservers even if !IsInProgres
Randy Smith (Not in Mondays)
2013/01/07 20:54:10
Good point; done.
| |
| 337 } | 355 } |
| 338 | 356 |
| 339 void DownloadItemImpl::Cancel(bool user_cancel) { | 357 void DownloadItemImpl::Cancel(bool user_cancel) { |
| 340 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 358 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 341 | 359 |
| 342 last_reason_ = user_cancel ? | |
| 343 DOWNLOAD_INTERRUPT_REASON_USER_CANCELED : | |
| 344 DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN; | |
| 345 | |
| 346 VLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); | 360 VLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); |
| 347 if (state_ != IN_PROGRESS_INTERNAL) { | 361 if (state_ != IN_PROGRESS_INTERNAL && state_ != INTERRUPTED_INTERNAL) { |
| 348 // Small downloads might be complete before this method has | 362 // Small downloads might be complete before this method has |
| 349 // a chance to run. | 363 // a chance to run. |
| 350 return; | 364 return; |
| 351 } | 365 } |
| 352 | 366 |
| 367 last_reason_ = user_cancel ? | |
| 368 DOWNLOAD_INTERRUPT_REASON_USER_CANCELED : | |
| 369 DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN; | |
| 370 | |
| 353 RecordDownloadCount(CANCELLED_COUNT); | 371 RecordDownloadCount(CANCELLED_COUNT); |
| 354 | 372 |
| 355 TransitionTo(CANCELLED_INTERNAL); | 373 TransitionTo(CANCELLED_INTERNAL); |
| 356 | 374 |
| 357 CancelDownloadFile(); | 375 CancelDownloadFile(); |
| 358 | 376 |
| 359 // Cancel the originating URL request. | 377 // Cancel the originating URL request. |
| 360 request_handle_->CancelRequest(); | 378 request_handle_->CancelRequest(); |
| 361 } | 379 } |
| 362 | 380 |
| 363 void DownloadItemImpl::Delete(DeleteReason reason) { | 381 void DownloadItemImpl::Delete(DeleteReason reason) { |
| 382 VLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); | |
| 364 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 383 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 365 | 384 |
| 366 switch (reason) { | 385 switch (reason) { |
| 367 case DELETE_DUE_TO_USER_DISCARD: | 386 case DELETE_DUE_TO_USER_DISCARD: |
| 368 UMA_HISTOGRAM_ENUMERATION( | 387 UMA_HISTOGRAM_ENUMERATION( |
| 369 "Download.UserDiscard", GetDangerType(), | 388 "Download.UserDiscard", GetDangerType(), |
| 370 DOWNLOAD_DANGER_TYPE_MAX); | 389 DOWNLOAD_DANGER_TYPE_MAX); |
| 371 break; | 390 break; |
| 372 case DELETE_DUE_TO_BROWSER_SHUTDOWN: | 391 case DELETE_DUE_TO_BROWSER_SHUTDOWN: |
| 373 UMA_HISTOGRAM_ENUMERATION( | 392 UMA_HISTOGRAM_ENUMERATION( |
| 374 "Download.Discard", GetDangerType(), | 393 "Download.Discard", GetDangerType(), |
| 375 DOWNLOAD_DANGER_TYPE_MAX); | 394 DOWNLOAD_DANGER_TYPE_MAX); |
| 376 break; | 395 break; |
| 377 default: | 396 default: |
| 378 NOTREACHED(); | 397 NOTREACHED(); |
| 379 } | 398 } |
| 380 | 399 |
| 381 // Delete the file if it exists and is not owned by a DownloadFile object. | 400 // Delete the file if it exists and is not owned by a DownloadFile object. |
| 382 // (In the latter case the DownloadFile object will delete it on cancel.) | 401 // (In the latter case the DownloadFile object will delete it on cancel.) |
| 383 if (!current_path_.empty() && download_file_.get() == NULL) { | 402 if (!current_path_.empty() && download_file_.get() == NULL) { |
| 384 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 403 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| 385 base::Bind(&DeleteDownloadedFile, current_path_)); | 404 base::Bind(&DeleteDownloadedFile, current_path_)); |
| 386 } | 405 } |
| 387 Remove(); | 406 Remove(); |
| 388 // We have now been deleted. | 407 // We have now been deleted. |
| 389 } | 408 } |
| 390 | 409 |
| 391 void DownloadItemImpl::Remove() { | 410 void DownloadItemImpl::Remove() { |
| 411 VLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); | |
| 392 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 412 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 393 | 413 |
| 394 delegate_->AssertStateConsistent(this); | 414 delegate_->AssertStateConsistent(this); |
| 395 Cancel(true); | 415 Cancel(true); |
| 396 delegate_->AssertStateConsistent(this); | 416 delegate_->AssertStateConsistent(this); |
| 397 | 417 |
| 398 NotifyRemoved(); | 418 NotifyRemoved(); |
| 399 delegate_->DownloadRemoved(this); | 419 delegate_->DownloadRemoved(this); |
| 400 // We have now been deleted. | 420 // We have now been deleted. |
| 401 } | 421 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 455 } | 475 } |
| 456 | 476 |
| 457 bool DownloadItemImpl::IsPaused() const { | 477 bool DownloadItemImpl::IsPaused() const { |
| 458 return is_paused_; | 478 return is_paused_; |
| 459 } | 479 } |
| 460 | 480 |
| 461 bool DownloadItemImpl::IsTemporary() const { | 481 bool DownloadItemImpl::IsTemporary() const { |
| 462 return is_temporary_; | 482 return is_temporary_; |
| 463 } | 483 } |
| 464 | 484 |
| 465 // TODO(ahendrickson) -- Move |INTERRUPTED| from |IsCancelled()| to | |
| 466 // |IsPartialDownload()|, when resuming interrupted downloads is implemented. | |
| 467 bool DownloadItemImpl::IsPartialDownload() const { | 485 bool DownloadItemImpl::IsPartialDownload() const { |
| 468 return InternalToExternalState(state_) == IN_PROGRESS; | 486 DownloadState state = InternalToExternalState(state_); |
| 487 return (state == IN_PROGRESS) || (state == INTERRUPTED); | |
| 469 } | 488 } |
| 470 | 489 |
| 471 bool DownloadItemImpl::IsInProgress() const { | 490 bool DownloadItemImpl::IsInProgress() const { |
| 472 return InternalToExternalState(state_) == IN_PROGRESS; | 491 return InternalToExternalState(state_) == IN_PROGRESS; |
| 473 } | 492 } |
| 474 | 493 |
| 475 bool DownloadItemImpl::IsCancelled() const { | 494 bool DownloadItemImpl::IsCancelled() const { |
| 476 DownloadState external_state = InternalToExternalState(state_); | 495 return InternalToExternalState(state_) == CANCELLED; |
| 477 return external_state == CANCELLED || external_state == INTERRUPTED; | |
| 478 } | 496 } |
| 479 | 497 |
| 480 bool DownloadItemImpl::IsInterrupted() const { | 498 bool DownloadItemImpl::IsInterrupted() const { |
| 481 return InternalToExternalState(state_) == INTERRUPTED; | 499 return InternalToExternalState(state_) == INTERRUPTED; |
| 482 } | 500 } |
| 483 | 501 |
| 484 bool DownloadItemImpl::IsComplete() const { | 502 bool DownloadItemImpl::IsComplete() const { |
| 485 return InternalToExternalState(state_) == COMPLETE; | 503 return InternalToExternalState(state_) == COMPLETE; |
| 486 } | 504 } |
| 487 | 505 |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 743 url_list += next_url.spec(); | 761 url_list += next_url.spec(); |
| 744 } | 762 } |
| 745 } | 763 } |
| 746 | 764 |
| 747 if (verbose) { | 765 if (verbose) { |
| 748 description += base::StringPrintf( | 766 description += base::StringPrintf( |
| 749 " total = %" PRId64 | 767 " total = %" PRId64 |
| 750 " received = %" PRId64 | 768 " received = %" PRId64 |
| 751 " reason = %s" | 769 " reason = %s" |
| 752 " paused = %c" | 770 " paused = %c" |
| 771 " resume_mode = %s" | |
| 772 " auto_resume_count = %d" | |
| 753 " safety = %s" | 773 " safety = %s" |
| 774 " all_data_saved = %c" | |
| 754 " last_modified = '%s'" | 775 " last_modified = '%s'" |
| 755 " etag = '%s'" | 776 " etag = '%s'" |
| 777 " has_download_file = %s" | |
| 756 " url_chain = \n\t\"%s\"\n\t" | 778 " url_chain = \n\t\"%s\"\n\t" |
| 757 " full_path = \"%" PRFilePath "\"" | 779 " full_path = \"%" PRFilePath "\"\n\t" |
| 758 " target_path = \"%" PRFilePath "\"" | 780 " target_path = \"%" PRFilePath "\"", |
| 759 " has download file = %s", | |
| 760 GetTotalBytes(), | 781 GetTotalBytes(), |
| 761 GetReceivedBytes(), | 782 GetReceivedBytes(), |
| 762 InterruptReasonDebugString(last_reason_).c_str(), | 783 InterruptReasonDebugString(last_reason_).c_str(), |
| 763 IsPaused() ? 'T' : 'F', | 784 IsPaused() ? 'T' : 'F', |
| 785 DebugResumeModeString(GetResumeMode()), | |
| 786 auto_resume_count_, | |
| 764 DebugSafetyStateString(GetSafetyState()), | 787 DebugSafetyStateString(GetSafetyState()), |
| 788 AllDataSaved() ? 'T' : 'F', | |
| 765 GetLastModifiedTime().c_str(), | 789 GetLastModifiedTime().c_str(), |
| 766 GetETag().c_str(), | 790 GetETag().c_str(), |
| 791 download_file_.get() ? "true" : "false", | |
| 767 url_list.c_str(), | 792 url_list.c_str(), |
| 768 GetFullPath().value().c_str(), | 793 GetFullPath().value().c_str(), |
| 769 GetTargetFilePath().value().c_str(), | 794 GetTargetFilePath().value().c_str()); |
| 770 download_file_.get() ? "true" : "false"); | |
| 771 } else { | 795 } else { |
| 772 description += base::StringPrintf(" url = \"%s\"", url_list.c_str()); | 796 description += base::StringPrintf(" url = \"%s\"", url_list.c_str()); |
| 773 } | 797 } |
| 774 | 798 |
| 775 description += " }"; | 799 description += " }"; |
| 776 | 800 |
| 777 return description; | 801 return description; |
| 778 } | 802 } |
| 779 | 803 |
| 780 void DownloadItemImpl::MockDownloadOpenForTesting() { | 804 void DownloadItemImpl::MockDownloadOpenForTesting() { |
| 781 open_enabled_ = false; | 805 open_enabled_ = false; |
| 782 } | 806 } |
| 783 | 807 |
| 808 DownloadItemImpl::ResumeMode DownloadItemImpl::GetResumeMode() const { | |
| 809 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 810 if (!IsInterrupted()) | |
| 811 return RESUME_MODE_INVALID; | |
| 812 | |
| 813 ResumeMode mode = RESUME_MODE_INVALID; | |
| 814 | |
| 815 switch(last_reason_) { | |
| 816 case DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR: | |
| 817 case DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT: | |
| 818 mode = RESUME_MODE_IMMEDIATE_CONTINUE; // Continue immediately. | |
|
benjhayden
2013/01/06 15:46:04
These comments look unnecessary.
Randy Smith (Not in Mondays)
2013/01/07 20:54:10
Done.
| |
| 819 break; | |
| 820 | |
| 821 case DOWNLOAD_INTERRUPT_REASON_SERVER_PRECONDITION: | |
| 822 case DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE: | |
| 823 case DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT: | |
| 824 mode = RESUME_MODE_IMMEDIATE_RESTART; // Restart immediately. | |
| 825 break; | |
| 826 | |
| 827 case DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED: | |
| 828 case DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED: | |
| 829 case DOWNLOAD_INTERRUPT_REASON_NETWORK_SERVER_DOWN: | |
| 830 case DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED: | |
| 831 case DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN: | |
| 832 case DOWNLOAD_INTERRUPT_REASON_CRASH: | |
| 833 mode = RESUME_MODE_USER_CONTINUE; // Continue via user input. | |
| 834 break; | |
| 835 | |
| 836 case DOWNLOAD_INTERRUPT_REASON_FILE_FAILED: | |
| 837 case DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED: | |
| 838 case DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE: | |
| 839 case DOWNLOAD_INTERRUPT_REASON_FILE_NAME_TOO_LONG: | |
| 840 case DOWNLOAD_INTERRUPT_REASON_FILE_TOO_LARGE: | |
| 841 mode = RESUME_MODE_USER_RESTART; // Restart via user input. | |
| 842 break; | |
| 843 | |
| 844 case DOWNLOAD_INTERRUPT_REASON_NONE: | |
| 845 case DOWNLOAD_INTERRUPT_REASON_FILE_VIRUS_INFECTED: | |
| 846 case DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT: | |
| 847 case DOWNLOAD_INTERRUPT_REASON_USER_CANCELED: | |
| 848 break; | |
|
benjhayden
2013/01/06 15:46:04
Merge this fall-through with the next?
Maybe expli
Randy Smith (Not in Mondays)
2013/01/07 20:54:10
Done.
| |
| 849 | |
| 850 case DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED: | |
| 851 case DOWNLOAD_INTERRUPT_REASON_FILE_SECURITY_CHECK_FAILED: | |
| 852 break; | |
| 853 } | |
| 854 | |
| 855 // If we don't have a file name, we won't be able to continue the | |
| 856 // download (e.g. if we're interrupted before intermediate rename). | |
| 857 if (current_path_.empty()) { | |
| 858 if (mode == RESUME_MODE_USER_CONTINUE) | |
| 859 mode = RESUME_MODE_USER_RESTART; | |
|
benjhayden
2013/01/06 15:46:04
How would you feel about trying to merge these exc
Randy Smith (Not in Mondays)
2013/01/07 20:54:10
This was an amusing exercise in "what's the simple
| |
| 860 if (mode == RESUME_MODE_IMMEDIATE_CONTINUE) | |
|
benjhayden
2013/01/06 15:46:04
else if
Randy Smith (Not in Mondays)
2013/01/07 20:54:10
Moot.
| |
| 861 mode = RESUME_MODE_IMMEDIATE_RESTART; | |
| 862 } | |
| 863 | |
| 864 // Check if we have exhausted the number of automatic retry attempts. | |
| 865 // We also force user interaction if the user previously paused the | |
| 866 // download. | |
| 867 if (auto_resume_count_ >= kMaxAutoResumeAttempts || is_paused_) { | |
| 868 if (mode == RESUME_MODE_IMMEDIATE_CONTINUE) | |
| 869 mode = RESUME_MODE_USER_CONTINUE; | |
| 870 else if (mode == RESUME_MODE_IMMEDIATE_RESTART) | |
| 871 mode = RESUME_MODE_USER_RESTART; | |
| 872 } | |
| 873 | |
| 874 return mode; | |
| 875 } | |
| 876 | |
| 877 void DownloadItemImpl::ResumeInterruptedDownload() { | |
| 878 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 879 | |
| 880 // If the flag for downloads resumption isn't enabled, ignore | |
|
benjhayden
2013/01/06 15:46:04
Would it make more sense to just not show the resu
Randy Smith (Not in Mondays)
2013/01/07 20:54:10
"Do not try to tweak the resume button. Only try
| |
| 881 // this request. | |
| 882 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | |
| 883 if (!command_line.HasSwitch(switches::kEnableDownloadResumption)) | |
| 884 return; | |
| 885 | |
| 886 // Handle the case of clicking 'Resume' in the download shelf. | |
| 887 DCHECK(IsInterrupted()); | |
| 888 | |
| 889 DVLOG(20) << __FUNCTION__ << "()" << DebugString(true); | |
| 890 | |
| 891 // If we can't get a web contents, we can't resume the download. | |
| 892 // TODO(rdsmith): Find some alternative web contents to use--this | |
| 893 // means we can't restart a download if it's a download imported | |
| 894 // from the history. | |
| 895 if (!GetWebContents()) | |
| 896 return; | |
| 897 | |
| 898 // Reset the apporpriate state if restarting. | |
|
benjhayden
2013/01/06 15:46:04
"appROpriate", and at least one of this comment an
Randy Smith (Not in Mondays)
2013/01/07 20:54:10
Done.
| |
| 899 ResumeMode mode = GetResumeMode(); | |
| 900 if (mode == RESUME_MODE_IMMEDIATE_RESTART || | |
| 901 mode == RESUME_MODE_USER_RESTART) { | |
| 902 received_bytes_ = 0; // Restart instead of continuing. | |
| 903 hash_state_ = ""; | |
| 904 last_modified_time_ = ""; | |
| 905 etag_ = ""; | |
| 906 } | |
| 907 | |
| 908 scoped_ptr<DownloadUrlParameters> download_params( | |
| 909 DownloadUrlParameters::FromWebContents(GetWebContents(), | |
| 910 GetOriginalUrl())); | |
| 911 | |
| 912 download_params->set_file_path(GetFullPath()); | |
| 913 download_params->set_offset(GetReceivedBytes()); | |
| 914 download_params->set_hash_state(GetHashState()); | |
| 915 | |
| 916 Referrer referrer(GetReferrerUrl(), WebKit::WebReferrerPolicyDefault); | |
| 917 download_params->set_referrer(referrer); | |
| 918 download_params->set_last_modified(GetLastModifiedTime()); | |
| 919 download_params->set_etag(GetETag()); | |
| 920 download_params->set_callback(DownloadUrlParameters::OnStartedCallback()); | |
| 921 | |
| 922 delegate_->ResumeInterruptedDownload(download_params.Pass(), GetGlobalId()); | |
|
benjhayden
2013/01/06 15:46:04
Should the id be inside DownloadUrlParams?
Why use
Randy Smith (Not in Mondays)
2013/01/07 20:54:10
I was going to make some vague statements based on
| |
| 923 | |
| 924 // Just in case we were interrupted while paused. | |
| 925 is_paused_ = false; | |
| 926 } | |
| 927 | |
| 784 void DownloadItemImpl::NotifyRemoved() { | 928 void DownloadItemImpl::NotifyRemoved() { |
| 785 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadRemoved(this)); | 929 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadRemoved(this)); |
| 786 } | 930 } |
| 787 | 931 |
| 788 void DownloadItemImpl::OnDownloadedFileRemoved() { | 932 void DownloadItemImpl::OnDownloadedFileRemoved() { |
| 789 file_externally_removed_ = true; | 933 file_externally_removed_ = true; |
| 790 VLOG(20) << __FUNCTION__ << " download=" << DebugString(true); | 934 VLOG(20) << __FUNCTION__ << " download=" << DebugString(true); |
| 791 UpdateObservers(); | 935 UpdateObservers(); |
| 792 } | 936 } |
| 793 | 937 |
| 794 base::WeakPtr<DownloadDestinationObserver> | 938 base::WeakPtr<DownloadDestinationObserver> |
| 795 DownloadItemImpl::DestinationObserverAsWeakPtr() { | 939 DownloadItemImpl::DestinationObserverAsWeakPtr() { |
| 796 return weak_ptr_factory_.GetWeakPtr(); | 940 return weak_ptr_factory_.GetWeakPtr(); |
| 797 } | 941 } |
| 798 | 942 |
| 943 const net::BoundNetLog& DownloadItemImpl::GetBoundNetLog() const { | |
| 944 return bound_net_log_; | |
| 945 } | |
| 946 | |
| 799 void DownloadItemImpl::SetTotalBytes(int64 total_bytes) { | 947 void DownloadItemImpl::SetTotalBytes(int64 total_bytes) { |
| 800 total_bytes_ = total_bytes; | 948 total_bytes_ = total_bytes; |
| 801 } | 949 } |
| 802 | 950 |
| 803 // Updates from the download thread may have been posted while this download | 951 // Updates from the download thread may have been posted while this download |
| 804 // was being cancelled in the UI thread, so we'll accept them unless we're | 952 // was being cancelled in the UI thread, so we'll accept them unless we're |
| 805 // complete. | 953 // complete. |
| 806 void DownloadItemImpl::UpdateProgress(int64 bytes_so_far, | 954 void DownloadItemImpl::UpdateProgress(int64 bytes_so_far, |
| 807 int64 bytes_per_sec, | 955 int64 bytes_per_sec, |
| 808 const std::string& hash_state) { | 956 const std::string& hash_state) { |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 945 net::NetLog::TYPE_DOWNLOAD_ITEM_ACTIVE, active_data); | 1093 net::NetLog::TYPE_DOWNLOAD_ITEM_ACTIVE, active_data); |
| 946 } else { | 1094 } else { |
| 947 bound_net_log_.AddEvent( | 1095 bound_net_log_.AddEvent( |
| 948 net::NetLog::TYPE_DOWNLOAD_ITEM_ACTIVE, active_data); | 1096 net::NetLog::TYPE_DOWNLOAD_ITEM_ACTIVE, active_data); |
| 949 } | 1097 } |
| 950 | 1098 |
| 951 VLOG(20) << __FUNCTION__ << "() " << DebugString(true); | 1099 VLOG(20) << __FUNCTION__ << "() " << DebugString(true); |
| 952 } | 1100 } |
| 953 | 1101 |
| 954 // We're starting the download. | 1102 // We're starting the download. |
| 955 void DownloadItemImpl::Start(scoped_ptr<DownloadFile> file) { | 1103 void DownloadItemImpl::Start( |
| 1104 scoped_ptr<DownloadFile> file, | |
| 1105 scoped_ptr<DownloadRequestHandleInterface> req_handle) { | |
| 1106 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 956 DCHECK(!download_file_.get()); | 1107 DCHECK(!download_file_.get()); |
| 957 DCHECK(file.get()); | 1108 DCHECK(file.get()); |
| 1109 DCHECK(req_handle.get()); | |
| 1110 | |
| 958 download_file_ = file.Pass(); | 1111 download_file_ = file.Pass(); |
| 1112 request_handle_ = req_handle.Pass(); | |
| 1113 | |
| 1114 TransitionTo(IN_PROGRESS_INTERNAL); | |
| 1115 | |
| 1116 last_reason_ = DOWNLOAD_INTERRUPT_REASON_NONE; | |
| 959 | 1117 |
| 960 BrowserThread::PostTask( | 1118 BrowserThread::PostTask( |
| 961 BrowserThread::FILE, FROM_HERE, | 1119 BrowserThread::FILE, FROM_HERE, |
| 962 base::Bind(&DownloadFile::Initialize, | 1120 base::Bind(&DownloadFile::Initialize, |
| 963 // Safe because we control download file lifetime. | 1121 // Safe because we control download file lifetime. |
| 964 base::Unretained(download_file_.get()), | 1122 base::Unretained(download_file_.get()), |
| 965 base::Bind(&DownloadItemImpl::OnDownloadFileInitialized, | 1123 base::Bind(&DownloadItemImpl::OnDownloadFileInitialized, |
| 966 weak_ptr_factory_.GetWeakPtr()))); | 1124 weak_ptr_factory_.GetWeakPtr()))); |
| 967 } | 1125 } |
| 968 | 1126 |
| 969 void DownloadItemImpl::OnDownloadFileInitialized( | 1127 void DownloadItemImpl::OnDownloadFileInitialized( |
| 970 DownloadInterruptReason result) { | 1128 DownloadInterruptReason result) { |
| 1129 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 971 if (result != DOWNLOAD_INTERRUPT_REASON_NONE) { | 1130 if (result != DOWNLOAD_INTERRUPT_REASON_NONE) { |
| 972 Interrupt(result); | 1131 Interrupt(result); |
| 973 // TODO(rdsmith): It makes no sense to continue along the | 1132 // TODO(rdsmith): It makes no sense to continue along the |
| 974 // regular download path after we've gotten an error. But it's | 1133 // regular download path after we've gotten an error. But it's |
| 975 // the way the code has historically worked, and this allows us | 1134 // the way the code has historically worked, and this allows us |
| 976 // to get the download persisted and observers of the download manager | 1135 // to get the download persisted and observers of the download manager |
| 977 // notified, so tests work. When we execute all side effects of cancel | 1136 // notified, so tests work. When we execute all side effects of cancel |
| 978 // (including queue removal) immedately rather than waiting for | 1137 // (including queue removal) immediately rather than waiting for |
| 979 // persistence we should replace this comment with a "return;". | 1138 // persistence we should replace this comment with a "return;". |
| 980 } | 1139 } |
| 981 | 1140 |
| 1141 // If we're resuming an interrupted download, we may already know | |
| 1142 // the download target so we can skip target name determination. | |
| 1143 if (!GetTargetFilePath().empty() && !GetFullPath().empty()) { | |
| 1144 delegate_->ShowDownloadInBrowser(this); | |
| 1145 MaybeCompleteDownload(); | |
| 1146 return; | |
| 1147 } | |
| 1148 | |
| 1149 // The target path might be set and the full path empty if we failed | |
| 1150 // the intermediate rename--re-do file name determination in this case. | |
| 1151 // TODO(rdsmith,asanka): Clean up this logic. | |
| 1152 target_path_ = FilePath(); | |
| 1153 | |
| 982 delegate_->DetermineDownloadTarget( | 1154 delegate_->DetermineDownloadTarget( |
| 983 this, base::Bind(&DownloadItemImpl::OnDownloadTargetDetermined, | 1155 this, base::Bind(&DownloadItemImpl::OnDownloadTargetDetermined, |
| 984 weak_ptr_factory_.GetWeakPtr())); | 1156 weak_ptr_factory_.GetWeakPtr())); |
| 985 } | 1157 } |
| 986 | 1158 |
| 987 // Called by delegate_ when the download target path has been | 1159 // Called by delegate_ when the download target path has been |
| 988 // determined. | 1160 // determined. |
| 989 void DownloadItemImpl::OnDownloadTargetDetermined( | 1161 void DownloadItemImpl::OnDownloadTargetDetermined( |
| 990 const FilePath& target_path, | 1162 const FilePath& target_path, |
| 991 TargetDisposition disposition, | 1163 TargetDisposition disposition, |
| 992 DownloadDangerType danger_type, | 1164 DownloadDangerType danger_type, |
| 993 const FilePath& intermediate_path) { | 1165 const FilePath& intermediate_path) { |
| 994 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1166 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 995 | 1167 |
| 996 // If the |target_path| is empty, then we consider this download to be | 1168 // If the |target_path| is empty, then we consider this download to be |
| 997 // canceled. | 1169 // canceled. |
| 998 if (target_path.empty()) { | 1170 if (target_path.empty()) { |
| 999 Cancel(true); | 1171 Cancel(true); |
| 1000 return; | 1172 return; |
| 1001 } | 1173 } |
| 1002 | 1174 |
| 1175 // TODO(rdsmith,asanka): We are ignoring the possibility that the download | |
| 1176 // has been interrupted at this point until we finish the intermediate | |
| 1177 // rename and set the full path. That's dangerous, because we might race | |
| 1178 // with resumption, either manual (because the interrupt is visible to the | |
| 1179 // UI) or automatic. If we keep the "ignore an error on download until file | |
| 1180 // name determination complete" semantics, we need to make sure that the | |
| 1181 // error is kept completely invisible until that point. | |
| 1182 | |
| 1003 VLOG(20) << __FUNCTION__ << " " << target_path.value() << " " << disposition | 1183 VLOG(20) << __FUNCTION__ << " " << target_path.value() << " " << disposition |
| 1004 << " " << danger_type << " " << DebugString(true); | 1184 << " " << danger_type << " " << DebugString(true); |
| 1005 | 1185 |
| 1006 target_path_ = target_path; | 1186 target_path_ = target_path; |
| 1007 target_disposition_ = disposition; | 1187 target_disposition_ = disposition; |
| 1008 SetDangerType(danger_type); | 1188 SetDangerType(danger_type); |
| 1009 // TODO(asanka): SetDangerType() doesn't need to send a notification here. | 1189 // TODO(asanka): SetDangerType() doesn't need to send a notification here. |
| 1010 | 1190 |
| 1011 // We want the intermediate and target paths to refer to the same directory so | 1191 // We want the intermediate and target paths to refer to the same directory so |
| 1012 // that they are both on the same device and subject to same | 1192 // that they are both on the same device and subject to same |
| 1013 // space/permission/availability constraints. | 1193 // space/permission/availability constraints. |
| 1014 DCHECK(intermediate_path.DirName() == target_path.DirName()); | 1194 DCHECK(intermediate_path.DirName() == target_path.DirName()); |
| 1015 | 1195 |
| 1016 if (state_ != IN_PROGRESS_INTERNAL) { | |
| 1017 // If we've been cancelled or interrupted while the target was being | |
| 1018 // determined, continue the cascade with a null name. | |
| 1019 // The error doesn't matter as the cause of download stoppage | |
| 1020 // will already have been recorded and will be retained, but we use | |
| 1021 // whatever was recorded for consistency. | |
| 1022 OnDownloadRenamedToIntermediateName(last_reason_, FilePath()); | |
| 1023 return; | |
| 1024 } | |
| 1025 | |
| 1026 // Rename to intermediate name. | 1196 // Rename to intermediate name. |
| 1027 // TODO(asanka): Skip this rename if AllDataSaved() is true. This avoids a | 1197 // TODO(asanka): Skip this rename if AllDataSaved() is true. This avoids a |
| 1028 // spurious rename when we can just rename to the final | 1198 // spurious rename when we can just rename to the final |
| 1029 // filename. Unnecessary renames may cause bugs like | 1199 // filename. Unnecessary renames may cause bugs like |
| 1030 // http://crbug.com/74187. | 1200 // http://crbug.com/74187. |
| 1031 DCHECK(!is_save_package_download_); | 1201 DCHECK(!is_save_package_download_); |
| 1032 DCHECK(download_file_.get()); | 1202 DCHECK(download_file_.get()); |
| 1033 DownloadFile::RenameCompletionCallback callback = | 1203 DownloadFile::RenameCompletionCallback callback = |
| 1034 base::Bind(&DownloadItemImpl::OnDownloadRenamedToIntermediateName, | 1204 base::Bind(&DownloadItemImpl::OnDownloadRenamedToIntermediateName, |
| 1035 weak_ptr_factory_.GetWeakPtr()); | 1205 weak_ptr_factory_.GetWeakPtr()); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1092 if (state_ != IN_PROGRESS_INTERNAL) | 1262 if (state_ != IN_PROGRESS_INTERNAL) |
| 1093 return; | 1263 return; |
| 1094 | 1264 |
| 1095 // Give the delegate a chance to override. | 1265 // Give the delegate a chance to override. |
| 1096 delegate_->ReadyForDownloadCompletion( | 1266 delegate_->ReadyForDownloadCompletion( |
| 1097 this, base::Bind(&DownloadItemImpl::ReadyForDownloadCompletionDone, | 1267 this, base::Bind(&DownloadItemImpl::ReadyForDownloadCompletionDone, |
| 1098 weak_ptr_factory_.GetWeakPtr())); | 1268 weak_ptr_factory_.GetWeakPtr())); |
| 1099 } | 1269 } |
| 1100 | 1270 |
| 1101 void DownloadItemImpl::ReadyForDownloadCompletionDone() { | 1271 void DownloadItemImpl::ReadyForDownloadCompletionDone() { |
| 1272 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 1273 | |
| 1102 if (state_ != IN_PROGRESS_INTERNAL) | 1274 if (state_ != IN_PROGRESS_INTERNAL) |
| 1103 return; | 1275 return; |
| 1104 | 1276 |
| 1105 VLOG(20) << __FUNCTION__ << "()" | 1277 VLOG(20) << __FUNCTION__ << "()" << " " << DebugString(true); |
| 1106 << " " << DebugString(true); | |
| 1107 DCHECK(!GetTargetFilePath().empty()); | 1278 DCHECK(!GetTargetFilePath().empty()); |
| 1108 DCHECK_NE(DANGEROUS, GetSafetyState()); | 1279 DCHECK_NE(DANGEROUS, GetSafetyState()); |
| 1109 | 1280 |
| 1110 // TODO(rdsmith/benjhayden): Remove as part of SavePackage integration. | 1281 // TODO(rdsmith/benjhayden): Remove as part of SavePackage integration. |
| 1111 if (is_save_package_download_) { | 1282 if (is_save_package_download_) { |
| 1112 // Avoid doing anything on the file thread; there's nothing we control | 1283 // Avoid doing anything on the file thread; there's nothing we control |
| 1113 // there. | 1284 // there. |
| 1114 // Strictly speaking, this skips giving the embedder a chance to open | 1285 // Strictly speaking, this skips giving the embedder a chance to open |
| 1115 // the download. But on a save package download, there's no real | 1286 // the download. But on a save package download, there's no real |
| 1116 // concept of opening. | 1287 // concept of opening. |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1175 if (delegate_->ShouldOpenDownload( | 1346 if (delegate_->ShouldOpenDownload( |
| 1176 this, base::Bind(&DownloadItemImpl::DelayedDownloadOpened, | 1347 this, base::Bind(&DownloadItemImpl::DelayedDownloadOpened, |
| 1177 weak_ptr_factory_.GetWeakPtr()))) { | 1348 weak_ptr_factory_.GetWeakPtr()))) { |
| 1178 Completed(); | 1349 Completed(); |
| 1179 } else { | 1350 } else { |
| 1180 delegate_delayed_complete_ = true; | 1351 delegate_delayed_complete_ = true; |
| 1181 } | 1352 } |
| 1182 } | 1353 } |
| 1183 | 1354 |
| 1184 void DownloadItemImpl::DelayedDownloadOpened(bool auto_opened) { | 1355 void DownloadItemImpl::DelayedDownloadOpened(bool auto_opened) { |
| 1356 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 1357 | |
| 1185 auto_opened_ = auto_opened; | 1358 auto_opened_ = auto_opened; |
| 1186 Completed(); | 1359 Completed(); |
| 1187 } | 1360 } |
| 1188 | 1361 |
| 1189 void DownloadItemImpl::Completed() { | 1362 void DownloadItemImpl::Completed() { |
| 1190 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1363 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1191 | 1364 |
| 1192 VLOG(20) << __FUNCTION__ << "() " << DebugString(false); | 1365 VLOG(20) << __FUNCTION__ << "() " << DebugString(false); |
| 1193 | 1366 |
| 1194 DCHECK(all_data_saved_); | 1367 DCHECK(all_data_saved_); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 1209 | 1382 |
| 1210 auto_opened_ = true; | 1383 auto_opened_ = true; |
| 1211 UpdateObservers(); | 1384 UpdateObservers(); |
| 1212 } | 1385 } |
| 1213 } | 1386 } |
| 1214 | 1387 |
| 1215 // **** End of Download progression cascade | 1388 // **** End of Download progression cascade |
| 1216 | 1389 |
| 1217 // An error occurred somewhere. | 1390 // An error occurred somewhere. |
| 1218 void DownloadItemImpl::Interrupt(DownloadInterruptReason reason) { | 1391 void DownloadItemImpl::Interrupt(DownloadInterruptReason reason) { |
| 1392 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 1393 | |
| 1219 // Somewhat counter-intuitively, it is possible for us to receive an | 1394 // Somewhat counter-intuitively, it is possible for us to receive an |
| 1220 // interrupt after we've already been interrupted. The generation of | 1395 // interrupt after we've already been interrupted. The generation of |
| 1221 // interrupts from the file thread Renames and the generation of | 1396 // interrupts from the file thread Renames and the generation of |
| 1222 // interrupts from disk writes go through two different mechanisms (driven | 1397 // interrupts from disk writes go through two different mechanisms (driven |
| 1223 // by rename requests from UI thread and by write requests from IO thread, | 1398 // by rename requests from UI thread and by write requests from IO thread, |
| 1224 // respectively), and since we choose not to keep state on the File thread, | 1399 // respectively), and since we choose not to keep state on the File thread, |
| 1225 // this is the place where the races collide. It's also possible for | 1400 // this is the place where the races collide. It's also possible for |
| 1226 // interrupts to race with cancels. | 1401 // interrupts to race with cancels. |
| 1227 | 1402 |
| 1228 // Whatever happens, the first one to hit the UI thread wins. | 1403 // Whatever happens, the first one to hit the UI thread wins. |
| 1229 if (state_ != IN_PROGRESS_INTERNAL) | 1404 if (state_ != IN_PROGRESS_INTERNAL) |
| 1230 return; | 1405 return; |
| 1231 | 1406 |
| 1232 last_reason_ = reason; | 1407 last_reason_ = reason; |
| 1408 | |
| 1233 TransitionTo(INTERRUPTED_INTERNAL); | 1409 TransitionTo(INTERRUPTED_INTERNAL); |
| 1234 | 1410 |
| 1235 CancelDownloadFile(); | 1411 ResumeMode resume_mode = GetResumeMode(); |
| 1412 if (resume_mode == RESUME_MODE_IMMEDIATE_RESTART || | |
| 1413 resume_mode == RESUME_MODE_USER_RESTART) { | |
| 1414 // Remove the download file; no point in leaving data around we | |
| 1415 // aren't going to use. | |
| 1416 CancelDownloadFile(); | |
| 1417 } else { | |
| 1418 // Keep the file around and maybe re-use it. | |
| 1419 BrowserThread::PostTask( | |
| 1420 BrowserThread::FILE, FROM_HERE, | |
| 1421 base::Bind(&DownloadFileDetach, base::Passed(&download_file_))); | |
| 1422 } | |
| 1236 | 1423 |
| 1237 // Cancel the originating URL request. | 1424 // Cancel the originating URL request. |
| 1238 request_handle_->CancelRequest(); | 1425 request_handle_->CancelRequest(); |
| 1239 | 1426 |
| 1240 RecordDownloadInterrupted(reason, received_bytes_, total_bytes_); | 1427 RecordDownloadInterrupted(reason, received_bytes_, total_bytes_); |
| 1428 AutoResumeIfValid(); | |
| 1241 } | 1429 } |
| 1242 | 1430 |
| 1243 void DownloadItemImpl::CancelDownloadFile() { | 1431 void DownloadItemImpl::CancelDownloadFile() { |
| 1432 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 1433 | |
| 1244 // TODO(rdsmith/benjhayden): Remove condition as part of | 1434 // TODO(rdsmith/benjhayden): Remove condition as part of |
| 1245 // SavePackage integration. | 1435 // |SavePackage| integration. |
| 1246 // download_file_ can be NULL if Interrupt() is called after the download file | 1436 // |download_file_| can be NULL if Interrupt() is called after the |
| 1247 // has been released. | 1437 // download file has been released. |
| 1248 if (!is_save_package_download_ && download_file_.get()) { | 1438 if (!is_save_package_download_ && download_file_.get()) { |
| 1249 BrowserThread::PostTask( | 1439 BrowserThread::PostTask( |
| 1250 BrowserThread::FILE, FROM_HERE, | 1440 BrowserThread::FILE, FROM_HERE, |
| 1251 // Will be deleted at end of task execution. | 1441 // Will be deleted at end of task execution. |
| 1252 base::Bind(&DownloadFileCancel, base::Passed(&download_file_))); | 1442 base::Bind(&DownloadFileCancel, base::Passed(&download_file_))); |
| 1253 } | 1443 } |
| 1254 } | 1444 } |
| 1255 | 1445 |
| 1256 bool DownloadItemImpl::IsDownloadReadyForCompletion() { | 1446 bool DownloadItemImpl::IsDownloadReadyForCompletion() { |
| 1257 VLOG(20) << __FUNCTION__ << " " << AllDataSaved() | 1447 VLOG(20) << __FUNCTION__ << " " << AllDataSaved() |
| 1258 << " " << (GetSafetyState() != DownloadItem::DANGEROUS) | 1448 << " " << (GetSafetyState() != DownloadItem::DANGEROUS) |
| 1259 << " " << (state_ == IN_PROGRESS_INTERNAL) | 1449 << " " << (state_ == IN_PROGRESS_INTERNAL) |
| 1260 << " " << !GetTargetFilePath().empty() | 1450 << " " << !GetTargetFilePath().empty() |
| 1261 << " " << (target_path_.DirName() == current_path_.DirName()); | 1451 << " " << (target_path_.DirName() == current_path_.DirName()); |
| 1452 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 1453 | |
| 1262 // If we don't have all the data, the download is not ready for | 1454 // If we don't have all the data, the download is not ready for |
| 1263 // completion. | 1455 // completion. |
| 1264 if (!AllDataSaved()) | 1456 if (!AllDataSaved()) |
| 1265 return false; | 1457 return false; |
| 1266 | 1458 |
| 1267 // If the download is dangerous, but not yet validated, it's not ready for | 1459 // If the download is dangerous, but not yet validated, it's not ready for |
| 1268 // completion. | 1460 // completion. |
| 1269 if (GetSafetyState() == DownloadItem::DANGEROUS) | 1461 if (GetSafetyState() == DownloadItem::DANGEROUS) |
| 1270 return false; | 1462 return false; |
| 1271 | 1463 |
| 1272 // If the download isn't active (e.g. has been cancelled) it's not | 1464 // If the download isn't active (e.g. has been cancelled) it's not |
| 1273 // ready for completion. | 1465 // ready for completion. |
| 1274 if (state_ != IN_PROGRESS_INTERNAL) | 1466 if (state_ != IN_PROGRESS_INTERNAL) |
| 1275 return false; | 1467 return false; |
| 1276 | 1468 |
| 1277 // If the target filename hasn't been determined, then it's not ready for | 1469 // If the target filename hasn't been determined, then it's not ready for |
| 1278 // completion. This is checked in ReadyForDownloadCompletionDone(). | 1470 // completion. This is checked in ReadyForDownloadCompletionDone(). |
| 1279 if (GetTargetFilePath().empty()) | 1471 if (GetTargetFilePath().empty()) |
| 1280 return false; | 1472 return false; |
| 1281 | 1473 |
| 1282 // This is checked in NeedsRename(). Without this conditional, | 1474 // This is checked in NeedsRename(). Without this conditional, |
| 1283 // browser_tests:DownloadTest.DownloadMimeType fails the DCHECK. | 1475 // browser_tests:DownloadTest.DownloadMimeType fails the DCHECK. |
| 1284 if (target_path_.DirName() != current_path_.DirName()) | 1476 if (target_path_.DirName() != current_path_.DirName()) |
| 1285 return false; | 1477 return false; |
| 1286 | 1478 |
| 1287 return true; | 1479 return true; |
| 1288 } | 1480 } |
| 1289 | 1481 |
| 1290 void DownloadItemImpl::TransitionTo(DownloadInternalState new_state) { | 1482 void DownloadItemImpl::TransitionTo(DownloadInternalState new_state) { |
| 1483 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 1484 | |
| 1291 if (state_ == new_state) | 1485 if (state_ == new_state) |
| 1292 return; | 1486 return; |
| 1293 | 1487 |
| 1294 DownloadInternalState old_state = state_; | 1488 DownloadInternalState old_state = state_; |
| 1295 state_ = new_state; | 1489 state_ = new_state; |
| 1296 | 1490 |
| 1297 switch (state_) { | 1491 switch (state_) { |
| 1298 case COMPLETING_INTERNAL: | 1492 case COMPLETING_INTERNAL: |
| 1299 bound_net_log_.AddEvent( | 1493 bound_net_log_.AddEvent( |
| 1300 net::NetLog::TYPE_DOWNLOAD_ITEM_COMPLETING, | 1494 net::NetLog::TYPE_DOWNLOAD_ITEM_COMPLETING, |
| 1301 base::Bind(&ItemCompletingNetLogCallback, received_bytes_, &hash_)); | 1495 base::Bind(&ItemCompletingNetLogCallback, received_bytes_, &hash_)); |
| 1302 break; | 1496 break; |
| 1303 case COMPLETE_INTERNAL: | 1497 case COMPLETE_INTERNAL: |
| 1304 bound_net_log_.AddEvent( | 1498 bound_net_log_.AddEvent( |
| 1305 net::NetLog::TYPE_DOWNLOAD_ITEM_FINISHED, | 1499 net::NetLog::TYPE_DOWNLOAD_ITEM_FINISHED, |
| 1306 base::Bind(&ItemFinishedNetLogCallback, auto_opened_)); | 1500 base::Bind(&ItemFinishedNetLogCallback, auto_opened_)); |
| 1307 break; | 1501 break; |
| 1308 case INTERRUPTED_INTERNAL: | 1502 case INTERRUPTED_INTERNAL: |
| 1309 bound_net_log_.AddEvent( | 1503 bound_net_log_.AddEvent( |
| 1310 net::NetLog::TYPE_DOWNLOAD_ITEM_INTERRUPTED, | 1504 net::NetLog::TYPE_DOWNLOAD_ITEM_INTERRUPTED, |
| 1311 base::Bind(&ItemInterruptedNetLogCallback, last_reason_, | 1505 base::Bind(&ItemInterruptedNetLogCallback, last_reason_, |
| 1312 received_bytes_, &hash_state_)); | 1506 received_bytes_, &hash_state_)); |
| 1313 break; | 1507 break; |
| 1508 case IN_PROGRESS_INTERNAL: | |
| 1509 if (old_state == INTERRUPTED_INTERNAL) { | |
| 1510 bound_net_log_.AddEvent( | |
| 1511 net::NetLog::TYPE_DOWNLOAD_ITEM_RESUMED, | |
| 1512 base::Bind(&ItemResumingNetLogCallback, | |
| 1513 false, last_reason_, received_bytes_, &hash_state_)); | |
| 1514 } | |
| 1515 break; | |
| 1314 case CANCELLED_INTERNAL: | 1516 case CANCELLED_INTERNAL: |
| 1315 bound_net_log_.AddEvent( | 1517 bound_net_log_.AddEvent( |
| 1316 net::NetLog::TYPE_DOWNLOAD_ITEM_CANCELED, | 1518 net::NetLog::TYPE_DOWNLOAD_ITEM_CANCELED, |
| 1317 base::Bind(&ItemCanceledNetLogCallback, received_bytes_, | 1519 base::Bind(&ItemCanceledNetLogCallback, received_bytes_, |
| 1318 &hash_state_)); | 1520 &hash_state_)); |
| 1319 break; | 1521 break; |
| 1320 default: | 1522 default: |
| 1321 break; | 1523 break; |
| 1322 } | 1524 } |
| 1323 | 1525 |
| 1324 VLOG(20) << " " << __FUNCTION__ << "()" << " this = " << DebugString(true) | 1526 VLOG(20) << " " << __FUNCTION__ << "()" << " this = " << DebugString(true) |
| 1325 << " " << InternalToExternalState(old_state) | 1527 << " " << InternalToExternalState(old_state) |
| 1326 << " " << InternalToExternalState(state_); | 1528 << " " << InternalToExternalState(state_); |
| 1327 | 1529 |
| 1328 // Only update observers on user visible state changes. | 1530 // Only update observers on user visible state changes. |
| 1329 if (InternalToExternalState(old_state) != InternalToExternalState(state_)) | 1531 if (InternalToExternalState(state_) != InternalToExternalState(old_state)) |
| 1330 UpdateObservers(); | 1532 UpdateObservers(); |
| 1331 | 1533 |
| 1332 bool is_done = (state_ != IN_PROGRESS_INTERNAL && | 1534 bool is_done = (state_ != IN_PROGRESS_INTERNAL && |
| 1333 state_ != COMPLETING_INTERNAL); | 1535 state_ != COMPLETING_INTERNAL); |
| 1334 bool was_done = (old_state != IN_PROGRESS_INTERNAL && | 1536 bool was_done = (old_state != IN_PROGRESS_INTERNAL && |
| 1335 old_state != COMPLETING_INTERNAL); | 1537 old_state != COMPLETING_INTERNAL); |
| 1538 // Termination | |
| 1336 if (is_done && !was_done) | 1539 if (is_done && !was_done) |
| 1337 bound_net_log_.EndEvent(net::NetLog::TYPE_DOWNLOAD_ITEM_ACTIVE); | 1540 bound_net_log_.EndEvent(net::NetLog::TYPE_DOWNLOAD_ITEM_ACTIVE); |
| 1541 | |
| 1542 // Resumption | |
| 1543 if (was_done && !is_done) { | |
| 1544 std::string file_name(target_path_.BaseName().AsUTF8Unsafe()); | |
| 1545 bound_net_log_.BeginEvent(net::NetLog::TYPE_DOWNLOAD_ITEM_ACTIVE, | |
| 1546 base::Bind(&ItemActivatedNetLogCallback, | |
| 1547 this, SRC_ACTIVE_DOWNLOAD, | |
| 1548 &file_name)); | |
| 1549 } | |
| 1338 } | 1550 } |
| 1339 | 1551 |
| 1340 void DownloadItemImpl::SetDangerType(DownloadDangerType danger_type) { | 1552 void DownloadItemImpl::SetDangerType(DownloadDangerType danger_type) { |
| 1341 danger_type_ = danger_type; | 1553 danger_type_ = danger_type; |
| 1342 // Notify observers if the safety state has changed as a result of the new | 1554 // Notify observers if the safety state has changed as a result of the new |
| 1343 // danger type. | 1555 // danger type. |
| 1344 SafetyState updated_value = IsDangerous() ? | 1556 SafetyState updated_value = IsDangerous() ? |
| 1345 DownloadItem::DANGEROUS : DownloadItem::SAFE; | 1557 DownloadItem::DANGEROUS : DownloadItem::SAFE; |
| 1346 if (updated_value != safety_state_) { | 1558 if (updated_value != safety_state_) { |
| 1347 safety_state_ = updated_value; | 1559 safety_state_ = updated_value; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1360 DCHECK(!new_path.empty()); | 1572 DCHECK(!new_path.empty()); |
| 1361 | 1573 |
| 1362 bound_net_log_.AddEvent( | 1574 bound_net_log_.AddEvent( |
| 1363 net::NetLog::TYPE_DOWNLOAD_ITEM_RENAMED, | 1575 net::NetLog::TYPE_DOWNLOAD_ITEM_RENAMED, |
| 1364 base::Bind(&ItemRenamedNetLogCallback, ¤t_path_, &new_path)); | 1576 base::Bind(&ItemRenamedNetLogCallback, ¤t_path_, &new_path)); |
| 1365 | 1577 |
| 1366 current_path_ = new_path; | 1578 current_path_ = new_path; |
| 1367 UpdateObservers(); | 1579 UpdateObservers(); |
| 1368 } | 1580 } |
| 1369 | 1581 |
| 1582 void DownloadItemImpl::AutoResumeIfValid() { | |
| 1583 DVLOG(20) << __FUNCTION__ << "() " << DebugString(true); | |
| 1584 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 1585 ResumeMode mode = GetResumeMode(); | |
| 1586 | |
| 1587 if (mode != RESUME_MODE_IMMEDIATE_RESTART && | |
| 1588 mode != RESUME_MODE_IMMEDIATE_CONTINUE) { | |
| 1589 return; | |
| 1590 } | |
| 1591 | |
| 1592 auto_resume_count_++; | |
| 1593 | |
| 1594 ResumeInterruptedDownload(); | |
| 1595 } | |
| 1596 | |
| 1370 // static | 1597 // static |
| 1371 DownloadItem::DownloadState DownloadItemImpl::InternalToExternalState( | 1598 DownloadItem::DownloadState DownloadItemImpl::InternalToExternalState( |
| 1372 DownloadInternalState internal_state) { | 1599 DownloadInternalState internal_state) { |
| 1373 switch (internal_state) { | 1600 switch (internal_state) { |
| 1374 case IN_PROGRESS_INTERNAL: | 1601 case IN_PROGRESS_INTERNAL: |
| 1375 return IN_PROGRESS; | 1602 return IN_PROGRESS; |
| 1376 case COMPLETING_INTERNAL: | 1603 case COMPLETING_INTERNAL: |
| 1377 return IN_PROGRESS; | 1604 return IN_PROGRESS; |
| 1378 case COMPLETE_INTERNAL: | 1605 case COMPLETE_INTERNAL: |
| 1379 return COMPLETE; | 1606 return COMPLETE; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1418 case CANCELLED_INTERNAL: | 1645 case CANCELLED_INTERNAL: |
| 1419 return "CANCELLED"; | 1646 return "CANCELLED"; |
| 1420 case INTERRUPTED_INTERNAL: | 1647 case INTERRUPTED_INTERNAL: |
| 1421 return "INTERRUPTED"; | 1648 return "INTERRUPTED"; |
| 1422 default: | 1649 default: |
| 1423 NOTREACHED() << "Unknown download state " << state; | 1650 NOTREACHED() << "Unknown download state " << state; |
| 1424 return "unknown"; | 1651 return "unknown"; |
| 1425 }; | 1652 }; |
| 1426 } | 1653 } |
| 1427 | 1654 |
| 1655 const char* DownloadItemImpl::DebugResumeModeString(ResumeMode mode) { | |
| 1656 switch (mode) { | |
| 1657 case RESUME_MODE_INVALID: | |
| 1658 return "INVALID"; | |
| 1659 case RESUME_MODE_IMMEDIATE_CONTINUE: | |
| 1660 return "IMMEDIATE_CONTINUE"; | |
| 1661 case RESUME_MODE_IMMEDIATE_RESTART: | |
| 1662 return "IMMEDIATE_RESTART"; | |
| 1663 case RESUME_MODE_USER_CONTINUE: | |
| 1664 return "USER_CONTINUE"; | |
| 1665 case RESUME_MODE_USER_RESTART: | |
| 1666 return "USER_RESTART"; | |
| 1667 } | |
| 1668 NOTREACHED() << "Unknown resume mode " << mode; | |
| 1669 return "unknown"; | |
| 1670 } | |
| 1671 | |
| 1428 } // namespace content | 1672 } // namespace content |
| OLD | NEW |