Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(449)

Side by Side Diff: chrome/browser/ui/webui/plugins/plugins_handler.cc

Issue 2630443002: Plugins: Remove chrome://plugins (Closed)
Patch Set: remove test Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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/plugins/plugins_handler.h"
6
7 #include <memory>
8 #include <vector>
9
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/files/file_path.h"
13 #include "base/path_service.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
17 #include "chrome/browser/plugins/plugin_finder.h"
18 #include "chrome/browser/plugins/plugin_metadata.h"
19 #include "chrome/browser/plugins/plugin_prefs.h"
20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/common/chrome_content_client.h"
22 #include "chrome/common/chrome_paths.h"
23 #include "chrome/common/features.h"
24 #include "chrome/common/pepper_flash.h"
25 #include "chrome/common/pref_names.h"
26 #include "chrome/grit/generated_resources.h"
27 #include "components/content_settings/core/browser/host_content_settings_map.h"
28 #include "components/prefs/pref_service.h"
29 #include "components/prefs/scoped_user_pref_update.h"
30 #include "content/public/browser/notification_observer.h"
31 #include "content/public/browser/plugin_service.h"
32 #include "content/public/browser/web_ui.h"
33 #include "content/public/common/content_constants.h"
34 #include "ui/base/l10n/l10n_util.h"
35
36 using content::WebPluginInfo;
37 // Holds grouped plugins. The key is the group identifier and
38 // the value is the list of plugins belonging to the group.
39 using PluginGroups =
40 base::hash_map<std::string, std::vector<const content::WebPluginInfo*>>;
41
42 namespace {
43
44 base::string16 PluginTypeToString(int type) {
45 // The type is stored as an |int|, but doing the switch on the right
46 // enumeration type gives us better build-time error checking (if someone adds
47 // a new type).
48 switch (static_cast<WebPluginInfo::PluginType>(type)) {
49 case WebPluginInfo::PLUGIN_TYPE_PEPPER_IN_PROCESS:
50 return l10n_util::GetStringUTF16(IDS_PLUGINS_PPAPI_IN_PROCESS);
51 case WebPluginInfo::PLUGIN_TYPE_PEPPER_OUT_OF_PROCESS:
52 return l10n_util::GetStringUTF16(IDS_PLUGINS_PPAPI_OUT_OF_PROCESS);
53 case WebPluginInfo::PLUGIN_TYPE_BROWSER_PLUGIN:
54 return l10n_util::GetStringUTF16(IDS_PLUGINS_BROWSER_PLUGIN);
55 }
56 NOTREACHED();
57 return base::string16();
58 }
59
60 base::string16 GetPluginDescription(const WebPluginInfo& plugin) {
61 // If this plugin is Pepper Flash, and the plugin path is the same as the
62 // path for the Pepper Flash System plugin, then mark this plugin
63 // description as the system plugin to help the user disambiguate the
64 // two plugins.
65 base::string16 desc = plugin.desc;
66 if (plugin.is_pepper_plugin() &&
67 plugin.name == base::ASCIIToUTF16(content::kFlashPluginName)) {
68 base::FilePath system_flash_path;
69 PathService::Get(chrome::FILE_PEPPER_FLASH_SYSTEM_PLUGIN,
70 &system_flash_path);
71 if (base::FilePath::CompareEqualIgnoreCase(plugin.path.value(),
72 system_flash_path.value())) {
73 if (chrome::IsSystemFlashScriptDebuggerPresent())
74 desc += base::ASCIIToUTF16(" Debug");
75 else
76 desc += base::ASCIIToUTF16(" System");
77 }
78 }
79 return desc;
80 }
81
82 std::vector<mojom::MimeTypePtr> GeneratePluginMimeTypes(
83 const WebPluginInfo& plugin) {
84 std::vector<mojom::MimeTypePtr> mime_types;
85 mime_types.reserve(plugin.mime_types.size());
86 for (const auto& plugin_mime_type : plugin.mime_types) {
87 mojom::MimeTypePtr mime_type(mojom::MimeType::New());
88 mime_type->description = base::UTF16ToUTF8(plugin_mime_type.description);
89 mime_type->mime_type = plugin_mime_type.mime_type;
90 mime_type->file_extensions = plugin_mime_type.file_extensions;
91 mime_types.push_back(std::move(mime_type));
92 }
93
94 return mime_types;
95 }
96
97 } // namespace
98
99 PluginsPageHandler::PluginsPageHandler(
100 content::WebUI* web_ui,
101 mojo::InterfaceRequest<mojom::PluginsPageHandler> request)
102 : web_ui_(web_ui),
103 binding_(this, std::move(request)),
104 weak_ptr_factory_(this) {
105 Profile* profile = Profile::FromWebUI(web_ui_);
106 PrefService* prefs = profile->GetPrefs();
107 show_details_.Init(prefs::kPluginsShowDetails, prefs);
108
109 registrar_.Add(this, chrome::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED,
110 content::Source<Profile>(profile));
111 }
112
113 PluginsPageHandler::~PluginsPageHandler() {}
114
115 void PluginsPageHandler::GetShowDetails(
116 const GetShowDetailsCallback& callback) {
117 callback.Run(show_details_.GetValue());
118 }
119
120 void PluginsPageHandler::SaveShowDetailsToPrefs(bool details_mode) {
121 show_details_.SetValue(details_mode);
122 }
123
124 void PluginsPageHandler::SetPluginAlwaysAllowed(const std::string& plugin,
125 bool allowed) {
126 Profile* profile = Profile::FromWebUI(web_ui_);
127 HostContentSettingsMapFactory::GetForProfile(profile)
128 ->SetContentSettingCustomScope(
129 ContentSettingsPattern::Wildcard(),
130 ContentSettingsPattern::Wildcard(), CONTENT_SETTINGS_TYPE_PLUGINS,
131 plugin, allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_DEFAULT);
132
133 // Keep track of the whitelist separately, so that we can distinguish plugins
134 // whitelisted by the user from automatically whitelisted ones.
135 DictionaryPrefUpdate update(profile->GetPrefs(),
136 prefs::kContentSettingsPluginWhitelist);
137 update->SetBoolean(plugin, allowed);
138 }
139
140 void PluginsPageHandler::GetPluginsData(
141 const GetPluginsDataCallback& callback) {
142 if (weak_ptr_factory_.HasWeakPtrs())
143 return;
144
145 content::PluginService::GetInstance()->GetPlugins(
146 base::Bind(&PluginsPageHandler::RespondWithPluginsData,
147 weak_ptr_factory_.GetWeakPtr(), callback));
148 }
149
150 void PluginsPageHandler::SetClientPage(mojom::PluginsPagePtr page) {
151 page_ = std::move(page);
152 }
153
154 void PluginsPageHandler::Observe(int type,
155 const content::NotificationSource& source,
156 const content::NotificationDetails& details) {
157 DCHECK_EQ(chrome::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED, type);
158
159 if (weak_ptr_factory_.HasWeakPtrs())
160 return;
161
162 content::PluginService::GetInstance()->GetPlugins(
163 base::Bind(&PluginsPageHandler::NotifyWithPluginsData,
164 weak_ptr_factory_.GetWeakPtr()));
165 }
166
167 void PluginsPageHandler::RespondWithPluginsData(
168 const GetPluginsDataCallback& callback,
169 const std::vector<WebPluginInfo>& plugins) {
170 callback.Run(GeneratePluginsData(plugins));
171 }
172
173 void PluginsPageHandler::NotifyWithPluginsData(
174 const std::vector<WebPluginInfo>& plugins) {
175 if (page_)
176 page_->OnPluginsUpdated(GeneratePluginsData(plugins));
177 }
178
179 std::vector<mojom::PluginDataPtr> PluginsPageHandler::GeneratePluginsData(
180 const std::vector<WebPluginInfo>& plugins) {
181 Profile* profile = Profile::FromWebUI(web_ui_);
182 PluginPrefs* plugin_prefs = PluginPrefs::GetForProfile(profile).get();
183
184 PluginFinder* plugin_finder = PluginFinder::GetInstance();
185 // Group plugins by identifier. This is done to be able to display
186 // the plugins in UI in a grouped fashion.
187 PluginGroups groups;
188 for (size_t i = 0; i < plugins.size(); ++i) {
189 std::unique_ptr<PluginMetadata> plugin(
190 plugin_finder->GetPluginMetadata(plugins[i]));
191 groups[plugin->identifier()].push_back(&plugins[i]);
192 }
193
194 std::vector<mojom::PluginDataPtr> plugins_data;
195 plugins_data.reserve(groups.size());
196 for (PluginGroups::const_iterator it = groups.begin(); it != groups.end();
197 ++it) {
198 mojom::PluginDataPtr plugin_data(mojom::PluginData::New());
199 const std::vector<const WebPluginInfo*>& group_plugins = it->second;
200
201 std::unique_ptr<PluginMetadata> plugin_metadata(
202 plugin_finder->GetPluginMetadata(*group_plugins[0]));
203 std::string group_identifier = plugin_metadata->identifier();
204 plugin_data->id = group_identifier;
205
206 const WebPluginInfo* active_plugin = nullptr;
207 bool group_enabled = false;
208
209 std::vector<mojom::PluginFilePtr> plugin_files;
210 plugin_files.reserve(group_plugins.size());
211 for (const auto* group_plugin : group_plugins) {
212 bool plugin_enabled = plugin_prefs->IsPluginEnabled(*group_plugin);
213
214 plugin_files.push_back(GeneratePluginFile(
215 *group_plugin, plugin_metadata->name(), plugin_enabled));
216
217 // Update |active_plugin| and |group_enabled|.
218 if (!active_plugin || (plugin_enabled && !group_enabled))
219 active_plugin = group_plugin;
220 group_enabled = plugin_enabled || group_enabled;
221 }
222
223 plugin_data->enabled_mode =
224 GetPluginGroupEnabledMode(plugin_files, group_enabled);
225
226 plugin_data->always_allowed = false;
227 plugin_data->trusted = false;
228 plugin_data->policy_click_to_play = GetClickToPlayPolicyEnabled();
229
230 if (group_enabled) {
231 if (plugin_metadata->GetSecurityStatus(*active_plugin) ==
232 PluginMetadata::SECURITY_STATUS_FULLY_TRUSTED) {
233 plugin_data->trusted = true;
234 plugin_data->always_allowed = true;
235 } else if (!GetClickToPlayPolicyEnabled()) {
236 const base::DictionaryValue* whitelist =
237 profile->GetPrefs()->GetDictionary(
238 prefs::kContentSettingsPluginWhitelist);
239 whitelist->GetBoolean(group_identifier, &plugin_data->always_allowed);
240 }
241 }
242
243 plugin_data->critical = false;
244 plugin_data->update_url = "";
245 #if BUILDFLAG(ENABLE_PLUGIN_INSTALLATION)
246 bool out_of_date = plugin_metadata->GetSecurityStatus(*active_plugin) ==
247 PluginMetadata::SECURITY_STATUS_OUT_OF_DATE;
248 plugin_data->critical = out_of_date;
249 plugin_data->update_url = plugin_metadata->plugin_url().spec();
250 #endif
251
252 plugin_data->description = base::UTF16ToUTF8(active_plugin->desc);
253 plugin_data->name = base::UTF16ToUTF8(plugin_metadata->name());
254 plugin_data->plugin_files = std::move(plugin_files);
255 plugin_data->version = base::UTF16ToUTF8(active_plugin->version);
256 plugins_data.push_back(std::move(plugin_data));
257 }
258
259 return plugins_data;
260 }
261
262 bool PluginsPageHandler::GetClickToPlayPolicyEnabled() const {
263 Profile* profile = Profile::FromWebUI(web_ui_);
264 HostContentSettingsMap* map =
265 HostContentSettingsMapFactory::GetForProfile(profile);
266 std::string provider_id;
267 ContentSetting setting = map->GetDefaultContentSetting(
268 CONTENT_SETTINGS_TYPE_PLUGINS, &provider_id);
269 return (setting == CONTENT_SETTING_ASK && provider_id == "policy");
270 }
271
272 mojom::PluginFilePtr PluginsPageHandler::GeneratePluginFile(
273 const WebPluginInfo& plugin,
274 const base::string16& group_name,
275 bool plugin_enabled) const {
276 mojom::PluginFilePtr plugin_file(mojom::PluginFile::New());
277 plugin_file->description = base::UTF16ToUTF8(GetPluginDescription(plugin));
278 plugin_file->enabled_mode =
279 GetPluginEnabledMode(plugin.name, group_name, plugin_enabled);
280 plugin_file->name = base::UTF16ToUTF8(plugin.name);
281 plugin_file->path = plugin.path.AsUTF8Unsafe();
282 plugin_file->type = base::UTF16ToUTF8(PluginTypeToString(plugin.type));
283 plugin_file->version = base::UTF16ToUTF8(plugin.version);
284 plugin_file->mime_types = GeneratePluginMimeTypes(plugin);
285
286 return plugin_file;
287 }
288
289 std::string PluginsPageHandler::GetPluginEnabledMode(
290 const base::string16& plugin_name,
291 const base::string16& group_name,
292 bool plugin_enabled) const {
293 Profile* profile = Profile::FromWebUI(web_ui_);
294 PluginPrefs* plugin_prefs = PluginPrefs::GetForProfile(profile).get();
295 PluginPrefs::PolicyStatus plugin_status =
296 plugin_prefs->PolicyStatusForPlugin(plugin_name);
297 PluginPrefs::PolicyStatus group_status =
298 plugin_prefs->PolicyStatusForPlugin(group_name);
299
300 if (plugin_status == PluginPrefs::POLICY_ENABLED ||
301 group_status == PluginPrefs::POLICY_ENABLED) {
302 return "enabledByPolicy";
303 }
304 if (plugin_status == PluginPrefs::POLICY_DISABLED ||
305 group_status == PluginPrefs::POLICY_DISABLED) {
306 return "disabledByPolicy";
307 }
308 return plugin_enabled ? "enabledByUser" : "disabledByUser";
309 }
310
311 std::string PluginsPageHandler::GetPluginGroupEnabledMode(
312 const std::vector<mojom::PluginFilePtr>& plugin_files,
313 bool group_enabled) const {
314 bool plugins_enabled_by_policy = true;
315 bool plugins_disabled_by_policy = true;
316 bool plugins_managed_by_policy = true;
317
318 for (size_t i = 0; i < plugin_files.size(); i++) {
319 std::string plugin_enabled_mode = plugin_files[i]->enabled_mode;
320
321 plugins_enabled_by_policy =
322 plugins_enabled_by_policy && plugin_enabled_mode == "enabledByPolicy";
323 plugins_disabled_by_policy =
324 plugins_disabled_by_policy && plugin_enabled_mode == "disabledByPolicy";
325 plugins_managed_by_policy = plugins_managed_by_policy &&
326 (plugin_enabled_mode == "enabledByPolicy" ||
327 plugin_enabled_mode == "disabledByPolicy");
328 }
329
330 if (plugins_enabled_by_policy)
331 return "enabledByPolicy";
332 if (plugins_disabled_by_policy)
333 return "disabledByPolicy";
334 if (plugins_managed_by_policy)
335 return "managedByPolicy";
336 return group_enabled ? "enabledByUser" : "disabledByUser";
337 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/webui/plugins/plugins_handler.h ('k') | chrome/browser/ui/webui/plugins/plugins_ui.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698