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