Chromium Code Reviews
[email protected] (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(177)

Side by Side Diff: content/browser/download/download_item_impl.cc

Issue 14947007: [Downloads] Allow acquiring dangerous download file. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix UMA and support stealing interrupted downloads Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 61 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
62 62
63 // Make sure we only delete files. 63 // Make sure we only delete files.
64 if (!file_util::DirectoryExists(path)) 64 if (!file_util::DirectoryExists(path))
65 file_util::Delete(path, false); 65 file_util::Delete(path, false);
66 } 66 }
67 67
68 // Wrapper around DownloadFile::Detach and DownloadFile::Cancel that 68 // Wrapper around DownloadFile::Detach and DownloadFile::Cancel that
69 // takes ownership of the DownloadFile and hence implicitly destroys it 69 // takes ownership of the DownloadFile and hence implicitly destroys it
70 // at the end of the function. 70 // at the end of the function.
71 static void DownloadFileDetach(scoped_ptr<DownloadFile> download_file) { 71 static base::FilePath DownloadFileDetach(
72 scoped_ptr<DownloadFile> download_file) {
72 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 73 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
74 base::FilePath full_path = download_file->FullPath();
73 download_file->Detach(); 75 download_file->Detach();
76 return full_path;
74 } 77 }
75 78
76 static void DownloadFileCancel(scoped_ptr<DownloadFile> download_file) { 79 static void DownloadFileCancel(scoped_ptr<DownloadFile> download_file) {
77 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 80 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
78 download_file->Cancel(); 81 download_file->Cancel();
79 } 82 }
80 83
81 bool IsDownloadResumptionEnabled() { 84 bool IsDownloadResumptionEnabled() {
82 return CommandLine::ForCurrentProcess()->HasSwitch( 85 return CommandLine::ForCurrentProcess()->HasSwitch(
83 switches::kEnableDownloadResumption); 86 switches::kEnableDownloadResumption);
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 271
269 observers_.RemoveObserver(observer); 272 observers_.RemoveObserver(observer);
270 } 273 }
271 274
272 void DownloadItemImpl::UpdateObservers() { 275 void DownloadItemImpl::UpdateObservers() {
273 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 276 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
274 277
275 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadUpdated(this)); 278 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadUpdated(this));
276 } 279 }
277 280
278 void DownloadItemImpl::DangerousDownloadValidated() { 281 void DownloadItemImpl::ValidateDangerousDownload() {
279 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 282 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
280 DCHECK_EQ(IN_PROGRESS, GetState()); 283 DCHECK_EQ(IN_PROGRESS, GetState());
281 DCHECK(IsDangerous()); 284 DCHECK(IsDangerous());
282 285
283 VLOG(20) << __FUNCTION__ << " download=" << DebugString(true); 286 VLOG(20) << __FUNCTION__ << " download=" << DebugString(true);
284 287
285 if (GetState() != IN_PROGRESS) 288 if (GetState() != IN_PROGRESS)
286 return; 289 return;
287 290
288 UMA_HISTOGRAM_ENUMERATION("Download.DangerousDownloadValidated", 291 RecordDangerousDownloadAccept(GetDangerType());
289 GetDangerType(),
290 DOWNLOAD_DANGER_TYPE_MAX);
291 292
292 danger_type_ = DOWNLOAD_DANGER_TYPE_USER_VALIDATED; 293 danger_type_ = DOWNLOAD_DANGER_TYPE_USER_VALIDATED;
293 294
294 bound_net_log_.AddEvent( 295 bound_net_log_.AddEvent(
295 net::NetLog::TYPE_DOWNLOAD_ITEM_SAFETY_STATE_UPDATED, 296 net::NetLog::TYPE_DOWNLOAD_ITEM_SAFETY_STATE_UPDATED,
296 base::Bind(&ItemCheckedNetLogCallback, GetDangerType())); 297 base::Bind(&ItemCheckedNetLogCallback, GetDangerType()));
297 298
298 UpdateObservers(); 299 UpdateObservers();
299 300
300 MaybeCompleteDownload(); 301 MaybeCompleteDownload();
301 } 302 }
302 303
304 void DownloadItemImpl::StealDangerousDownload(
Randy Smith (Not in Mondays) 2013/05/28 17:29:40 Given that this is one of the ways that we can tra
asanka 2013/05/28 22:01:39 The Steal() -> Remove() -> Cancel(true) call adds
305 const AcquireFileCallback& callback) {
306 VLOG(20) << __FUNCTION__ << "() download = " << DebugString(true);
307 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
308 DCHECK(IsDangerous());
309 if (download_file_) {
310 BrowserThread::PostTaskAndReplyWithResult(
311 BrowserThread::FILE,
312 FROM_HERE,
313 base::Bind(&DownloadFileDetach, base::Passed(&download_file_)),
314 callback);
315 } else {
316 callback.Run(current_path_);
317 }
318 current_path_.clear();
319 Remove();
320 // We have now been deleted.
321 }
322
303 void DownloadItemImpl::Pause() { 323 void DownloadItemImpl::Pause() {
304 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 324 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
305 325
306 // Ignore irrelevant states. 326 // Ignore irrelevant states.
307 if (state_ != IN_PROGRESS_INTERNAL || is_paused_) 327 if (state_ != IN_PROGRESS_INTERNAL || is_paused_)
308 return; 328 return;
309 329
310 request_handle_->PauseRequest(); 330 request_handle_->PauseRequest();
311 is_paused_ = true; 331 is_paused_ = true;
312 UpdateObservers(); 332 UpdateObservers();
(...skipping 30 matching lines...) Expand all
343 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 363 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
344 364
345 VLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); 365 VLOG(20) << __FUNCTION__ << "() download = " << DebugString(true);
346 if (state_ != IN_PROGRESS_INTERNAL && 366 if (state_ != IN_PROGRESS_INTERNAL &&
347 state_ != INTERRUPTED_INTERNAL && 367 state_ != INTERRUPTED_INTERNAL &&
348 state_ != RESUMING_INTERNAL) { 368 state_ != RESUMING_INTERNAL) {
349 // Small downloads might be complete before this method has a chance to run. 369 // Small downloads might be complete before this method has a chance to run.
350 return; 370 return;
351 } 371 }
352 372
353 last_reason_ = user_cancel ? 373 if (IsDangerous()) {
354 DOWNLOAD_INTERRUPT_REASON_USER_CANCELED : 374 RecordDangerousDownloadDiscard(
355 DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN; 375 user_cancel ? DOWNLOAD_DISCARD_DUE_TO_USER_ACTION
376 : DOWNLOAD_DISCARD_DUE_TO_SHUTDOWN,
377 GetDangerType());
378 }
379
380 last_reason_ = user_cancel ? DOWNLOAD_INTERRUPT_REASON_USER_CANCELED
381 : DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN;
356 382
357 RecordDownloadCount(CANCELLED_COUNT); 383 RecordDownloadCount(CANCELLED_COUNT);
358 384
359 // TODO(rdsmith/benjhayden): Remove condition as part of 385 // TODO(rdsmith/benjhayden): Remove condition as part of
360 // |SavePackage| integration. 386 // |SavePackage| integration.
361 // |download_file_| can be NULL if Interrupt() is called after the 387 // |download_file_| can be NULL if Interrupt() is called after the
362 // download file has been released. 388 // download file has been released.
363 if (!is_save_package_download_ && download_file_) 389 if (!is_save_package_download_ && download_file_)
364 ReleaseDownloadFile(true); 390 ReleaseDownloadFile(true);
365 391
366 if (state_ == IN_PROGRESS_INTERNAL) { 392 if (state_ == IN_PROGRESS_INTERNAL) {
367 // Cancel the originating URL request unless it's already been cancelled 393 // Cancel the originating URL request unless it's already been cancelled
368 // by interrupt. 394 // by interrupt.
369 request_handle_->CancelRequest(); 395 request_handle_->CancelRequest();
370 } 396 }
371 397
372 // Remove the intermediate file if we are cancelling an interrupted download. 398 // Remove the intermediate file if we are cancelling an interrupted download.
373 // Continuable interruptions leave the intermediate file around. 399 // Continuable interruptions leave the intermediate file around.
374 if ((state_ == INTERRUPTED_INTERNAL || state_ == RESUMING_INTERNAL) && 400 if ((state_ == INTERRUPTED_INTERNAL || state_ == RESUMING_INTERNAL) &&
375 !current_path_.empty()) { 401 !current_path_.empty()) {
376 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 402 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
377 base::Bind(&DeleteDownloadedFile, current_path_)); 403 base::Bind(&DeleteDownloadedFile, current_path_));
378 current_path_.clear(); 404 current_path_.clear();
379 } 405 }
380 406
381 TransitionTo(CANCELLED_INTERNAL); 407 TransitionTo(CANCELLED_INTERNAL);
382 } 408 }
383 409
384 void DownloadItemImpl::Delete(DeleteReason reason) {
385 VLOG(20) << __FUNCTION__ << "() download = " << DebugString(true);
386 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
387
388 switch (reason) {
389 case DELETE_DUE_TO_USER_DISCARD:
390 UMA_HISTOGRAM_ENUMERATION(
391 "Download.UserDiscard", GetDangerType(),
392 DOWNLOAD_DANGER_TYPE_MAX);
393 break;
394 case DELETE_DUE_TO_BROWSER_SHUTDOWN:
395 UMA_HISTOGRAM_ENUMERATION(
396 "Download.Discard", GetDangerType(),
397 DOWNLOAD_DANGER_TYPE_MAX);
398 break;
399 default:
400 NOTREACHED();
401 }
402
403 // Delete the file if it exists and is not owned by a DownloadFile object.
404 // (In the latter case the DownloadFile object will delete it on cancel.)
405 if (!current_path_.empty() && download_file_.get() == NULL) {
406 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
407 base::Bind(&DeleteDownloadedFile, current_path_));
408 current_path_.clear();
409 }
410 Remove();
411 // We have now been deleted.
412 }
413
414 void DownloadItemImpl::Remove() { 410 void DownloadItemImpl::Remove() {
415 VLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); 411 VLOG(20) << __FUNCTION__ << "() download = " << DebugString(true);
416 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 412 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
417 413
418 delegate_->AssertStateConsistent(this); 414 delegate_->AssertStateConsistent(this);
419 Cancel(true); 415 Cancel(true);
420 delegate_->AssertStateConsistent(this); 416 delegate_->AssertStateConsistent(this);
421 417
422 NotifyRemoved(); 418 NotifyRemoved();
423 delegate_->DownloadRemoved(this); 419 delegate_->DownloadRemoved(this);
(...skipping 968 matching lines...) Expand 10 before | Expand all | Expand 10 after
1392 if (destroy_file) { 1388 if (destroy_file) {
1393 BrowserThread::PostTask( 1389 BrowserThread::PostTask(
1394 BrowserThread::FILE, FROM_HERE, 1390 BrowserThread::FILE, FROM_HERE,
1395 // Will be deleted at end of task execution. 1391 // Will be deleted at end of task execution.
1396 base::Bind(&DownloadFileCancel, base::Passed(&download_file_))); 1392 base::Bind(&DownloadFileCancel, base::Passed(&download_file_)));
1397 // Avoid attempting to reuse the intermediate file by clearing out 1393 // Avoid attempting to reuse the intermediate file by clearing out
1398 // current_path_. 1394 // current_path_.
1399 current_path_.clear(); 1395 current_path_.clear();
1400 } else { 1396 } else {
1401 BrowserThread::PostTask( 1397 BrowserThread::PostTask(
1402 BrowserThread::FILE, FROM_HERE, 1398 BrowserThread::FILE,
1403 // Will be deleted at end of task execution. 1399 FROM_HERE,
1404 base::Bind(&DownloadFileDetach, base::Passed(&download_file_))); 1400 base::Bind(base::IgnoreResult(&DownloadFileDetach),
1401 // Will be deleted at end of task execution.
1402 base::Passed(&download_file_)));
1405 } 1403 }
1406 // Don't accept any more messages from the DownloadFile, and null 1404 // Don't accept any more messages from the DownloadFile, and null
1407 // out any previous "all data received". This also breaks links to 1405 // out any previous "all data received". This also breaks links to
1408 // other entities we've given out weak pointers to. 1406 // other entities we've given out weak pointers to.
1409 weak_ptr_factory_.InvalidateWeakPtrs(); 1407 weak_ptr_factory_.InvalidateWeakPtrs();
1410 } 1408 }
1411 1409
1412 bool DownloadItemImpl::IsDownloadReadyForCompletion( 1410 bool DownloadItemImpl::IsDownloadReadyForCompletion(
1413 const base::Closure& state_change_notification) { 1411 const base::Closure& state_change_notification) {
1414 // If we don't have all the data, the download is not ready for 1412 // If we don't have all the data, the download is not ready for
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
1678 case RESUME_MODE_USER_CONTINUE: 1676 case RESUME_MODE_USER_CONTINUE:
1679 return "USER_CONTINUE"; 1677 return "USER_CONTINUE";
1680 case RESUME_MODE_USER_RESTART: 1678 case RESUME_MODE_USER_RESTART:
1681 return "USER_RESTART"; 1679 return "USER_RESTART";
1682 } 1680 }
1683 NOTREACHED() << "Unknown resume mode " << mode; 1681 NOTREACHED() << "Unknown resume mode " << mode;
1684 return "unknown"; 1682 return "unknown";
1685 } 1683 }
1686 1684
1687 } // namespace content 1685 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698