| 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 #include "chrome/browser/ui/views/download/download_item_view.h" | 5 #include "chrome/browser/ui/views/download/download_item_view.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 // TODO(paulg): These may need to be adjusted when download progress | 42 // TODO(paulg): These may need to be adjusted when download progress |
| 43 // animation is added, and also possibly to take into account | 43 // animation is added, and also possibly to take into account |
| 44 // different screen resolutions. | 44 // different screen resolutions. |
| 45 static const int kTextWidth = 140; // Pixels | 45 static const int kTextWidth = 140; // Pixels |
| 46 static const int kDangerousTextWidth = 200; // Pixels | 46 static const int kDangerousTextWidth = 200; // Pixels |
| 47 static const int kHorizontalTextPadding = 2; // Pixels | 47 static const int kHorizontalTextPadding = 2; // Pixels |
| 48 static const int kVerticalPadding = 3; // Pixels | 48 static const int kVerticalPadding = 3; // Pixels |
| 49 static const int kVerticalTextSpacer = 2; // Pixels | 49 static const int kVerticalTextSpacer = 2; // Pixels |
| 50 static const int kVerticalTextPadding = 2; // Pixels | 50 static const int kVerticalTextPadding = 2; // Pixels |
| 51 | 51 |
| 52 // The maximum number of characters we show in a file name when displaying the | |
| 53 // dangerous download message. | |
| 54 static const int kFileNameMaxLength = 20; | |
| 55 | |
| 56 // We add some padding before the left image so that the progress animation icon | 52 // We add some padding before the left image so that the progress animation icon |
| 57 // hides the corners of the left image. | 53 // hides the corners of the left image. |
| 58 static const int kLeftPadding = 0; // Pixels. | 54 static const int kLeftPadding = 0; // Pixels. |
| 59 | 55 |
| 60 // The space between the Save and Discard buttons when prompting for a dangerous | 56 // The space between the Save and Discard buttons when prompting for a dangerous |
| 61 // download. | 57 // download. |
| 62 static const int kButtonPadding = 5; // Pixels. | 58 static const int kButtonPadding = 5; // Pixels. |
| 63 | 59 |
| 64 // The space on the left and right side of the dangerous download label. | 60 // The space on the left and right side of the dangerous download label. |
| 65 static const int kLabelPadding = 4; // Pixels. | 61 static const int kLabelPadding = 4; // Pixels. |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 if (download_util::kSmallProgressIconSize > box_height_) | 194 if (download_util::kSmallProgressIconSize > box_height_) |
| 199 box_y_ = (download_util::kSmallProgressIconSize - box_height_) / 2; | 195 box_y_ = (download_util::kSmallProgressIconSize - box_height_) / 2; |
| 200 else | 196 else |
| 201 box_y_ = kVerticalPadding; | 197 box_y_ = kVerticalPadding; |
| 202 | 198 |
| 203 body_hover_animation_.reset(new ui::SlideAnimation(this)); | 199 body_hover_animation_.reset(new ui::SlideAnimation(this)); |
| 204 drop_hover_animation_.reset(new ui::SlideAnimation(this)); | 200 drop_hover_animation_.reset(new ui::SlideAnimation(this)); |
| 205 | 201 |
| 206 UpdateDropDownButtonPosition(); | 202 UpdateDropDownButtonPosition(); |
| 207 | 203 |
| 208 if (download->GetSafetyState() == DownloadItem::DANGEROUS) | 204 if (model_->IsDangerous()) |
| 209 ShowWarningDialog(); | 205 ShowWarningDialog(); |
| 210 | 206 |
| 211 UpdateAccessibleName(); | 207 UpdateAccessibleName(); |
| 212 set_accessibility_focusable(true); | 208 set_accessibility_focusable(true); |
| 213 | 209 |
| 214 // Set up our animation. | 210 // Set up our animation. |
| 215 StartDownloadProgress(); | 211 StartDownloadProgress(); |
| 216 } | 212 } |
| 217 | 213 |
| 218 DownloadItemView::~DownloadItemView() { | 214 DownloadItemView::~DownloadItemView() { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 248 parent()->SchedulePaint(); | 244 parent()->SchedulePaint(); |
| 249 } | 245 } |
| 250 | 246 |
| 251 // DownloadObserver interface. | 247 // DownloadObserver interface. |
| 252 | 248 |
| 253 // Update the progress graphic on the icon and our text status label | 249 // Update the progress graphic on the icon and our text status label |
| 254 // to reflect our current bytes downloaded, time remaining. | 250 // to reflect our current bytes downloaded, time remaining. |
| 255 void DownloadItemView::OnDownloadUpdated(DownloadItem* download) { | 251 void DownloadItemView::OnDownloadUpdated(DownloadItem* download) { |
| 256 DCHECK(download == download_); | 252 DCHECK(download == download_); |
| 257 | 253 |
| 258 if (IsShowingWarningDialog() && | 254 if (IsShowingWarningDialog() && !model_->IsDangerous()) { |
| 259 download->GetSafetyState() == DownloadItem::DANGEROUS_BUT_VALIDATED) { | |
| 260 // We have been approved. | 255 // We have been approved. |
| 261 ClearWarningDialog(); | 256 ClearWarningDialog(); |
| 262 } else if (!IsShowingWarningDialog() && | 257 } else if (!IsShowingWarningDialog() && model_->IsDangerous()) { |
| 263 download->GetSafetyState() == DownloadItem::DANGEROUS) { | |
| 264 ShowWarningDialog(); | 258 ShowWarningDialog(); |
| 265 // Force the shelf to layout again as our size has changed. | 259 // Force the shelf to layout again as our size has changed. |
| 266 parent_->Layout(); | 260 parent_->Layout(); |
| 267 SchedulePaint(); | 261 SchedulePaint(); |
| 268 } else { | 262 } else { |
| 269 string16 status_text = model_->GetStatusText(); | 263 string16 status_text = model_->GetStatusText(); |
| 270 switch (download_->GetState()) { | 264 switch (download_->GetState()) { |
| 271 case DownloadItem::IN_PROGRESS: | 265 case DownloadItem::IN_PROGRESS: |
| 272 download_->IsPaused() ? | 266 download_->IsPaused() ? |
| 273 StopDownloadProgress() : StartDownloadProgress(); | 267 StopDownloadProgress() : StartDownloadProgress(); |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 566 if (!context_menu_.get()) | 560 if (!context_menu_.get()) |
| 567 context_menu_.reset(new DownloadShelfContextMenuView(model_.get())); | 561 context_menu_.reset(new DownloadShelfContextMenuView(model_.get())); |
| 568 context_menu_->Run(GetWidget()->GetTopLevelWidget(), | 562 context_menu_->Run(GetWidget()->GetTopLevelWidget(), |
| 569 gfx::Rect(point, size)); | 563 gfx::Rect(point, size)); |
| 570 // We could be deleted now. | 564 // We could be deleted now. |
| 571 } | 565 } |
| 572 | 566 |
| 573 void DownloadItemView::GetAccessibleState(ui::AccessibleViewState* state) { | 567 void DownloadItemView::GetAccessibleState(ui::AccessibleViewState* state) { |
| 574 state->name = accessible_name_; | 568 state->name = accessible_name_; |
| 575 state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON; | 569 state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON; |
| 576 if (download_->GetSafetyState() == DownloadItem::DANGEROUS) { | 570 if (model_->IsDangerous()) { |
| 577 state->state = ui::AccessibilityTypes::STATE_UNAVAILABLE; | 571 state->state = ui::AccessibilityTypes::STATE_UNAVAILABLE; |
| 578 } else { | 572 } else { |
| 579 state->state = ui::AccessibilityTypes::STATE_HASPOPUP; | 573 state->state = ui::AccessibilityTypes::STATE_HASPOPUP; |
| 580 } | 574 } |
| 581 } | 575 } |
| 582 | 576 |
| 583 void DownloadItemView::ButtonPressed( | 577 void DownloadItemView::ButtonPressed( |
| 584 views::Button* sender, const views::Event& event) { | 578 views::Button* sender, const views::Event& event) { |
| 585 if (sender == discard_button_) { | 579 if (sender == discard_button_) { |
| 586 UMA_HISTOGRAM_LONG_TIMES("clickjacking.discard_download", | 580 UMA_HISTOGRAM_LONG_TIMES("clickjacking.discard_download", |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 997 LoadIcon(); | 991 LoadIcon(); |
| 998 tooltip_text_ = download_->GetFileNameToReportUser().LossyDisplayName(); | 992 tooltip_text_ = download_->GetFileNameToReportUser().LossyDisplayName(); |
| 999 | 993 |
| 1000 // Force the shelf to layout again as our size has changed. | 994 // Force the shelf to layout again as our size has changed. |
| 1001 parent_->Layout(); | 995 parent_->Layout(); |
| 1002 parent_->SchedulePaint(); | 996 parent_->SchedulePaint(); |
| 1003 } | 997 } |
| 1004 | 998 |
| 1005 void DownloadItemView::ShowWarningDialog() { | 999 void DownloadItemView::ShowWarningDialog() { |
| 1006 DCHECK(mode_ != DANGEROUS_MODE && mode_ != MALICIOUS_MODE); | 1000 DCHECK(mode_ != DANGEROUS_MODE && mode_ != MALICIOUS_MODE); |
| 1007 if (download_->GetDangerType() == | 1001 mode_ = ((model_->IsMalicious()) ? MALICIOUS_MODE : DANGEROUS_MODE); |
| 1008 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL || | 1002 |
| 1009 download_->GetDangerType() == | |
| 1010 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT) { | |
| 1011 mode_ = MALICIOUS_MODE; | |
| 1012 } else { | |
| 1013 DCHECK(download_->GetDangerType() == | |
| 1014 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); | |
| 1015 mode_ = DANGEROUS_MODE; | |
| 1016 } | |
| 1017 body_state_ = NORMAL; | 1003 body_state_ = NORMAL; |
| 1018 drop_down_state_ = NORMAL; | 1004 drop_down_state_ = NORMAL; |
| 1019 tooltip_text_.clear(); | 1005 tooltip_text_.clear(); |
| 1020 if (mode_ == DANGEROUS_MODE) { | 1006 if (mode_ == DANGEROUS_MODE) { |
| 1021 save_button_ = new views::NativeTextButton(this, | 1007 save_button_ = new views::NativeTextButton( |
| 1022 l10n_util::GetStringUTF16( | 1008 this, model_->GetWarningConfirmButtonText()); |
| 1023 ChromeDownloadManagerDelegate::IsExtensionDownload(download_) ? | |
| 1024 IDS_CONTINUE_EXTENSION_DOWNLOAD : IDS_CONFIRM_DOWNLOAD)); | |
| 1025 save_button_->set_ignore_minimum_size(true); | 1009 save_button_->set_ignore_minimum_size(true); |
| 1026 AddChildView(save_button_); | 1010 AddChildView(save_button_); |
| 1027 } | 1011 } |
| 1028 discard_button_ = new views::NativeTextButton( | 1012 discard_button_ = new views::NativeTextButton( |
| 1029 this, l10n_util::GetStringUTF16(IDS_DISCARD_DOWNLOAD)); | 1013 this, l10n_util::GetStringUTF16(IDS_DISCARD_DOWNLOAD)); |
| 1030 discard_button_->set_ignore_minimum_size(true); | 1014 discard_button_->set_ignore_minimum_size(true); |
| 1031 AddChildView(discard_button_); | 1015 AddChildView(discard_button_); |
| 1032 | 1016 |
| 1033 // Ensure the file name is not too long. | |
| 1034 | |
| 1035 // Extract the file extension (if any). | |
| 1036 FilePath filename(download_->GetTargetName()); | |
| 1037 #if defined(OS_POSIX) | |
| 1038 string16 extension = WideToUTF16(base::SysNativeMBToWide( | |
| 1039 filename.Extension())); | |
| 1040 #else | |
| 1041 string16 extension = filename.Extension(); | |
| 1042 #endif | |
| 1043 | |
| 1044 // Remove leading '.' | |
| 1045 if (extension.length() > 0) | |
| 1046 extension = extension.substr(1); | |
| 1047 #if defined(OS_POSIX) | |
| 1048 string16 rootname = WideToUTF16(base::SysNativeMBToWide( | |
| 1049 filename.RemoveExtension().value())); | |
| 1050 #else | |
| 1051 string16 rootname = filename.RemoveExtension().value(); | |
| 1052 #endif | |
| 1053 | |
| 1054 // Elide giant extensions (this shouldn't currently be hit, but might | |
| 1055 // in future, should we ever notice unsafe giant extensions). | |
| 1056 if (extension.length() > kFileNameMaxLength / 2) | |
| 1057 ui::ElideString(extension, kFileNameMaxLength / 2, &extension); | |
| 1058 | |
| 1059 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 1017 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 1060 // The dangerous download label text and icon are different | 1018 // The dangerous download label text and icon are different under |
| 1061 // under different cases. | 1019 // different cases. |
| 1062 if (mode_ == MALICIOUS_MODE) { | 1020 if (mode_ == MALICIOUS_MODE) { |
| 1063 warning_icon_ = rb.GetBitmapNamed(IDR_SAFEBROWSING_WARNING); | 1021 warning_icon_ = rb.GetBitmapNamed(IDR_SAFEBROWSING_WARNING); |
| 1064 } else { | 1022 } else { |
| 1065 DCHECK(download_->GetDangerType() == | |
| 1066 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); | |
| 1067 // The download file has dangerous file type (e.g.: an executable). | 1023 // The download file has dangerous file type (e.g.: an executable). |
| 1068 warning_icon_ = rb.GetBitmapNamed(IDR_WARNING); | 1024 warning_icon_ = rb.GetBitmapNamed(IDR_WARNING); |
| 1069 } | 1025 } |
| 1070 string16 dangerous_label; | 1026 string16 dangerous_label = model_->GetWarningText(font_, kTextWidth); |
| 1071 if (download_->GetDangerType() == | |
| 1072 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL) { | |
| 1073 // Safebrowsing shows the download URL or content leads to malicious file. | |
| 1074 dangerous_label = l10n_util::GetStringUTF16( | |
| 1075 IDS_PROMPT_MALICIOUS_DOWNLOAD_URL); | |
| 1076 } else if (download_->GetDangerType() == | |
| 1077 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE && | |
| 1078 ChromeDownloadManagerDelegate::IsExtensionDownload(download_)) { | |
| 1079 dangerous_label = | |
| 1080 l10n_util::GetStringUTF16(IDS_PROMPT_DANGEROUS_DOWNLOAD_EXTENSION); | |
| 1081 } else { | |
| 1082 // The download file has dangerous file type (e.g.: an executable) or the | |
| 1083 // file content is known to be malicious. | |
| 1084 DCHECK(download_->GetDangerType() == | |
| 1085 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE || | |
| 1086 download_->GetDangerType() == | |
| 1087 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT); | |
| 1088 ui::ElideString(rootname, | |
| 1089 kFileNameMaxLength - extension.length(), | |
| 1090 &rootname); | |
| 1091 string16 filename = rootname + ASCIIToUTF16(".") + extension; | |
| 1092 filename = base::i18n::GetDisplayStringInLTRDirectionality(filename); | |
| 1093 dangerous_label = l10n_util::GetStringFUTF16( | |
| 1094 download_->GetDangerType() == | |
| 1095 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE ? | |
| 1096 IDS_PROMPT_DANGEROUS_DOWNLOAD : | |
| 1097 IDS_PROMPT_MALICIOUS_DOWNLOAD_CONTENT, | |
| 1098 filename); | |
| 1099 } | |
| 1100 | |
| 1101 dangerous_download_label_ = new views::Label(dangerous_label); | 1027 dangerous_download_label_ = new views::Label(dangerous_label); |
| 1102 dangerous_download_label_->SetMultiLine(true); | 1028 dangerous_download_label_->SetMultiLine(true); |
| 1103 dangerous_download_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | 1029 dangerous_download_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
| 1104 dangerous_download_label_->SetAutoColorReadabilityEnabled(false); | 1030 dangerous_download_label_->SetAutoColorReadabilityEnabled(false); |
| 1105 AddChildView(dangerous_download_label_); | 1031 AddChildView(dangerous_download_label_); |
| 1106 SizeLabelToMinWidth(); | 1032 SizeLabelToMinWidth(); |
| 1107 UpdateDropDownButtonPosition(); | 1033 UpdateDropDownButtonPosition(); |
| 1108 } | 1034 } |
| 1109 | 1035 |
| 1110 gfx::Size DownloadItemView::GetButtonSize() { | 1036 gfx::Size DownloadItemView::GetButtonSize() { |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1238 // Drop down button is glued to the left of the download shelf. | 1164 // Drop down button is glued to the left of the download shelf. |
| 1239 drop_down_x_left_ = 0; | 1165 drop_down_x_left_ = 0; |
| 1240 drop_down_x_right_ = normal_drop_down_image_set_.top->width(); | 1166 drop_down_x_right_ = normal_drop_down_image_set_.top->width(); |
| 1241 } else { | 1167 } else { |
| 1242 // Drop down button is glued to the right of the download shelf. | 1168 // Drop down button is glued to the right of the download shelf. |
| 1243 drop_down_x_left_ = | 1169 drop_down_x_left_ = |
| 1244 size.width() - normal_drop_down_image_set_.top->width(); | 1170 size.width() - normal_drop_down_image_set_.top->width(); |
| 1245 drop_down_x_right_ = size.width(); | 1171 drop_down_x_right_ = size.width(); |
| 1246 } | 1172 } |
| 1247 } | 1173 } |
| OLD | NEW |