| 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 // Download utility implementation | 5 // Download utility implementation |
| 6 | 6 |
| 7 #define _USE_MATH_DEFINES // For VC++ to get M_PI. This has to be first. |
| 8 |
| 7 #include "chrome/browser/download/download_util.h" | 9 #include "chrome/browser/download/download_util.h" |
| 8 | 10 |
| 9 #if defined(OS_WIN) | 11 #include <cmath> |
| 10 #include <shobjidl.h> | |
| 11 #endif | |
| 12 #include <string> | 12 #include <string> |
| 13 | 13 |
| 14 #include "base/file_util.h" | 14 #include "base/file_util.h" |
| 15 #include "base/i18n/rtl.h" | 15 #include "base/i18n/rtl.h" |
| 16 #include "base/i18n/time_formatting.h" | 16 #include "base/i18n/time_formatting.h" |
| 17 #include "base/lazy_instance.h" | 17 #include "base/lazy_instance.h" |
| 18 #include "base/metrics/histogram.h" | 18 #include "base/metrics/histogram.h" |
| 19 #include "base/path_service.h" | 19 #include "base/path_service.h" |
| 20 #include "base/string16.h" | 20 #include "base/string16.h" |
| 21 #include "base/string_number_conversions.h" | 21 #include "base/string_number_conversions.h" |
| 22 #include "base/sys_string_conversions.h" | 22 #include "base/sys_string_conversions.h" |
| 23 #include "base/threading/thread_restrictions.h" | 23 #include "base/threading/thread_restrictions.h" |
| 24 #include "base/utf_string_conversions.h" | 24 #include "base/utf_string_conversions.h" |
| 25 #include "base/value_conversions.h" | 25 #include "base/value_conversions.h" |
| 26 #include "base/values.h" | 26 #include "base/values.h" |
| 27 #include "base/win/windows_version.h" | |
| 28 #include "chrome/browser/download/download_extensions.h" | 27 #include "chrome/browser/download/download_extensions.h" |
| 29 #include "chrome/browser/download/download_item_model.h" | 28 #include "chrome/browser/download/download_item_model.h" |
| 30 #include "chrome/browser/profiles/profile.h" | 29 #include "chrome/browser/profiles/profile.h" |
| 31 #include "chrome/browser/ui/browser.h" | 30 #include "chrome/browser/ui/browser.h" |
| 32 #include "chrome/common/chrome_notification_types.h" | 31 #include "chrome/common/chrome_notification_types.h" |
| 33 #include "chrome/common/chrome_paths.h" | 32 #include "chrome/common/chrome_paths.h" |
| 34 #include "chrome/common/time_format.h" | 33 #include "chrome/common/time_format.h" |
| 35 #include "content/public/browser/browser_thread.h" | 34 #include "content/public/browser/browser_thread.h" |
| 36 #include "content/public/browser/download_item.h" | 35 #include "content/public/browser/download_item.h" |
| 37 #include "content/public/browser/download_manager.h" | 36 #include "content/public/browser/download_manager.h" |
| 38 #include "content/public/browser/render_view_host.h" | 37 #include "content/public/browser/render_view_host.h" |
| 39 #include "content/public/common/url_constants.h" | 38 #include "content/public/common/url_constants.h" |
| 40 #include "grit/generated_resources.h" | 39 #include "grit/generated_resources.h" |
| 41 #include "grit/locale_settings.h" | 40 #include "grit/locale_settings.h" |
| 42 #include "grit/theme_resources.h" | 41 #include "grit/theme_resources.h" |
| 43 #include "net/base/mime_util.h" | 42 #include "net/base/mime_util.h" |
| 44 #include "net/base/net_util.h" | 43 #include "net/base/net_util.h" |
| 45 #include "skia/ext/image_operations.h" | 44 #include "skia/ext/image_operations.h" |
| 46 #include "third_party/skia/include/core/SkPath.h" | 45 #include "third_party/skia/include/core/SkPath.h" |
| 47 #include "third_party/skia/include/core/SkShader.h" | 46 #include "third_party/skia/include/core/SkShader.h" |
| 48 #include "ui/base/l10n/l10n_util.h" | 47 #include "ui/base/l10n/l10n_util.h" |
| 49 #include "ui/base/resource/resource_bundle.h" | 48 #include "ui/base/resource/resource_bundle.h" |
| 50 #include "ui/base/text/bytes_formatting.h" | 49 #include "ui/base/text/bytes_formatting.h" |
| 51 #include "ui/gfx/canvas.h" | 50 #include "ui/gfx/canvas.h" |
| 52 #include "ui/gfx/image/image.h" | 51 #include "ui/gfx/image/image.h" |
| 53 #include "ui/gfx/rect.h" | 52 #include "ui/gfx/rect.h" |
| 54 | 53 |
| 54 #if defined(OS_WIN) |
| 55 #include <shobjidl.h> |
| 56 |
| 57 #include "base/win/windows_version.h" |
| 58 #endif |
| 59 |
| 55 #if defined(TOOLKIT_VIEWS) | 60 #if defined(TOOLKIT_VIEWS) |
| 56 #include "ui/base/dragdrop/drag_utils.h" | 61 #include "ui/base/dragdrop/drag_utils.h" |
| 57 #include "ui/base/dragdrop/os_exchange_data.h" | 62 #include "ui/base/dragdrop/os_exchange_data.h" |
| 58 #include "ui/base/dragdrop/drag_drop_types.h" | 63 #include "ui/base/dragdrop/drag_drop_types.h" |
| 59 #include "ui/gfx/screen.h" | 64 #include "ui/gfx/screen.h" |
| 60 #include "ui/views/widget/widget.h" | 65 #include "ui/views/widget/widget.h" |
| 61 #endif | 66 #endif |
| 62 | 67 |
| 63 #if defined(TOOLKIT_GTK) | 68 #if defined(TOOLKIT_GTK) |
| 64 #include "chrome/browser/ui/gtk/custom_drag.h" | 69 #include "chrome/browser/ui/gtk/custom_drag.h" |
| 65 #include "chrome/browser/ui/gtk/unity_service.h" | 70 #include "chrome/browser/ui/gtk/unity_service.h" |
| 66 #endif // defined(TOOLKIT_GTK) | 71 #endif // defined(TOOLKIT_GTK) |
| 67 | 72 |
| 68 #if defined(OS_WIN) && !defined(USE_AURA) | 73 #if defined(OS_WIN) && !defined(USE_AURA) |
| 69 #include "base/win/scoped_comptr.h" | 74 #include "base/win/scoped_comptr.h" |
| 70 #include "chrome/browser/ui/browser_list.h" | 75 #include "chrome/browser/ui/browser_list.h" |
| 71 #include "chrome/browser/ui/views/frame/browser_view.h" | 76 #include "chrome/browser/ui/views/frame/browser_view.h" |
| 72 #include "ui/base/dragdrop/drag_source.h" | 77 #include "ui/base/dragdrop/drag_source.h" |
| 73 #include "ui/base/dragdrop/os_exchange_data_provider_win.h" | 78 #include "ui/base/dragdrop/os_exchange_data_provider_win.h" |
| 74 #endif | 79 #endif |
| 75 | 80 |
| 76 // TODO(phajdan.jr): Find some standard location for this, maintaining | |
| 77 // the same value on all platforms. | |
| 78 static const double PI = 3.141592653589793; | |
| 79 | |
| 80 using content::DownloadItem; | |
| 81 | |
| 82 namespace { | 81 namespace { |
| 83 | 82 |
| 84 // Returns a string constant to be used as the |danger_type| value in | 83 // Returns a string constant to be used as the |danger_type| value in |
| 85 // CreateDownloadItemValue(). We only return strings for DANGEROUS_FILE, | 84 // CreateDownloadItemValue(). We only return strings for DANGEROUS_FILE, |
| 86 // DANGEROUS_URL, DANGEROUS_CONTENT, and UNCOMMON_CONTENT because the | 85 // DANGEROUS_URL, DANGEROUS_CONTENT, and UNCOMMON_CONTENT because the |
| 87 // |danger_type| value is only defined if the value of |state| is |DANGEROUS|. | 86 // |danger_type| value is only defined if the value of |state| is |DANGEROUS|. |
| 88 const char* GetDangerTypeString(content::DownloadDangerType danger_type) { | 87 const char* GetDangerTypeString(content::DownloadDangerType danger_type) { |
| 89 switch (danger_type) { | 88 switch (danger_type) { |
| 90 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE: | 89 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE: |
| 91 return "DANGEROUS_FILE"; | 90 return "DANGEROUS_FILE"; |
| 92 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL: | 91 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL: |
| 93 return "DANGEROUS_URL"; | 92 return "DANGEROUS_URL"; |
| 94 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT: | 93 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT: |
| 95 return "DANGEROUS_CONTENT"; | 94 return "DANGEROUS_CONTENT"; |
| 96 case content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT: | 95 case content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT: |
| 97 return "UNCOMMON_CONTENT"; | 96 return "UNCOMMON_CONTENT"; |
| 98 default: | 97 default: |
| 99 // We shouldn't be returning a danger type string if it is | 98 // We shouldn't be returning a danger type string if it is |
| 100 // NOT_DANGEROUS or MAYBE_DANGEROUS_CONTENT. | 99 // NOT_DANGEROUS or MAYBE_DANGEROUS_CONTENT. |
| 101 NOTREACHED(); | 100 NOTREACHED(); |
| 102 return ""; | 101 return ""; |
| 103 } | 102 } |
| 104 } | 103 } |
| 105 | 104 |
| 105 // Get the opacity based on |animation_progress|, with values in [0.0, 1.0]. |
| 106 // Range of return value is [0, 255]. |
| 107 int GetOpacity(double animation_progress) { |
| 108 DCHECK(animation_progress >= 0 && animation_progress <= 1); |
| 109 |
| 110 // How many times to cycle the complete animation. This should be an odd |
| 111 // number so that the animation ends faded out. |
| 112 static const int kCompleteAnimationCycles = 5; |
| 113 double temp = animation_progress * kCompleteAnimationCycles * M_PI + M_PI_2; |
| 114 temp = sin(temp) / 2 + 0.5; |
| 115 return static_cast<int>(255.0 * temp); |
| 116 } |
| 117 |
| 106 } // namespace | 118 } // namespace |
| 107 | 119 |
| 108 namespace download_util { | 120 namespace download_util { |
| 109 | 121 |
| 110 // How many times to cycle the complete animation. This should be an odd number | 122 using content::DownloadItem; |
| 111 // so that the animation ends faded out. | |
| 112 static const int kCompleteAnimationCycles = 5; | |
| 113 | 123 |
| 114 // Download temporary file creation -------------------------------------------- | 124 // Download temporary file creation -------------------------------------------- |
| 115 | 125 |
| 116 class DefaultDownloadDirectory { | 126 class DefaultDownloadDirectory { |
| 117 public: | 127 public: |
| 118 const FilePath& path() const { return path_; } | 128 const FilePath& path() const { return path_; } |
| 119 private: | 129 private: |
| 120 DefaultDownloadDirectory() { | 130 DefaultDownloadDirectory() { |
| 121 if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &path_)) { | 131 if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &path_)) { |
| 122 NOTREACHED(); | 132 NOTREACHED(); |
| 123 } | 133 } |
| 124 if (DownloadPathIsDangerous(path_)) { | 134 if (DownloadPathIsDangerous(path_)) { |
| 135 // This is only useful on platforms that support |
| 136 // DIR_DEFAULT_DOWNLOADS_SAFE. |
| 125 if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS_SAFE, &path_)) { | 137 if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS_SAFE, &path_)) { |
| 126 NOTREACHED(); | 138 NOTREACHED(); |
| 127 } | 139 } |
| 128 } | 140 } |
| 129 } | 141 } |
| 130 friend struct base::DefaultLazyInstanceTraits<DefaultDownloadDirectory>; | 142 friend struct base::DefaultLazyInstanceTraits<DefaultDownloadDirectory>; |
| 131 FilePath path_; | 143 FilePath path_; |
| 132 }; | 144 }; |
| 133 | 145 |
| 134 static base::LazyInstance<DefaultDownloadDirectory> | 146 static base::LazyInstance<DefaultDownloadDirectory> |
| 135 g_default_download_directory = LAZY_INSTANCE_INITIALIZER; | 147 g_default_download_directory = LAZY_INSTANCE_INITIALIZER; |
| 136 | 148 |
| 137 const FilePath& GetDefaultDownloadDirectory() { | 149 const FilePath& GetDefaultDownloadDirectory() { |
| 138 return g_default_download_directory.Get().path(); | 150 return g_default_download_directory.Get().path(); |
| 139 } | 151 } |
| 140 | 152 |
| 153 // Consider downloads 'dangerous' if they go to the home directory on Linux and |
| 154 // to the desktop on any platform. |
| 141 bool DownloadPathIsDangerous(const FilePath& download_path) { | 155 bool DownloadPathIsDangerous(const FilePath& download_path) { |
| 156 #if defined(OS_LINUX) |
| 157 FilePath home_dir = file_util::GetHomeDir(); |
| 158 if (download_path == home_dir) { |
| 159 return true; |
| 160 } |
| 161 #endif |
| 162 |
| 142 FilePath desktop_dir; | 163 FilePath desktop_dir; |
| 143 if (!PathService::Get(chrome::DIR_USER_DESKTOP, &desktop_dir)) { | 164 if (!PathService::Get(chrome::DIR_USER_DESKTOP, &desktop_dir)) { |
| 144 NOTREACHED(); | 165 NOTREACHED(); |
| 145 return false; | 166 return false; |
| 146 } | 167 } |
| 147 return (download_path == desktop_dir); | 168 return (download_path == desktop_dir); |
| 148 } | 169 } |
| 149 | 170 |
| 150 void GenerateFileNameFromRequest(const DownloadItem& download_item, | 171 void GenerateFileNameFromRequest(const DownloadItem& download_item, |
| 151 FilePath* generated_name) { | 172 FilePath* generated_name) { |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 | 309 |
| 289 gfx::Rect complete_bounds(origin_x, origin_y, | 310 gfx::Rect complete_bounds(origin_x, origin_y, |
| 290 complete->width(), complete->height()); | 311 complete->width(), complete->height()); |
| 291 #if defined(TOOLKIT_VIEWS) | 312 #if defined(TOOLKIT_VIEWS) |
| 292 // Mirror the positions if necessary. | 313 // Mirror the positions if necessary. |
| 293 complete_bounds.set_x(containing_view->GetMirroredXForRect(complete_bounds)); | 314 complete_bounds.set_x(containing_view->GetMirroredXForRect(complete_bounds)); |
| 294 #endif | 315 #endif |
| 295 | 316 |
| 296 // Start at full opacity, then loop back and forth five times before ending | 317 // Start at full opacity, then loop back and forth five times before ending |
| 297 // at zero opacity. | 318 // at zero opacity. |
| 298 double opacity = sin(animation_progress * PI * kCompleteAnimationCycles + | 319 canvas->SaveLayerAlpha(GetOpacity(animation_progress), complete_bounds); |
| 299 PI/2) / 2 + 0.5; | |
| 300 | |
| 301 canvas->SaveLayerAlpha(static_cast<int>(255.0 * opacity), complete_bounds); | |
| 302 canvas->sk_canvas()->drawARGB(0, 255, 255, 255, SkXfermode::kClear_Mode); | 320 canvas->sk_canvas()->drawARGB(0, 255, 255, 255, SkXfermode::kClear_Mode); |
| 303 canvas->DrawBitmapInt(*complete, complete_bounds.x(), complete_bounds.y()); | 321 canvas->DrawBitmapInt(*complete, complete_bounds.x(), complete_bounds.y()); |
| 304 canvas->Restore(); | 322 canvas->Restore(); |
| 305 } | 323 } |
| 306 | 324 |
| 307 void PaintDownloadInterrupted(gfx::Canvas* canvas, | 325 void PaintDownloadInterrupted(gfx::Canvas* canvas, |
| 308 #if defined(TOOLKIT_VIEWS) | 326 #if defined(TOOLKIT_VIEWS) |
| 309 views::View* containing_view, | 327 views::View* containing_view, |
| 310 #endif | 328 #endif |
| 311 int origin_x, | 329 int origin_x, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 323 | 341 |
| 324 gfx::Rect complete_bounds(origin_x, origin_y, | 342 gfx::Rect complete_bounds(origin_x, origin_y, |
| 325 complete->width(), complete->height()); | 343 complete->width(), complete->height()); |
| 326 #if defined(TOOLKIT_VIEWS) | 344 #if defined(TOOLKIT_VIEWS) |
| 327 // Mirror the positions if necessary. | 345 // Mirror the positions if necessary. |
| 328 complete_bounds.set_x(containing_view->GetMirroredXForRect(complete_bounds)); | 346 complete_bounds.set_x(containing_view->GetMirroredXForRect(complete_bounds)); |
| 329 #endif | 347 #endif |
| 330 | 348 |
| 331 // Start at zero opacity, then loop back and forth five times before ending | 349 // Start at zero opacity, then loop back and forth five times before ending |
| 332 // at full opacity. | 350 // at full opacity. |
| 333 double opacity = sin( | 351 canvas->SaveLayerAlpha(GetOpacity(1.0 - animation_progress), complete_bounds); |
| 334 (1.0 - animation_progress) * PI * kCompleteAnimationCycles + PI/2) / 2 + | |
| 335 0.5; | |
| 336 | |
| 337 canvas->SaveLayerAlpha(static_cast<int>(255.0 * opacity), complete_bounds); | |
| 338 canvas->sk_canvas()->drawARGB(0, 255, 255, 255, SkXfermode::kClear_Mode); | 352 canvas->sk_canvas()->drawARGB(0, 255, 255, 255, SkXfermode::kClear_Mode); |
| 339 canvas->DrawBitmapInt(*complete, complete_bounds.x(), complete_bounds.y()); | 353 canvas->DrawBitmapInt(*complete, complete_bounds.x(), complete_bounds.y()); |
| 340 canvas->Restore(); | 354 canvas->Restore(); |
| 341 } | 355 } |
| 342 | 356 |
| 343 // Load a language dependent height so that the dangerous download confirmation | 357 // Load a language dependent height so that the dangerous download confirmation |
| 344 // message doesn't overlap with the download link label. | 358 // message doesn't overlap with the download link label. |
| 345 int GetBigProgressIconSize() { | 359 int GetBigProgressIconSize() { |
| 346 static int big_progress_icon_size = 0; | 360 static int big_progress_icon_size = 0; |
| 347 if (big_progress_icon_size == 0) { | 361 if (big_progress_icon_size == 0) { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 390 } | 404 } |
| 391 | 405 |
| 392 #if !defined(TOOLKIT_GTK) | 406 #if !defined(TOOLKIT_GTK) |
| 393 #if defined(USE_AURA) | 407 #if defined(USE_AURA) |
| 394 views::Widget* widget = views::Widget::GetWidgetForNativeView(view); | 408 views::Widget* widget = views::Widget::GetWidgetForNativeView(view); |
| 395 gfx::Point location = gfx::Screen::GetCursorScreenPoint(); | 409 gfx::Point location = gfx::Screen::GetCursorScreenPoint(); |
| 396 // We do not care about notifying the DragItemView on completion of drag. So | 410 // We do not care about notifying the DragItemView on completion of drag. So |
| 397 // we pass NULL to RunShellDrag for the source view. | 411 // we pass NULL to RunShellDrag for the source view. |
| 398 widget->RunShellDrag(NULL, data, location, | 412 widget->RunShellDrag(NULL, data, location, |
| 399 ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_LINK); | 413 ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_LINK); |
| 400 #else // We are on WIN without AURA | 414 #else // We are on WIN without AURA |
| 401 // We cannot use Widget::RunShellDrag on WIN since the |view| is backed by a | 415 // We cannot use Widget::RunShellDrag on WIN since the |view| is backed by a |
| 402 // TabContentsViewWin, not a NativeWidgetWin. | 416 // TabContentsViewWin, not a NativeWidgetWin. |
| 403 scoped_refptr<ui::DragSource> drag_source(new ui::DragSource); | 417 scoped_refptr<ui::DragSource> drag_source(new ui::DragSource); |
| 404 // Run the drag and drop loop | 418 // Run the drag and drop loop |
| 405 DWORD effects; | 419 DWORD effects; |
| 406 DoDragDrop(ui::OSExchangeDataProviderWin::GetIDataObject(data), | 420 DoDragDrop(ui::OSExchangeDataProviderWin::GetIDataObject(data), |
| 407 drag_source.get(), DROPEFFECT_COPY | DROPEFFECT_LINK, &effects); | 421 drag_source.get(), DROPEFFECT_COPY | DROPEFFECT_LINK, &effects); |
| 408 #endif | 422 #endif |
| 409 | 423 |
| 410 #else | 424 #else |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 642 UMA_HISTOGRAM_ENUMERATION( | 656 UMA_HISTOGRAM_ENUMERATION( |
| 643 "Download.CountsChrome", type, CHROME_DOWNLOAD_COUNT_TYPES_LAST_ENTRY); | 657 "Download.CountsChrome", type, CHROME_DOWNLOAD_COUNT_TYPES_LAST_ENTRY); |
| 644 } | 658 } |
| 645 | 659 |
| 646 void RecordDownloadSource(ChromeDownloadSource source) { | 660 void RecordDownloadSource(ChromeDownloadSource source) { |
| 647 UMA_HISTOGRAM_ENUMERATION( | 661 UMA_HISTOGRAM_ENUMERATION( |
| 648 "Download.SourcesChrome", source, CHROME_DOWNLOAD_SOURCE_LAST_ENTRY); | 662 "Download.SourcesChrome", source, CHROME_DOWNLOAD_SOURCE_LAST_ENTRY); |
| 649 } | 663 } |
| 650 | 664 |
| 651 } // namespace download_util | 665 } // namespace download_util |
| OLD | NEW |