Commit ca0abd4c authored by Daniel Rubery's avatar Daniel Rubery Committed by Commit Bot

Update chrome://downloads UX for WebProtect final states

This CL adds UX on the chrome://downloads page for all the new WebProtect
download states. These correspond to the changes made in the download shelf.

Screenshots:
https://screenshot.googleplex.com/DgQ6RMa47eU.png
https://screenshot.googleplex.com/cRWuijJRw8H.png
https://screenshot.googleplex.com/dT5XRGgX1v0.png
https://screenshot.googleplex.com/5d1DfXa3WYf.png
https://screenshot.googleplex.com/sYeBGWwuJrb.png
https://screenshot.googleplex.com/VAobzSD4J89.png

Bug: 980777
Change-Id: I7b4f8e99dc61cf7c7135fd0a9c03dffefd574f9d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1865039
Commit-Queue: Daniel Rubery <drubery@chromium.org>
Reviewed-by: default avatarDan Beam <dbeam@chromium.org>
Cr-Commit-Position: refs/heads/master@{#707244}
parent 7ca6de3a
...@@ -1607,6 +1607,26 @@ are declared in tools/grit/grit_rule.gni. ...@@ -1607,6 +1607,26 @@ are declared in tools/grit/grit_rule.gni.
desc="Message shown to the user on chrome://downloads page to explain that this download is blocked because it may be dangerous."> desc="Message shown to the user on chrome://downloads page to explain that this download is blocked because it may be dangerous.">
This type of file may harm your computer. This type of file may harm your computer.
</message> </message>
<message name="IDS_DEEP_SCANNED_SAFE_DESCRIPTION"
desc="Message shown to the user on chrome://downloads page to explain this this download was deep scanned, and found to be safe.">
Scan complete, no issues identified.
</message>
<message name="IDS_DEEP_SCANNED_OPENED_DANGEROUS_DESCRIPTION"
desc="Message shown to the user on chrome://downloads page to explain this this download was deep scanned, and found to be malicious.">
Download contains malware.
</message>
<message name="IDS_BLOCK_REASON_SENSITIVE_CONTENT_WARNING" desc="Message shown to the user on chrome://downloads page to explain this download is showing a warning because it contains sensitive content">
This file contains sensitive content.
</message>
<message name="IDS_SENSITIVE_CONTENT_BLOCKED_DESCRIPTION" desc="Message shown to the user on chrome://downloads page to explain this download is blocked because it contains sensitive content">
This file has been blocked because it contains sensitive content.
</message>
<message name="IDS_BLOCKED_TOO_LARGE_DESCRIPTION" desc="Message shown to the user on chrome://downloads page to explain this download is blocked because it is too large for deep scanning">
This file is too large for cloud scanning and has been blocked from opening.
</message>
<message name="IDS_BLOCKED_PASSWORD_PROTECTED_DESCRIPTION" desc="Message shown to the user on chrome://downloads page to explain this download is blocked because it is password protected">
This file is encrypted and has been blocked from opening.
</message>
<if expr="chromeos"> <if expr="chromeos">
<message name="IDS_PROMPT_BLOCKED_MALICIOUS_DOWNLOAD_TITLE" <message name="IDS_PROMPT_BLOCKED_MALICIOUS_DOWNLOAD_TITLE"
......
8c685d8f10818b388126f7224840841e425259ca
\ No newline at end of file
b0b2cfaae0289a3ce9b3f0726c8fe7139985da3e
\ No newline at end of file
8efc789c0d8fad1938532b964e2a3f8457eb553d
\ No newline at end of file
6d7c479d7ef38d40c81c463a94f5991d7efc6e44
\ No newline at end of file
e0805ea96e5ebec1fada17db794f448f7c3ee00c
\ No newline at end of file
51d44bd2905fe06d4f2d7f5ab988f99ab2ac2e84
\ No newline at end of file
...@@ -15,6 +15,12 @@ cr.define('downloads', function() { ...@@ -15,6 +15,12 @@ cr.define('downloads', function() {
UNCOMMON_CONTENT: 'UNCOMMON_CONTENT', UNCOMMON_CONTENT: 'UNCOMMON_CONTENT',
DANGEROUS_HOST: 'DANGEROUS_HOST', DANGEROUS_HOST: 'DANGEROUS_HOST',
POTENTIALLY_UNWANTED: 'POTENTIALLY_UNWANTED', POTENTIALLY_UNWANTED: 'POTENTIALLY_UNWANTED',
DEEP_SCANNED_SAFE: 'DEEP_SCANNED_SAFE',
DEEP_SCANNED_OPENED_DANGEROUS: 'DEEP_SCANNED_OPENED_DANGEROUS',
SENSITIVE_CONTENT_WARNING: 'SENSITIVE_CONTENT_WARNING',
SENSITIVE_CONTENT_BLOCK: 'SENSITIVE_CONTENT_BLOCK',
BLOCKED_TOO_LARGE: 'BLOCKED_TOO_LARGE',
BLOCKED_PASSWORD_PROTECTED: 'BLOCKED_PASSWORD_PROTECTED',
}; };
/** /**
......
...@@ -211,6 +211,15 @@ cr.define('downloads', function() { ...@@ -211,6 +211,15 @@ cr.define('downloads', function() {
const data = this.data; const data = this.data;
switch (data.state) { switch (data.state) {
case downloads.States.COMPLETE:
switch (data.dangerType) {
case downloads.DangerType.DEEP_SCANNED_SAFE:
return loadTimeData.getString('deepScannedSafeDesc');
case downloads.DangerType.DEEP_SCANNED_OPENED_DANGEROUS:
return loadTimeData.getString('deepScannedOpenedDangerousDesc');
}
break;
case downloads.States.DANGEROUS: case downloads.States.DANGEROUS:
const fileName = data.fileName; const fileName = data.fileName;
switch (data.dangerType) { switch (data.dangerType) {
...@@ -227,12 +236,25 @@ cr.define('downloads', function() { ...@@ -227,12 +236,25 @@ cr.define('downloads', function() {
case downloads.DangerType.POTENTIALLY_UNWANTED: case downloads.DangerType.POTENTIALLY_UNWANTED:
return loadTimeData.getString('dangerSettingsDesc'); return loadTimeData.getString('dangerSettingsDesc');
case downloads.DangerType.SENSITIVE_CONTENT_WARNING:
return loadTimeData.getString('sensitiveContentWarningDesc');
} }
break; break;
case downloads.States.IN_PROGRESS: case downloads.States.IN_PROGRESS:
case downloads.States.PAUSED: // Fallthrough. case downloads.States.PAUSED: // Fallthrough.
return data.progressStatusText; return data.progressStatusText;
case downloads.States.INTERRUPTED:
switch (data.dangerType) {
case downloads.DangerType.SENSITIVE_CONTENT_BLOCK:
return loadTimeData.getString('sensitiveContentBlockedDesc');
case downloads.DangerType.BLOCKED_TOO_LARGE:
return loadTimeData.getString('blockedTooLargeDesc');
case downloads.DangerType.BLOCKED_PASSWORD_PROTECTED:
return loadTimeData.getString('blockedPasswordProtectedDesc');
}
} }
return ''; return '';
...@@ -243,10 +265,23 @@ cr.define('downloads', function() { ...@@ -243,10 +265,23 @@ cr.define('downloads', function() {
* @private * @private
*/ */
computeIcon_: function() { computeIcon_: function() {
if (loadTimeData.getBoolean('requestsApVerdicts') && if (this.data) {
this.data && const dangerType = this.data.dangerType;
this.data.dangerType == downloads.DangerType.UNCOMMON_CONTENT) {
return 'cr:error'; if ((loadTimeData.getBoolean('requestsApVerdicts') &&
dangerType == downloads.DangerType.UNCOMMON_CONTENT) ||
dangerType == downloads.DangerType.SENSITIVE_CONTENT_WARNING) {
return 'cr:error';
}
const WARNING_TYPES = [
downloads.DangerType.SENSITIVE_CONTENT_BLOCK,
downloads.DangerType.BLOCKED_TOO_LARGE,
downloads.DangerType.BLOCKED_PASSWORD_PROTECTED,
];
if (WARNING_TYPES.includes(dangerType)) {
return 'cr:warning';
}
} }
if (this.isDangerous_) { if (this.isDangerous_) {
return 'cr:warning'; return 'cr:warning';
...@@ -406,9 +441,17 @@ cr.define('downloads', function() { ...@@ -406,9 +441,17 @@ cr.define('downloads', function() {
return; return;
} }
const OVERRIDDEN_ICON_TYPES = [
downloads.DangerType.SENSITIVE_CONTENT_BLOCK,
downloads.DangerType.BLOCKED_TOO_LARGE,
downloads.DangerType.BLOCKED_PASSWORD_PROTECTED,
];
if (this.isDangerous_) { if (this.isDangerous_) {
this.$.url.removeAttribute('href'); this.$.url.removeAttribute('href');
this.useFileIcon_ = false; this.useFileIcon_ = false;
} else if (OVERRIDDEN_ICON_TYPES.includes(this.data.dangerType)) {
this.useFileIcon_ = false;
} else { } else {
this.$.url.href = assert(this.data.url); this.$.url.href = assert(this.data.url);
const path = this.data.filePath; const path = this.data.filePath;
......
...@@ -45,9 +45,8 @@ using DownloadVector = DownloadManager::DownloadVector; ...@@ -45,9 +45,8 @@ using DownloadVector = DownloadManager::DownloadVector;
namespace { namespace {
// Returns a string constant to be used as the |danger_type| value in // Returns a string constant to be used as the |danger_type| value in
// CreateDownloadData(). Only return strings for DANGEROUS_FILE, // CreateDownloadData(). This can be the empty string, if the danger type is not
// DANGEROUS_URL, DANGEROUS_CONTENT, and UNCOMMON_CONTENT because the // relevant for the UI.
// |danger_type| value is only defined if the value of |state| is |DANGEROUS|.
const char* GetDangerTypeString(download::DownloadDangerType danger_type) { const char* GetDangerTypeString(download::DownloadDangerType danger_type) {
switch (danger_type) { switch (danger_type) {
case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE: case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE:
...@@ -73,7 +72,9 @@ const char* GetDangerTypeString(download::DownloadDangerType danger_type) { ...@@ -73,7 +72,9 @@ const char* GetDangerTypeString(download::DownloadDangerType danger_type) {
case download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_BLOCK: case download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_BLOCK:
return "SENSITIVE_CONTENT_BLOCK"; return "SENSITIVE_CONTENT_BLOCK";
case download::DOWNLOAD_DANGER_TYPE_DEEP_SCANNED_SAFE: case download::DOWNLOAD_DANGER_TYPE_DEEP_SCANNED_SAFE:
return "DEEP_SCANNED_SAFE";
case download::DOWNLOAD_DANGER_TYPE_DEEP_SCANNED_OPENED_DANGEROUS: case download::DOWNLOAD_DANGER_TYPE_DEEP_SCANNED_OPENED_DANGEROUS:
return "DEEP_SCANNED_OPENED_DANGEROUS";
case download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS: case download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS:
case download::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT: case download::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT:
case download::DOWNLOAD_DANGER_TYPE_USER_VALIDATED: case download::DOWNLOAD_DANGER_TYPE_USER_VALIDATED:
...@@ -81,9 +82,9 @@ const char* GetDangerTypeString(download::DownloadDangerType danger_type) { ...@@ -81,9 +82,9 @@ const char* GetDangerTypeString(download::DownloadDangerType danger_type) {
case download::DOWNLOAD_DANGER_TYPE_MAX: case download::DOWNLOAD_DANGER_TYPE_MAX:
break; break;
} }
// Don't return a danger type string if it is NOT_DANGEROUS, // Don't return a danger type string if it is NOT_DANGEROUS,
// MAYBE_DANGEROUS_CONTENT, or USER_VALIDATED. // MAYBE_DANGEROUS_CONTENT, or USER_VALIDATED, or WHITELISTED_BY_POLICY.
NOTREACHED();
return ""; return "";
} }
...@@ -259,7 +260,7 @@ downloads::mojom::DataPtr DownloadsListTracker::CreateDownloadData( ...@@ -259,7 +260,7 @@ downloads::mojom::DataPtr DownloadsListTracker::CreateDownloadData(
file_value->resume = download_item->CanResume(); file_value->resume = download_item->CanResume();
file_value->otr = IsIncognito(*download_item); file_value->otr = IsIncognito(*download_item);
const char* danger_type = ""; const char* danger_type = GetDangerTypeString(download_item->GetDangerType());
base::string16 last_reason_text; base::string16 last_reason_text;
// -2 is invalid, -1 means indeterminate, and 0-100 are in-progress. // -2 is invalid, -1 means indeterminate, and 0-100 are in-progress.
int percent = -2; int percent = -2;
...@@ -271,7 +272,6 @@ downloads::mojom::DataPtr DownloadsListTracker::CreateDownloadData( ...@@ -271,7 +272,6 @@ downloads::mojom::DataPtr DownloadsListTracker::CreateDownloadData(
case download::DownloadItem::IN_PROGRESS: { case download::DownloadItem::IN_PROGRESS: {
if (download_item->IsDangerous()) { if (download_item->IsDangerous()) {
state = "DANGEROUS"; state = "DANGEROUS";
danger_type = GetDangerTypeString(download_item->GetDangerType());
} else if (download_item->IsPaused()) { } else if (download_item->IsPaused()) {
state = "PAUSED"; state = "PAUSED";
} else { } else {
......
...@@ -88,6 +88,18 @@ content::WebUIDataSource* CreateDownloadsUIHTMLSource(Profile* profile) { ...@@ -88,6 +88,18 @@ content::WebUIDataSource* CreateDownloadsUIHTMLSource(Profile* profile) {
{"dangerRestore", IDS_CONFIRM_DOWNLOAD_RESTORE}, {"dangerRestore", IDS_CONFIRM_DOWNLOAD_RESTORE},
{"dangerDiscard", IDS_DISCARD_DOWNLOAD}, {"dangerDiscard", IDS_DISCARD_DOWNLOAD},
// Deep scanning strings.
{"deepScannedSafeDesc", IDS_DEEP_SCANNED_SAFE_DESCRIPTION},
{"deepScannedOpenedDangerousDesc",
IDS_DEEP_SCANNED_OPENED_DANGEROUS_DESCRIPTION},
{"sensitiveContentWarningDesc",
IDS_BLOCK_REASON_SENSITIVE_CONTENT_WARNING},
{"sensitiveContentBlockedDesc",
IDS_SENSITIVE_CONTENT_BLOCKED_DESCRIPTION},
{"blockedTooLargeDesc", IDS_BLOCKED_TOO_LARGE_DESCRIPTION},
{"blockedPasswordProtectedDesc",
IDS_BLOCKED_PASSWORD_PROTECTED_DESCRIPTION},
// Controls. // Controls.
{"controlPause", IDS_DOWNLOAD_LINK_PAUSE}, {"controlPause", IDS_DOWNLOAD_LINK_PAUSE},
{"controlCancel", IDS_DOWNLOAD_LINK_CANCEL}, {"controlCancel", IDS_DOWNLOAD_LINK_CANCEL},
......
...@@ -54,4 +54,31 @@ suite('item tests', function() { ...@@ -54,4 +54,31 @@ suite('item tests', function() {
Polymer.dom.flush(); Polymer.dom.flush();
assertTrue(item.getFileIcon().hidden); assertTrue(item.getFileIcon().hidden);
}); });
test('icon overridden by danger type', async () => {
testIconLoader.setShouldIconsLoad(true);
item.set('data', createDownload({
filePath: 'unique1',
hideDate: false,
dangerType: downloads.DangerType.SENSITIVE_CONTENT_BLOCK,
}));
assertEquals(item.computeIcon_(), 'cr:warning');
assertFalse(item.useFileIcon_);
item.set('data', createDownload({
filePath: 'unique1',
hideDate: false,
dangerType: downloads.DangerType.BLOCKED_TOO_LARGE,
}));
assertEquals(item.computeIcon_(), 'cr:warning');
assertFalse(item.useFileIcon_);
item.set('data', createDownload({
filePath: 'unique1',
hideDate: false,
dangerType: downloads.DangerType.BLOCKED_PASSWORD_PROTECTED,
}));
assertEquals(item.computeIcon_(), 'cr:warning');
assertFalse(item.useFileIcon_);
});
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment