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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/webui/downloads/downloads_ui.h"
6
7 #include <memory>
8 #include <utility>
9
10 #include "base/bind.h"
11 #include "base/memory/ref_counted_memory.h"
12 #include "base/memory/singleton.h"
13 #include "base/strings/string_piece.h"
14 #include "base/threading/thread.h"
15 #include "base/values.h"
16 #include "chrome/browser/defaults.h"
17 #include "chrome/browser/enterprise/connectors/connectors_manager.h"
18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/safe_browsing/advanced_protection_status_manager.h"
20 #include "chrome/browser/safe_browsing/advanced_protection_status_manager_factory.h"
21 #include "chrome/browser/ui/webui/downloads/downloads.mojom.h"
22 #include "chrome/browser/ui/webui/downloads/downloads_dom_handler.h"
23 #include "chrome/browser/ui/webui/managed_ui_handler.h"
24 #include "chrome/browser/ui/webui/metrics_handler.h"
25 #include "chrome/browser/ui/webui/theme_source.h"
26 #include "chrome/browser/ui/webui/webui_util.h"
27 #include "chrome/common/buildflags.h"
28 #include "chrome/common/chrome_switches.h"
29 #include "chrome/common/pref_names.h"
30 #include "chrome/common/url_constants.h"
31 #include "chrome/grit/chromium_strings.h"
32 #include "chrome/grit/downloads_resources.h"
33 #include "chrome/grit/downloads_resources_map.h"
34 #include "chrome/grit/generated_resources.h"
35 #include "chrome/grit/theme_resources.h"
36 #include "components/prefs/pref_service.h"
37 #include "content/public/browser/download_manager.h"
38 #include "content/public/browser/url_data_source.h"
39 #include "content/public/browser/web_contents.h"
40 #include "content/public/browser/web_ui.h"
41 #include "content/public/browser/web_ui_data_source.h"
42 #include "mojo/public/cpp/bindings/pending_receiver.h"
43 #include "mojo/public/cpp/bindings/pending_remote.h"
44 #include "mojo/public/cpp/bindings/receiver.h"
45 #include "ui/base/accelerators/accelerator.h"
46 #include "ui/base/l10n/l10n_util.h"
47 #include "ui/base/resource/resource_bundle.h"
48 #include "ui/base/webui/web_ui_util.h"
49
50 using content::BrowserContext;
51 using content::DownloadManager;
52 using content::WebContents;
53
54 namespace {
55
CreateDownloadsUIHTMLSource(Profile * profile)56 content::WebUIDataSource* CreateDownloadsUIHTMLSource(Profile* profile) {
57 content::WebUIDataSource* source =
58 content::WebUIDataSource::Create(chrome::kChromeUIDownloadsHost);
59 webui::SetupWebUIDataSource(
60 source, base::make_span(kDownloadsResources, kDownloadsResourcesSize), "",
61 IDR_DOWNLOADS_DOWNLOADS_HTML);
62
63 bool requests_ap_verdicts =
64 safe_browsing::AdvancedProtectionStatusManagerFactory::GetForProfile(
65 profile)
66 ->IsUnderAdvancedProtection();
67 source->AddBoolean("requestsApVerdicts", requests_ap_verdicts);
68
69 static constexpr webui::LocalizedString kStrings[] = {
70 {"title", IDS_DOWNLOAD_TITLE},
71 {"searchResultsPlural", IDS_SEARCH_RESULTS_PLURAL},
72 {"searchResultsSingular", IDS_SEARCH_RESULTS_SINGULAR},
73 {"downloads", IDS_DOWNLOAD_TITLE},
74 {"actionMenuDescription", IDS_DOWNLOAD_ACTION_MENU_DESCRIPTION},
75 {"clearAll", IDS_DOWNLOAD_LINK_CLEAR_ALL},
76 {"clearSearch", IDS_CLEAR_SEARCH},
77 {"openDownloadsFolder", IDS_DOWNLOAD_LINK_OPEN_DOWNLOADS_FOLDER},
78 {"moreActions", IDS_DOWNLOAD_MORE_ACTIONS},
79 {"search", IDS_DOWNLOAD_SEARCH},
80
81 // No results message that shows instead of the downloads list.
82 {"noDownloads", IDS_DOWNLOAD_NO_DOWNLOADS},
83 {"noSearchResults", IDS_SEARCH_NO_RESULTS},
84
85 // Status.
86 {"statusCancelled", IDS_DOWNLOAD_TAB_CANCELLED},
87 {"statusRemoved", IDS_DOWNLOAD_FILE_REMOVED},
88
89 // Dangerous file.
90 {"dangerFileDesc", IDS_BLOCK_REASON_GENERIC_DOWNLOAD},
91 {"dangerSave", IDS_CONFIRM_DOWNLOAD},
92 {"dangerRestore", IDS_CONFIRM_DOWNLOAD_RESTORE},
93 {"dangerDiscard", IDS_DISCARD_DOWNLOAD},
94
95 // Deep scanning strings.
96 {"deepScannedSafeDesc", IDS_DEEP_SCANNED_SAFE_DESCRIPTION},
97 {"deepScannedOpenedDangerousDesc",
98 IDS_DEEP_SCANNED_OPENED_DANGEROUS_DESCRIPTION},
99 {"sensitiveContentWarningDesc",
100 IDS_BLOCK_REASON_SENSITIVE_CONTENT_WARNING},
101 {"sensitiveContentBlockedDesc",
102 IDS_SENSITIVE_CONTENT_BLOCKED_DESCRIPTION},
103 {"blockedTooLargeDesc", IDS_BLOCKED_TOO_LARGE_DESCRIPTION},
104 {"blockedPasswordProtectedDesc",
105 IDS_BLOCKED_PASSWORD_PROTECTED_DESCRIPTION},
106
107 // Controls.
108 {"controlPause", IDS_DOWNLOAD_LINK_PAUSE},
109 {"controlCancel", IDS_DOWNLOAD_LINK_CANCEL},
110 {"controlResume", IDS_DOWNLOAD_LINK_RESUME},
111 {"controlRemoveFromList", IDS_DOWNLOAD_LINK_REMOVE},
112 {"controlRemoveFromListAriaLabel", IDS_DOWNLOAD_LINK_REMOVE_ARIA_LABEL},
113 {"controlRetry", IDS_DOWNLOAD_LINK_RETRY},
114 {"controlledByUrl", IDS_DOWNLOAD_BY_EXTENSION_URL},
115 {"controlOpenNow", IDS_OPEN_DOWNLOAD_NOW},
116 {"toastClearedAll", IDS_DOWNLOAD_TOAST_CLEARED_ALL},
117 {"toastRemovedFromList", IDS_DOWNLOAD_TOAST_REMOVED_FROM_LIST},
118 {"undo", IDS_DOWNLOAD_UNDO},
119 };
120 AddLocalizedStringsBulk(source, kStrings);
121
122 source->AddLocalizedString("dangerDownloadDesc",
123 IDS_BLOCK_REASON_DANGEROUS_DOWNLOAD);
124 source->AddLocalizedString(
125 "dangerUncommonDesc",
126 requests_ap_verdicts
127 ? IDS_BLOCK_REASON_UNCOMMON_DOWNLOAD_IN_ADVANCED_PROTECTION
128 : IDS_BLOCK_REASON_UNCOMMON_DOWNLOAD);
129 source->AddLocalizedString("dangerSettingsDesc",
130 IDS_BLOCK_REASON_UNWANTED_DOWNLOAD);
131 source->AddLocalizedString("mixedContentDownloadDesc",
132 IDS_BLOCK_REASON_MIXED_CONTENT);
133 source->AddLocalizedString("asyncScanningDownloadDesc",
134 IDS_BLOCK_REASON_DEEP_SCANNING);
135 if (browser_defaults::kDownloadPageHasShowInFolder)
136 source->AddLocalizedString("controlShowInFolder", IDS_DOWNLOAD_LINK_SHOW);
137
138 // Build an Accelerator to describe undo shortcut
139 // NOTE: the undo shortcut is also defined in downloads/downloads.html
140 // TODO(crbug/893033): de-duplicate shortcut by moving all shortcut
141 // definitions from JS to C++.
142 ui::Accelerator undo_accelerator(ui::VKEY_Z, ui::EF_PLATFORM_ACCELERATOR);
143 source->AddString("undoDescription", l10n_util::GetStringFUTF16(
144 IDS_UNDO_DESCRIPTION,
145 undo_accelerator.GetShortcutText()));
146
147 PrefService* prefs = profile->GetPrefs();
148 source->AddBoolean("allowDeletingHistory",
149 prefs->GetBoolean(prefs::kAllowDeletingBrowserHistory) &&
150 !profile->IsSupervised());
151
152 source->AddLocalizedString("inIncognito", IDS_DOWNLOAD_IN_INCOGNITO);
153
154 source->AddBoolean(
155 "allowOpenNow",
156 !enterprise_connectors::ConnectorsManager::GetInstance()
157 ->DelayUntilVerdict(
158 enterprise_connectors::AnalysisConnector::FILE_DOWNLOADED));
159
160 return source;
161 }
162
163 } // namespace
164
165 ///////////////////////////////////////////////////////////////////////////////
166 //
167 // DownloadsUI
168 //
169 ///////////////////////////////////////////////////////////////////////////////
170
DownloadsUI(content::WebUI * web_ui)171 DownloadsUI::DownloadsUI(content::WebUI* web_ui)
172 : ui::MojoWebUIController(web_ui, true) {
173 Profile* profile = Profile::FromWebUI(web_ui);
174 web_ui->AddMessageHandler(std::make_unique<MetricsHandler>());
175
176 // Set up the chrome://downloads/ source.
177 content::WebUIDataSource* source = CreateDownloadsUIHTMLSource(profile);
178 ManagedUIHandler::Initialize(web_ui, source);
179 content::WebUIDataSource::Add(profile, source);
180 content::URLDataSource::Add(profile, std::make_unique<ThemeSource>(profile));
181 }
182
183 WEB_UI_CONTROLLER_TYPE_IMPL(DownloadsUI)
184
185 DownloadsUI::~DownloadsUI() = default;
186
187 // static
GetFaviconResourceBytes(ui::ScaleFactor scale_factor)188 base::RefCountedMemory* DownloadsUI::GetFaviconResourceBytes(
189 ui::ScaleFactor scale_factor) {
190 return ui::ResourceBundle::GetSharedInstance().LoadDataResourceBytesForScale(
191 IDR_DOWNLOADS_FAVICON, scale_factor);
192 }
193
BindInterface(mojo::PendingReceiver<downloads::mojom::PageHandlerFactory> receiver)194 void DownloadsUI::BindInterface(
195 mojo::PendingReceiver<downloads::mojom::PageHandlerFactory> receiver) {
196 page_factory_receiver_.reset();
197
198 page_factory_receiver_.Bind(std::move(receiver));
199 }
200
CreatePageHandler(mojo::PendingRemote<downloads::mojom::Page> page,mojo::PendingReceiver<downloads::mojom::PageHandler> receiver)201 void DownloadsUI::CreatePageHandler(
202 mojo::PendingRemote<downloads::mojom::Page> page,
203 mojo::PendingReceiver<downloads::mojom::PageHandler> receiver) {
204 DCHECK(page);
205 Profile* profile = Profile::FromWebUI(web_ui());
206 DownloadManager* dlm = BrowserContext::GetDownloadManager(profile);
207
208 page_handler_ = std::make_unique<DownloadsDOMHandler>(
209 std::move(receiver), std::move(page), dlm, web_ui());
210 }
211