Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(636)

Side by Side Diff: chrome/browser/download/download_util.cc

Issue 3127008: Preliminary work on resuming downloads whose connections have expired.
Patch Set: Waiting to send download automation error message until after other downloads are canceled. Created 10 years, 3 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
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 // Download utility implementation 5 // Download utility implementation
6 6
7 #include "chrome/browser/download/download_util.h" 7 #include "chrome/browser/download/download_util.h"
8 8
9 #if defined(OS_WIN) 9 #if defined(OS_WIN)
10 #include <shobjidl.h> 10 #include <shobjidl.h>
11 #endif 11 #endif
12 #include <string> 12 #include <string>
13 13
14 #include "app/l10n_util.h" 14 #include "app/l10n_util.h"
15 #include "app/resource_bundle.h" 15 #include "app/resource_bundle.h"
16 #include "base/file_path.h"
16 #include "base/file_util.h" 17 #include "base/file_util.h"
17 #include "base/i18n/rtl.h" 18 #include "base/i18n/rtl.h"
18 #include "base/i18n/time_formatting.h" 19 #include "base/i18n/time_formatting.h"
19 #include "base/path_service.h" 20 #include "base/path_service.h"
20 #include "base/singleton.h" 21 #include "base/singleton.h"
21 #include "base/string16.h" 22 #include "base/string16.h"
22 #include "base/string_number_conversions.h" 23 #include "base/string_number_conversions.h"
23 #include "base/sys_string_conversions.h" 24 #include "base/sys_string_conversions.h"
24 #include "base/utf_string_conversions.h" 25 #include "base/utf_string_conversions.h"
25 #include "base/values.h" 26 #include "base/values.h"
26 #include "chrome/browser/browser.h" 27 #include "chrome/browser/browser.h"
27 #include "chrome/browser/browser_list.h" 28 #include "chrome/browser/browser_list.h"
28 #include "chrome/browser/browser_process.h" 29 #include "chrome/browser/browser_process.h"
29 #include "chrome/browser/chrome_thread.h" 30 #include "chrome/browser/chrome_thread.h"
30 #include "chrome/browser/download/download_item.h" 31 #include "chrome/browser/download/download_item.h"
31 #include "chrome/browser/download/download_item_model.h" 32 #include "chrome/browser/download/download_item_model.h"
32 #include "chrome/browser/download/download_manager.h" 33 #include "chrome/browser/download/download_manager.h"
34 #include "chrome/browser/download/download_types.h"
33 #include "chrome/browser/extensions/crx_installer.h" 35 #include "chrome/browser/extensions/crx_installer.h"
34 #include "chrome/browser/extensions/extension_install_ui.h" 36 #include "chrome/browser/extensions/extension_install_ui.h"
35 #include "chrome/browser/extensions/extensions_service.h" 37 #include "chrome/browser/extensions/extensions_service.h"
36 #include "chrome/browser/history/download_create_info.h" 38 #include "chrome/browser/history/download_create_info.h"
37 #include "chrome/browser/net/chrome_url_request_context.h" 39 #include "chrome/browser/net/chrome_url_request_context.h"
38 #include "chrome/browser/profile.h" 40 #include "chrome/browser/profile.h"
39 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" 41 #include "chrome/browser/renderer_host/resource_dispatcher_host.h"
40 #include "chrome/browser/tab_contents/infobar_delegate.h" 42 #include "chrome/browser/tab_contents/infobar_delegate.h"
41 #include "chrome/browser/tab_contents/tab_contents.h" 43 #include "chrome/browser/tab_contents/tab_contents.h"
42 #include "chrome/common/chrome_paths.h" 44 #include "chrome/common/chrome_paths.h"
(...skipping 28 matching lines...) Expand all
71 #include "app/os_exchange_data_provider_win.h" 73 #include "app/os_exchange_data_provider_win.h"
72 #include "app/win_util.h" 74 #include "app/win_util.h"
73 #include "base/base_drag_source.h" 75 #include "base/base_drag_source.h"
74 #include "base/registry.h" 76 #include "base/registry.h"
75 #include "base/scoped_comptr_win.h" 77 #include "base/scoped_comptr_win.h"
76 #include "base/win_util.h" 78 #include "base/win_util.h"
77 #include "chrome/browser/browser_list.h" 79 #include "chrome/browser/browser_list.h"
78 #include "chrome/browser/views/frame/browser_view.h" 80 #include "chrome/browser/views/frame/browser_view.h"
79 #endif 81 #endif
80 82
83 static const double PI = 3.141592653589793;
84
81 namespace download_util { 85 namespace download_util {
82 86
83 // How many times to cycle the complete animation. This should be an odd number 87 // How many times to cycle the complete animation. This should be an odd number
84 // so that the animation ends faded out. 88 // so that the animation ends faded out.
85 static const int kCompleteAnimationCycles = 5; 89 static const int kCompleteAnimationCycles = 5;
86 90
87 // Download temporary file creation -------------------------------------------- 91 // Download temporary file creation --------------------------------------------
88 92
89 class DefaultDownloadDirectory { 93 class DefaultDownloadDirectory {
90 public: 94 public:
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 gfx::Rect complete_bounds(origin_x, origin_y, 449 gfx::Rect complete_bounds(origin_x, origin_y,
446 complete->width(), complete->height()); 450 complete->width(), complete->height());
447 #if defined(TOOLKIT_VIEWS) 451 #if defined(TOOLKIT_VIEWS)
448 // Mirror the positions if necessary. 452 // Mirror the positions if necessary.
449 complete_bounds.set_x( 453 complete_bounds.set_x(
450 containing_view->MirroredLeftPointForRect(complete_bounds)); 454 containing_view->MirroredLeftPointForRect(complete_bounds));
451 #endif 455 #endif
452 456
453 // Start at full opacity, then loop back and forth five times before ending 457 // Start at full opacity, then loop back and forth five times before ending
454 // at zero opacity. 458 // at zero opacity.
455 static const double PI = 3.141592653589793;
456 double opacity = sin(animation_progress * PI * kCompleteAnimationCycles + 459 double opacity = sin(animation_progress * PI * kCompleteAnimationCycles +
457 PI/2) / 2 + 0.5; 460 PI/2) / 2 + 0.5;
458 461
459 canvas->SaveLayerAlpha(static_cast<int>(255.0 * opacity), complete_bounds); 462 canvas->SaveLayerAlpha(static_cast<int>(255.0 * opacity), complete_bounds);
460 canvas->AsCanvasSkia()->drawARGB(0, 255, 255, 255, SkXfermode::kClear_Mode); 463 canvas->AsCanvasSkia()->drawARGB(0, 255, 255, 255, SkXfermode::kClear_Mode);
461 canvas->DrawBitmapInt(*complete, complete_bounds.x(), complete_bounds.y()); 464 canvas->DrawBitmapInt(*complete, complete_bounds.x(), complete_bounds.y());
462 canvas->Restore(); 465 canvas->Restore();
463 } 466 }
464 467
468 void PaintDownloadInterrupted(gfx::Canvas* canvas,
469 #if defined(TOOLKIT_VIEWS)
470 views::View* containing_view,
471 #endif
472 int origin_x,
473 int origin_y,
474 double animation_progress,
475 PaintDownloadProgressSize size) {
476 // Load up our common bitmaps.
477 if (!g_foreground_16) {
478 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
479 g_foreground_16 = rb.GetBitmapNamed(IDR_DOWNLOAD_PROGRESS_FOREGROUND_16);
480 g_foreground_32 = rb.GetBitmapNamed(IDR_DOWNLOAD_PROGRESS_FOREGROUND_32);
481 }
482
483 SkBitmap* complete = (size == BIG) ? g_foreground_32 : g_foreground_16;
484
485 gfx::Rect complete_bounds(origin_x, origin_y,
486 complete->width(), complete->height());
487 #if defined(TOOLKIT_VIEWS)
488 // Mirror the positions if necessary.
489 complete_bounds.set_x(
490 containing_view->MirroredLeftPointForRect(complete_bounds));
491 #endif
492
493 // Start at zero opacity, then loop back and forth five times before ending
494 // at full opacity.
495 double opacity =
496 sin((1.0 - animation_progress) * PI * kCompleteAnimationCycles +
497 PI/2) / 2 + 0.5;
498
499 canvas->SaveLayerAlpha(static_cast<int>(255.0 * opacity), complete_bounds);
500 canvas->AsCanvasSkia()->drawARGB(0, 255, 255, 255, SkXfermode::kClear_Mode);
501 canvas->DrawBitmapInt(*complete, complete_bounds.x(), complete_bounds.y());
502 canvas->Restore();
503 }
504
465 // Load a language dependent height so that the dangerous download confirmation 505 // Load a language dependent height so that the dangerous download confirmation
466 // message doesn't overlap with the download link label. 506 // message doesn't overlap with the download link label.
467 int GetBigProgressIconSize() { 507 int GetBigProgressIconSize() {
468 static int big_progress_icon_size = 0; 508 static int big_progress_icon_size = 0;
469 if (big_progress_icon_size == 0) { 509 if (big_progress_icon_size == 0) {
470 string16 locale_size_str = 510 string16 locale_size_str =
471 l10n_util::GetStringUTF16(IDS_DOWNLOAD_BIG_PROGRESS_SIZE); 511 l10n_util::GetStringUTF16(IDS_DOWNLOAD_BIG_PROGRESS_SIZE);
472 bool rc = base::StringToInt(locale_size_str, &big_progress_icon_size); 512 bool rc = base::StringToInt(locale_size_str, &big_progress_icon_size);
473 if (!rc || big_progress_icon_size < kBigProgressIconSize) { 513 if (!rc || big_progress_icon_size < kBigProgressIconSize) {
474 NOTREACHED(); 514 NOTREACHED();
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 file_value->SetString("state", "IN_PROGRESS"); 606 file_value->SetString("state", "IN_PROGRESS");
567 } 607 }
568 608
569 file_value->SetString("progress_status_text", 609 file_value->SetString("progress_status_text",
570 WideToUTF16Hack(GetProgressStatusText(download))); 610 WideToUTF16Hack(GetProgressStatusText(download)));
571 611
572 file_value->SetInteger("percent", 612 file_value->SetInteger("percent",
573 static_cast<int>(download->PercentComplete())); 613 static_cast<int>(download->PercentComplete()));
574 file_value->SetInteger("received", 614 file_value->SetInteger("received",
575 static_cast<int>(download->received_bytes())); 615 static_cast<int>(download->received_bytes()));
616 } else if (download->state() == DownloadItem::INTERRUPTED) {
617 if (download->safety_state() == DownloadItem::DANGEROUS) {
618 file_value->SetString("state", "DANGEROUS");
619 } else {
620 file_value->SetString("state", "INTERRUPTED");
621 }
622
623 file_value->SetString("progress_status_text",
624 WideToUTF16Hack(GetProgressStatusText(download)));
625
626 file_value->SetInteger("percent",
627 static_cast<int>(download->PercentComplete()));
628 file_value->SetInteger("received",
629 static_cast<int>(download->received_bytes()));
576 } else if (download->state() == DownloadItem::CANCELLED) { 630 } else if (download->state() == DownloadItem::CANCELLED) {
577 file_value->SetString("state", "CANCELLED"); 631 file_value->SetString("state", "CANCELLED");
578 } else if (download->state() == DownloadItem::COMPLETE) { 632 } else if (download->state() == DownloadItem::COMPLETE) {
579 if (download->safety_state() == DownloadItem::DANGEROUS) { 633 if (download->safety_state() == DownloadItem::DANGEROUS) {
580 file_value->SetString("state", "DANGEROUS"); 634 file_value->SetString("state", "DANGEROUS");
581 } else { 635 } else {
582 file_value->SetString("state", "COMPLETE"); 636 file_value->SetString("state", "COMPLETE");
583 } 637 }
584 } 638 }
585 639
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 776
723 URLRequestContext* context = request_context_getter->GetURLRequestContext(); 777 URLRequestContext* context = request_context_getter->GetURLRequestContext();
724 context->set_referrer_charset(referrer_charset); 778 context->set_referrer_charset(referrer_charset);
725 779
726 rdh->BeginDownload(url, 780 rdh->BeginDownload(url,
727 referrer, 781 referrer,
728 save_info, 782 save_info,
729 true, // Show "Save as" UI. 783 true, // Show "Save as" UI.
730 render_process_host_id, 784 render_process_host_id,
731 render_view_id, 785 render_view_id,
732 context); 786 context,
787 0);
788 }
789
790 static void PostBeginDownload(ResourceDispatcherHost* rdh,
791 const GURL& url,
792 const GURL& referrer,
793 const DownloadSaveInfo& save_info,
794 int render_process_host_id,
795 int render_view_id,
796 uint64 start_offset) {
797 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
798 URLRequestContextGetter* context_getter = Profile::GetDefaultRequestContext();
799 if (context_getter) {
800 URLRequestContext* context = context_getter->GetURLRequestContext();
801 // |referrer_charset| is used to construct suggested filename, but we are
802 // using an existing file so we don't need to set it.
803
804 rdh->BeginDownload(url,
805 referrer,
806 save_info,
807 false, // Don't show "Save as" UI.
808 render_process_host_id,
809 render_view_id,
810 context,
811 start_offset);
812 }
813 }
814
815 void RestartDownloadUrl(
816 ResourceDispatcherHost* rdh,
817 const GURL& url,
818 const GURL& referrer,
819 const FilePath& path,
820 int64 start_offset,
821 int render_process_host_id,
822 int render_view_id) {
823 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
824
825 // Get the temporary file and rename it to the original value.
826 FilePath crpath = download_util::GetCrDownloadPath(path);
827
828 // Validate the start offset.
829 int64 end = 0;
830 if (file_util::GetFileSize(crpath, &end)) {
831 if (end != start_offset) {
832 LOG(WARNING) << " File size (" << end
833 << ") is different from the expected size (" << start_offset
834 << ") for \"" << path.value() << "\"";
835 }
836 }
837
838 DownloadSaveInfo save_info;
839 save_info.file_path = path;
840
841 ChromeThread::PostTask(
842 ChromeThread::IO,
843 FROM_HERE,
844 NewRunnableFunction(&PostBeginDownload,
845 rdh,
846 url,
847 referrer,
848 save_info,
849 render_process_host_id,
850 render_view_id,
851 end));
733 } 852 }
734 853
735 void CancelDownloadRequest(ResourceDispatcherHost* rdh, 854 void CancelDownloadRequest(ResourceDispatcherHost* rdh,
736 int render_process_id, 855 int render_process_id,
737 int request_id) { 856 int request_id) {
738 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); 857 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
739 rdh->CancelRequest(render_process_id, request_id, false); 858 rdh->CancelRequest(render_process_id, request_id, false);
740 } 859 }
741 860
742 int GetUniquePathNumberWithCrDownload(const FilePath& path) { 861 int GetUniquePathNumberWithCrDownload(const FilePath& path) {
(...skipping 16 matching lines...) Expand all
759 return -1; 878 return -1;
760 } 879 }
761 880
762 FilePath GetCrDownloadPath(const FilePath& suggested_path) { 881 FilePath GetCrDownloadPath(const FilePath& suggested_path) {
763 FilePath::StringType file_name; 882 FilePath::StringType file_name;
764 SStringPrintf(&file_name, PRFilePathLiteral FILE_PATH_LITERAL(".crdownload"), 883 SStringPrintf(&file_name, PRFilePathLiteral FILE_PATH_LITERAL(".crdownload"),
765 suggested_path.value().c_str()); 884 suggested_path.value().c_str());
766 return FilePath(file_name); 885 return FilePath(file_name);
767 } 886 }
768 887
888 FilePath RemoveCrDownloadPath(const FilePath& cr_path) {
889 FilePath::StringType file_name = cr_path.value();
890 size_t pos = file_name.find(FILE_PATH_LITERAL(".crdownload"));
891 if (pos != std::string::npos)
892 file_name = file_name.substr(0, pos);
893 return FilePath(file_name);
894 }
895
896 bool IsCrDownloadPath(const FilePath& path) {
897 FilePath::StringType file_name = path.value();
898 FilePath::StringType extension = FILE_PATH_LITERAL(".crdownload");
899 FilePath::StringType::size_type name_len = file_name.length();
900 FilePath::StringType::size_type ext_len = extension.length();
901 if (ext_len > name_len)
902 return false;
903
904 return file_name.substr(name_len - ext_len, ext_len) == extension;
905 }
906
769 } // namespace download_util 907 } // namespace download_util
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698