blob: 36fb2c8fad052f677544be7b7bd01d274f328fac [file] [log] [blame]
[email protected]3b48dbc2012-01-06 16:34:171// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]e67385f2011-12-21 06:00:565#include "content/browser/plugin_service_impl.h"
initial.commit09911bf2008-07-26 23:55:296
avib7348942015-12-25 20:57:107#include <stddef.h>
8
Lukasz Anforowicze4986b22018-08-27 21:32:259#include <string>
fdoray9292e0722017-05-13 03:47:5110#include <utility>
11
[email protected]d33e7cc2011-09-23 01:43:5612#include "base/bind.h"
[email protected]d48f1e0c2009-02-12 20:57:5413#include "base/command_line.h"
[email protected]7b3ee8b2011-04-01 18:48:1914#include "base/compiler_specific.h"
[email protected]57999812013-02-24 05:40:5215#include "base/files/file_path.h"
skyostil95082a62015-06-05 19:53:0716#include "base/location.h"
fdoray5e1706c32016-09-08 12:57:0917#include "base/logging.h"
asvitkine30330812016-08-30 04:01:0818#include "base/metrics/histogram_macros.h"
[email protected]348fbaac2013-06-11 06:31:5119#include "base/strings/string_util.h"
[email protected]74ebfb12013-06-07 20:48:0020#include "base/strings/utf_string_conversions.h"
[email protected]7f070d42011-03-09 20:25:3221#include "base/synchronization/waitable_event.h"
Gabriel Charette44db1422018-08-06 11:19:3322#include "base/task/post_task.h"
fdoray9292e0722017-05-13 03:47:5123#include "base/task_runner_util.h"
[email protected]34b99632011-01-01 01:01:0624#include "base/threading/thread.h"
avib7348942015-12-25 20:57:1025#include "build/build_config.h"
[email protected]a01efd22011-03-01 00:38:3226#include "content/browser/ppapi_plugin_process_host.h"
[email protected]f3b1a082011-11-18 00:34:3027#include "content/browser/renderer_host/render_process_host_impl.h"
[email protected]b3c41c0b2012-03-06 15:48:3228#include "content/browser/renderer_host/render_view_host_impl.h"
Steven Holte38041342018-06-22 22:00:5729#include "content/browser/web_contents/web_contents_impl.h"
wfh1a90e032015-04-14 17:10:1730#include "content/common/content_switches_internal.h"
[email protected]dac6a5a2013-07-25 05:06:4831#include "content/common/pepper_plugin_list.h"
[email protected]29e2fb42013-07-19 01:13:4732#include "content/common/plugin_list.h"
[email protected]38b592902011-04-16 02:08:4233#include "content/common/view_messages.h"
Eric Seckler8652dcd52018-09-20 10:42:2834#include "content/public/browser/browser_task_traits.h"
[email protected]c38831a12011-10-28 12:44:4935#include "content/public/browser/browser_thread.h"
[email protected]87f3c082011-10-19 18:07:4436#include "content/public/browser/content_browser_client.h"
[email protected]31f376c2012-03-13 16:43:0937#include "content/public/browser/plugin_service_filter.h"
Raymes Khoury978652c2017-11-27 06:28:3738#include "content/public/browser/render_frame_host.h"
[email protected]ce967862012-02-09 22:47:0539#include "content/public/browser/resource_context.h"
Raymes Khoury978652c2017-11-27 06:28:3740#include "content/public/browser/web_contents.h"
[email protected]73270292013-08-09 03:48:0741#include "content/public/common/content_constants.h"
[email protected]c08950d22011-10-13 22:20:2942#include "content/public/common/content_switches.h"
[email protected]bd5d6cf2011-12-01 00:39:1243#include "content/public/common/process_type.h"
[email protected]d7bd3e52013-07-21 04:29:2044#include "content/public/common/webplugininfo.h"
Lukasz Anforowicze4986b22018-08-27 21:32:2545#include "ppapi/shared_impl/ppapi_permissions.h"
Raymes Khoury978652c2017-11-27 06:28:3746#include "services/metrics/public/cpp/ukm_builders.h"
[email protected]191eb3f72010-12-21 06:27:5047
[email protected]130757672012-10-24 00:26:1948namespace content {
[email protected]d33e7cc2011-09-23 01:43:5649namespace {
50
[email protected]fd8d8d6c2013-02-28 02:48:3351// This enum is used to collect Flash usage data.
52enum FlashUsage {
[email protected]fd8d8d6c2013-02-28 02:48:3353 // Number of browser processes that have started at least one PPAPI Flash
54 // process during their lifetime.
pimane8c57ea2016-04-06 01:19:3655 START_PPAPI_FLASH_AT_LEAST_ONCE = 1,
[email protected]fd8d8d6c2013-02-28 02:48:3356 // Total number of browser processes.
57 TOTAL_BROWSER_PROCESSES,
58 FLASH_USAGE_ENUM_COUNT
59};
60
[email protected]49125952011-09-27 18:05:1561// Callback set on the PluginList to assert that plugin loading happens on the
62// correct thread.
fdoray5e1706c32016-09-08 12:57:0963void WillLoadPluginsCallback(base::SequenceChecker* sequence_checker) {
64 DCHECK(sequence_checker->CalledOnValidSequence());
[email protected]a79912252012-05-16 11:52:1965}
[email protected]d33e7cc2011-09-23 01:43:5666
Steven Holteba045f12017-12-14 21:30:1967} // namespace
68
69// static
70void PluginServiceImpl::RecordBrokerUsage(int render_process_id,
71 int render_frame_id) {
Raymes Khoury978652c2017-11-27 06:28:3772 WebContents* web_contents = WebContents::FromRenderFrameHost(
73 RenderFrameHost::FromID(render_process_id, render_frame_id));
74 if (web_contents) {
Steven Holte38041342018-06-22 22:00:5775 ukm::SourceId source_id = static_cast<WebContentsImpl*>(web_contents)
76 ->GetUkmSourceIdForLastCommittedSource();
77 ukm::builders::Pepper_Broker(source_id).Record(ukm::UkmRecorder::Get());
Raymes Khoury978652c2017-11-27 06:28:3778 }
79}
80
[email protected]3a5180ae2011-12-21 02:39:3881// static
82PluginService* PluginService::GetInstance() {
[email protected]e67385f2011-12-21 06:00:5683 return PluginServiceImpl::GetInstance();
[email protected]3a5180ae2011-12-21 02:39:3884}
85
86void PluginService::PurgePluginListCache(BrowserContext* browser_context,
87 bool reload_pages) {
88 for (RenderProcessHost::iterator it = RenderProcessHost::AllHostsIterator();
89 !it.IsAtEnd(); it.Advance()) {
90 RenderProcessHost* host = it.GetCurrentValue();
91 if (!browser_context || host->GetBrowserContext() == browser_context)
rockota2db0da2016-10-18 17:39:1192 host->GetRendererInterface()->PurgePluginListCache(reload_pages);
[email protected]3a5180ae2011-12-21 02:39:3893 }
94}
95
initial.commit09911bf2008-07-26 23:55:2996// static
[email protected]e67385f2011-12-21 06:00:5697PluginServiceImpl* PluginServiceImpl::GetInstance() {
olli.raula36aa8be2015-09-10 11:14:2298 return base::Singleton<PluginServiceImpl>::get();
initial.commit09911bf2008-07-26 23:55:2999}
100
Ivan Kotenkov2c0d2bb32017-11-01 15:41:28101PluginServiceImpl::PluginServiceImpl() : filter_(nullptr) {
fdoray5e1706c32016-09-08 12:57:09102 plugin_list_sequence_checker_.DetachFromSequence();
103
[email protected]fd8d8d6c2013-02-28 02:48:33104 // Collect the total number of browser processes (which create
105 // PluginServiceImpl objects, to be precise). The number is used to normalize
106 // the number of processes which start at least one NPAPI/PPAPI Flash process.
107 static bool counted = false;
108 if (!counted) {
109 counted = true;
110 UMA_HISTOGRAM_ENUMERATION("Plugin.FlashUsage", TOTAL_BROWSER_PROCESSES,
111 FLASH_USAGE_ENUM_COUNT);
112 }
[email protected]ee066172011-11-10 23:20:05113}
114
[email protected]e67385f2011-12-21 06:00:56115PluginServiceImpl::~PluginServiceImpl() {
[email protected]ee066172011-11-10 23:20:05116}
117
[email protected]e67385f2011-12-21 06:00:56118void PluginServiceImpl::Init() {
fdoraycc22a38d2017-04-27 06:56:39119 plugin_list_task_runner_ = base::CreateSequencedTaskRunnerWithTraits(
fdoray27b0b2a2017-05-04 19:52:08120 {base::MayBlock(), base::TaskPriority::USER_VISIBLE,
121 base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN});
[email protected]29e2fb42013-07-19 01:13:47122 PluginList::Singleton()->set_will_load_plugins_callback(
fdoray5e1706c32016-09-08 12:57:09123 base::Bind(&WillLoadPluginsCallback, &plugin_list_sequence_checker_));
[email protected]49125952011-09-27 18:05:15124
[email protected]4e0616e2010-05-28 14:55:53125 RegisterPepperPlugins();
initial.commit09911bf2008-07-26 23:55:29126}
127
[email protected]e67385f2011-12-21 06:00:56128PpapiPluginProcessHost* PluginServiceImpl::FindPpapiPluginProcess(
[email protected]2dec8ec2013-02-07 19:20:34129 const base::FilePath& plugin_path,
Tom Sepez8db30ad2018-03-01 21:38:54130 const base::FilePath& profile_data_directory,
131 const base::Optional<url::Origin>& origin_lock) {
[email protected]4967f792012-01-20 22:14:40132 for (PpapiPluginProcessHostIterator iter; !iter.Done(); ++iter) {
[email protected]dd9a0952012-05-31 20:11:31133 if (iter->plugin_path() == plugin_path &&
Tom Sepez8db30ad2018-03-01 21:38:54134 iter->profile_data_directory() == profile_data_directory &&
135 (!iter->origin_lock() || iter->origin_lock() == origin_lock)) {
[email protected]4967f792012-01-20 22:14:40136 return *iter;
[email protected]dd9a0952012-05-31 20:11:31137 }
[email protected]a08ebea2011-02-13 17:50:20138 }
Ivan Kotenkov2c0d2bb32017-11-01 15:41:28139 return nullptr;
[email protected]a08ebea2011-02-13 17:50:20140}
141
Tom Sepez19fecb3d2018-03-02 18:40:21142int PluginServiceImpl::CountPpapiPluginProcessesForProfile(
143 const base::FilePath& plugin_path,
144 const base::FilePath& profile_data_directory) {
145 int count = 0;
146 for (PpapiPluginProcessHostIterator iter; !iter.Done(); ++iter) {
147 if (iter->plugin_path() == plugin_path &&
148 iter->profile_data_directory() == profile_data_directory) {
149 ++count;
150 }
151 }
152 return count;
153}
154
[email protected]e67385f2011-12-21 06:00:56155PpapiPluginProcessHost* PluginServiceImpl::FindPpapiBrokerProcess(
[email protected]2dec8ec2013-02-07 19:20:34156 const base::FilePath& broker_path) {
[email protected]4967f792012-01-20 22:14:40157 for (PpapiBrokerProcessHostIterator iter; !iter.Done(); ++iter) {
158 if (iter->plugin_path() == broker_path)
159 return *iter;
[email protected]eb415bf0e2011-04-14 02:45:42160 }
161
Ivan Kotenkov2c0d2bb32017-11-01 15:41:28162 return nullptr;
[email protected]eb415bf0e2011-04-14 02:45:42163}
164
[email protected]e67385f2011-12-21 06:00:56165PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiPluginProcess(
[email protected]6be31d202013-02-01 18:20:54166 int render_process_id,
[email protected]2dec8ec2013-02-07 19:20:34167 const base::FilePath& plugin_path,
Tom Sepez8db30ad2018-03-01 21:38:54168 const base::FilePath& profile_data_directory,
169 const base::Optional<url::Origin>& origin_lock) {
mostynb4c27d042015-03-18 21:47:47170 DCHECK_CURRENTLY_ON(BrowserThread::IO);
[email protected]a08ebea2011-02-13 17:50:20171
[email protected]132bca82013-12-10 09:14:47172 if (filter_ && !filter_->CanLoadPlugin(render_process_id, plugin_path)) {
173 VLOG(1) << "Unable to load ppapi plugin: " << plugin_path.MaybeAsASCII();
Ivan Kotenkov2c0d2bb32017-11-01 15:41:28174 return nullptr;
[email protected]132bca82013-12-10 09:14:47175 }
[email protected]6be31d202013-02-01 18:20:54176
[email protected]eb415bf0e2011-04-14 02:45:42177 // Validate that the plugin is actually registered.
Lei Zhangfa5e24d2018-08-29 01:34:09178 const PepperPluginInfo* info = GetRegisteredPpapiPluginInfo(plugin_path);
[email protected]132bca82013-12-10 09:14:47179 if (!info) {
180 VLOG(1) << "Unable to find ppapi plugin registration for: "
181 << plugin_path.MaybeAsASCII();
Ivan Kotenkov2c0d2bb32017-11-01 15:41:28182 return nullptr;
[email protected]132bca82013-12-10 09:14:47183 }
[email protected]a08ebea2011-02-13 17:50:20184
Lukasz Anforowicze4986b22018-08-27 21:32:25185 // Flash has its own flavour of CORS, so CORB needs to allow all responses
186 // and rely on Flash to enforce same-origin policy. See also
187 // https://crbug.com/874515 and https://crbug.com/816318#c5.
188 //
189 // Note that ppapi::PERMISSION_FLASH is present not only in the Flash plugin.
190 // This permission is also present in plugins added from the cmdline and so
191 // will be also present for "PPAPI Tests" plugin used for
192 // OutOfProcessPPAPITest.URLLoaderTrusted and related tests.
193 //
194 // TODO(lukasza, laforge): https://crbug.com/702995: Remove the code below
195 // once Flash support is removed from Chromium (probably around 2020 - see
196 // https://www.chromium.org/flash-roadmap).
197 if (info->permissions & ppapi::PERMISSION_FLASH)
198 RenderProcessHostImpl::AddCorbExceptionForPlugin(render_process_id);
199
Tom Sepez8db30ad2018-03-01 21:38:54200 PpapiPluginProcessHost* plugin_host =
201 FindPpapiPluginProcess(plugin_path, profile_data_directory, origin_lock);
202 if (plugin_host)
203 return plugin_host;
204
[email protected]fd8d8d6c2013-02-28 02:48:33205 // Record when PPAPI Flash process is started for the first time.
206 static bool counted = false;
207 if (!counted && info->name == kFlashPluginName) {
208 counted = true;
209 UMA_HISTOGRAM_ENUMERATION("Plugin.FlashUsage",
210 START_PPAPI_FLASH_AT_LEAST_ONCE,
211 FLASH_USAGE_ENUM_COUNT);
212 }
213
Tom Sepez19fecb3d2018-03-02 18:40:21214 // Avoid fork bomb.
215 if (origin_lock.has_value() && CountPpapiPluginProcessesForProfile(
216 plugin_path, profile_data_directory) >=
217 max_ppapi_processes_per_profile_) {
218 return nullptr;
219 }
220
[email protected]a08ebea2011-02-13 17:50:20221 // This plugin isn't loaded by any plugin process, so create a new process.
[email protected]132bca82013-12-10 09:14:47222 plugin_host = PpapiPluginProcessHost::CreatePluginHost(
Tom Sepez8db30ad2018-03-01 21:38:54223 *info, profile_data_directory, origin_lock);
[email protected]132bca82013-12-10 09:14:47224 if (!plugin_host) {
225 VLOG(1) << "Unable to create ppapi plugin process for: "
226 << plugin_path.MaybeAsASCII();
227 }
228
229 return plugin_host;
[email protected]a08ebea2011-02-13 17:50:20230}
231
[email protected]e67385f2011-12-21 06:00:56232PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiBrokerProcess(
[email protected]6be31d202013-02-01 18:20:54233 int render_process_id,
[email protected]2dec8ec2013-02-07 19:20:34234 const base::FilePath& plugin_path) {
mostynb4c27d042015-03-18 21:47:47235 DCHECK_CURRENTLY_ON(BrowserThread::IO);
[email protected]eb415bf0e2011-04-14 02:45:42236
[email protected]6be31d202013-02-01 18:20:54237 if (filter_ && !filter_->CanLoadPlugin(render_process_id, plugin_path))
Ivan Kotenkov2c0d2bb32017-11-01 15:41:28238 return nullptr;
[email protected]6be31d202013-02-01 18:20:54239
[email protected]a50432d2011-09-30 16:32:14240 PpapiPluginProcessHost* plugin_host = FindPpapiBrokerProcess(plugin_path);
[email protected]eb415bf0e2011-04-14 02:45:42241 if (plugin_host)
242 return plugin_host;
243
244 // Validate that the plugin is actually registered.
Lei Zhangfa5e24d2018-08-29 01:34:09245 const PepperPluginInfo* info = GetRegisteredPpapiPluginInfo(plugin_path);
[email protected]eb415bf0e2011-04-14 02:45:42246 if (!info)
Ivan Kotenkov2c0d2bb32017-11-01 15:41:28247 return nullptr;
[email protected]eb415bf0e2011-04-14 02:45:42248
Lei Zhangfa5e24d2018-08-29 01:34:09249 DCHECK(info->is_out_of_process);
[email protected]eb415bf0e2011-04-14 02:45:42250
251 // This broker isn't loaded by any broker process, so create a new process.
[email protected]a50432d2011-09-30 16:32:14252 return PpapiPluginProcessHost::CreateBrokerHost(*info);
[email protected]eb415bf0e2011-04-14 02:45:42253}
254
[email protected]e67385f2011-12-21 06:00:56255void PluginServiceImpl::OpenChannelToPpapiPlugin(
[email protected]6be31d202013-02-01 18:20:54256 int render_process_id,
[email protected]2dec8ec2013-02-07 19:20:34257 const base::FilePath& plugin_path,
258 const base::FilePath& profile_data_directory,
Tom Sepez8db30ad2018-03-01 21:38:54259 const base::Optional<url::Origin>& origin_lock,
[email protected]a50432d2011-09-30 16:32:14260 PpapiPluginProcessHost::PluginClient* client) {
[email protected]d259a8e2011-05-18 22:31:09261 PpapiPluginProcessHost* plugin_host = FindOrStartPpapiPluginProcess(
Tom Sepez8db30ad2018-03-01 21:38:54262 render_process_id, plugin_path, profile_data_directory, origin_lock);
[email protected]1bf0fb22012-04-12 21:44:16263 if (plugin_host) {
[email protected]a08ebea2011-02-13 17:50:20264 plugin_host->OpenChannelToPlugin(client);
[email protected]1bf0fb22012-04-12 21:44:16265 } else {
266 // Send error.
[email protected]108fd342013-01-04 20:46:54267 client->OnPpapiChannelOpened(IPC::ChannelHandle(), base::kNullProcessId, 0);
[email protected]1bf0fb22012-04-12 21:44:16268 }
[email protected]a08ebea2011-02-13 17:50:20269}
270
[email protected]e67385f2011-12-21 06:00:56271void PluginServiceImpl::OpenChannelToPpapiBroker(
[email protected]6be31d202013-02-01 18:20:54272 int render_process_id,
Raymes Khoury978652c2017-11-27 06:28:37273 int render_frame_id,
[email protected]2dec8ec2013-02-07 19:20:34274 const base::FilePath& path,
[email protected]a50432d2011-09-30 16:32:14275 PpapiPluginProcessHost::BrokerClient* client) {
Eric Seckler8652dcd52018-09-20 10:42:28276 base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
277 base::BindOnce(&PluginServiceImpl::RecordBrokerUsage,
278 render_process_id, render_frame_id));
Raymes Khoury978652c2017-11-27 06:28:37279
[email protected]6be31d202013-02-01 18:20:54280 PpapiPluginProcessHost* plugin_host = FindOrStartPpapiBrokerProcess(
281 render_process_id, path);
[email protected]1bf0fb22012-04-12 21:44:16282 if (plugin_host) {
[email protected]a50432d2011-09-30 16:32:14283 plugin_host->OpenChannelToPlugin(client);
[email protected]1bf0fb22012-04-12 21:44:16284 } else {
285 // Send error.
[email protected]108fd342013-01-04 20:46:54286 client->OnPpapiChannelOpened(IPC::ChannelHandle(), base::kNullProcessId, 0);
[email protected]1bf0fb22012-04-12 21:44:16287 }
[email protected]eb415bf0e2011-04-14 02:45:42288}
289
[email protected]e67385f2011-12-21 06:00:56290bool PluginServiceImpl::GetPluginInfoArray(
[email protected]51b63f62011-10-05 18:55:42291 const GURL& url,
292 const std::string& mime_type,
293 bool allow_wildcard,
[email protected]d7bd3e52013-07-21 04:29:20294 std::vector<WebPluginInfo>* plugins,
[email protected]51b63f62011-10-05 18:55:42295 std::vector<std::string>* actual_mime_types) {
296 bool use_stale = false;
[email protected]29e2fb42013-07-19 01:13:47297 PluginList::Singleton()->GetPluginInfoArray(
pimane8c57ea2016-04-06 01:19:36298 url, mime_type, allow_wildcard, &use_stale, plugins, actual_mime_types);
[email protected]51b63f62011-10-05 18:55:42299 return use_stale;
300}
301
[email protected]e67385f2011-12-21 06:00:56302bool PluginServiceImpl::GetPluginInfo(int render_process_id,
[email protected]60eca4eb2013-12-06 00:02:16303 int render_frame_id,
[email protected]130757672012-10-24 00:26:19304 ResourceContext* context,
[email protected]e67385f2011-12-21 06:00:56305 const GURL& url,
tommyclif2a1e9f2016-10-06 18:34:36306 const url::Origin& main_frame_origin,
[email protected]e67385f2011-12-21 06:00:56307 const std::string& mime_type,
308 bool allow_wildcard,
309 bool* is_stale,
[email protected]d7bd3e52013-07-21 04:29:20310 WebPluginInfo* info,
[email protected]e67385f2011-12-21 06:00:56311 std::string* actual_mime_type) {
[email protected]d7bd3e52013-07-21 04:29:20312 std::vector<WebPluginInfo> plugins;
[email protected]68598072011-07-29 08:21:28313 std::vector<std::string> mime_types;
[email protected]88ca4912011-10-12 14:00:43314 bool stale = GetPluginInfoArray(
315 url, mime_type, allow_wildcard, &plugins, &mime_types);
316 if (is_stale)
317 *is_stale = stale;
[email protected]dfba8762011-09-02 12:49:54318
[email protected]68598072011-07-29 08:21:28319 for (size_t i = 0; i < plugins.size(); ++i) {
tommyclif2a1e9f2016-10-06 18:34:36320 if (!filter_ ||
321 filter_->IsPluginAvailable(render_process_id, render_frame_id, context,
322 url, main_frame_origin, &plugins[i])) {
[email protected]68598072011-07-29 08:21:28323 *info = plugins[i];
324 if (actual_mime_type)
325 *actual_mime_type = mime_types[i];
326 return true;
327 }
328 }
329 return false;
[email protected]6fdd4182010-10-14 23:59:26330}
331
[email protected]2dec8ec2013-02-07 19:20:34332bool PluginServiceImpl::GetPluginInfoByPath(const base::FilePath& plugin_path,
[email protected]d7bd3e52013-07-21 04:29:20333 WebPluginInfo* info) {
334 std::vector<WebPluginInfo> plugins;
[email protected]29e2fb42013-07-19 01:13:47335 PluginList::Singleton()->GetPluginsNoRefresh(&plugins);
[email protected]88ca4912011-10-12 14:00:43336
Lei Zhangfa5e24d2018-08-29 01:34:09337 for (const WebPluginInfo& plugin : plugins) {
338 if (plugin.path == plugin_path) {
339 *info = plugin;
[email protected]88ca4912011-10-12 14:00:43340 return true;
341 }
342 }
343
344 return false;
345}
346
[email protected]fcf75d42013-12-03 20:11:26347base::string16 PluginServiceImpl::GetPluginDisplayNameByPath(
[email protected]2dec8ec2013-02-07 19:20:34348 const base::FilePath& path) {
[email protected]fcf75d42013-12-03 20:11:26349 base::string16 plugin_name = path.LossyDisplayName();
[email protected]d7bd3e52013-07-21 04:29:20350 WebPluginInfo info;
[email protected]8be45842012-04-13 19:49:29351 if (PluginService::GetInstance()->GetPluginInfoByPath(path, &info) &&
352 !info.name.empty()) {
353 plugin_name = info.name;
354#if defined(OS_MACOSX)
355 // Many plugins on the Mac have .plugin in the actual name, which looks
356 // terrible, so look for that and strip it off if present.
Lei Zhangfa5e24d2018-08-29 01:34:09357 static const char kPluginExtension[] = ".plugin";
brettwa7ff1b292015-07-16 17:49:29358 if (base::EndsWith(plugin_name, base::ASCIIToUTF16(kPluginExtension),
359 base::CompareCase::SENSITIVE))
Lei Zhangfa5e24d2018-08-29 01:34:09360 plugin_name.erase(plugin_name.length() - strlen(kPluginExtension));
361#endif // defined(OS_MACOSX)
[email protected]8be45842012-04-13 19:49:29362 }
363 return plugin_name;
364}
365
fdoray9292e0722017-05-13 03:47:51366void PluginServiceImpl::GetPlugins(GetPluginsCallback callback) {
367 base::PostTaskAndReplyWithResult(
368 plugin_list_task_runner_.get(), FROM_HERE, base::BindOnce([]() {
369 std::vector<WebPluginInfo> plugins;
370 PluginList::Singleton()->GetPlugins(&plugins);
371 return plugins;
372 }),
373 std::move(callback));
[email protected]dfba8762011-09-02 12:49:54374}
375
[email protected]e67385f2011-12-21 06:00:56376void PluginServiceImpl::RegisterPepperPlugins() {
[email protected]dac6a5a2013-07-25 05:06:48377 ComputePepperPluginList(&ppapi_plugins_);
Lei Zhangfa5e24d2018-08-29 01:34:09378 for (const auto& plugin : ppapi_plugins_)
379 RegisterInternalPlugin(plugin.ToWebPluginInfo(), /*add_at_beginning=*/true);
[email protected]4e0616e2010-05-28 14:55:53380}
[email protected]634d23d2011-01-19 10:38:19381
[email protected]eb415bf0e2011-04-14 02:45:42382// There should generally be very few plugins so a brute-force search is fine.
Lei Zhangfa5e24d2018-08-29 01:34:09383const PepperPluginInfo* PluginServiceImpl::GetRegisteredPpapiPluginInfo(
[email protected]2dec8ec2013-02-07 19:20:34384 const base::FilePath& plugin_path) {
Lei Zhangfa5e24d2018-08-29 01:34:09385 for (auto& plugin : ppapi_plugins_) {
386 if (plugin.path == plugin_path)
387 return &plugin;
[email protected]eb415bf0e2011-04-14 02:45:42388 }
Lei Zhangfa5e24d2018-08-29 01:34:09389
[email protected]076117592011-08-17 03:16:41390 // We did not find the plugin in our list. But wait! the plugin can also
391 // be a latecomer, as it happens with pepper flash. This information
392 // can be obtained from the PluginList singleton and we can use it to
393 // construct it and add it to the list. This same deal needs to be done
394 // in the renderer side in PepperPluginRegistry.
[email protected]d7bd3e52013-07-21 04:29:20395 WebPluginInfo webplugin_info;
[email protected]88ca4912011-10-12 14:00:43396 if (!GetPluginInfoByPath(plugin_path, &webplugin_info))
thestig76ee1f42016-07-08 18:54:00397 return nullptr;
[email protected]130757672012-10-24 00:26:19398 PepperPluginInfo new_pepper_info;
[email protected]076117592011-08-17 03:16:41399 if (!MakePepperPluginInfo(webplugin_info, &new_pepper_info))
thestig76ee1f42016-07-08 18:54:00400 return nullptr;
[email protected]076117592011-08-17 03:16:41401 ppapi_plugins_.push_back(new_pepper_info);
thestig76ee1f42016-07-08 18:54:00402 return &ppapi_plugins_.back();
[email protected]eb415bf0e2011-04-14 02:45:42403}
404
[email protected]130757672012-10-24 00:26:19405void PluginServiceImpl::SetFilter(PluginServiceFilter* filter) {
[email protected]3a5180ae2011-12-21 02:39:38406 filter_ = filter;
407}
408
[email protected]130757672012-10-24 00:26:19409PluginServiceFilter* PluginServiceImpl::GetFilter() {
[email protected]3a5180ae2011-12-21 02:39:38410 return filter_;
411}
412
[email protected]47214d882012-02-29 06:28:48413static const unsigned int kMaxCrashesPerInterval = 3;
414static const unsigned int kCrashesInterval = 120;
415
[email protected]2dec8ec2013-02-07 19:20:34416void PluginServiceImpl::RegisterPluginCrash(const base::FilePath& path) {
mostynb4c27d042015-03-18 21:47:47417 DCHECK_CURRENTLY_ON(BrowserThread::IO);
[email protected]2dec8ec2013-02-07 19:20:34418 std::map<base::FilePath, std::vector<base::Time> >::iterator i =
[email protected]47214d882012-02-29 06:28:48419 crash_times_.find(path);
420 if (i == crash_times_.end()) {
421 crash_times_[path] = std::vector<base::Time>();
422 i = crash_times_.find(path);
423 }
424 if (i->second.size() == kMaxCrashesPerInterval) {
425 i->second.erase(i->second.begin());
426 }
427 base::Time time = base::Time::Now();
428 i->second.push_back(time);
429}
430
[email protected]2dec8ec2013-02-07 19:20:34431bool PluginServiceImpl::IsPluginUnstable(const base::FilePath& path) {
mostynb4c27d042015-03-18 21:47:47432 DCHECK_CURRENTLY_ON(BrowserThread::IO);
[email protected]2dec8ec2013-02-07 19:20:34433 std::map<base::FilePath, std::vector<base::Time> >::const_iterator i =
[email protected]47214d882012-02-29 06:28:48434 crash_times_.find(path);
435 if (i == crash_times_.end()) {
436 return false;
437 }
438 if (i->second.size() != kMaxCrashesPerInterval) {
439 return false;
440 }
441 base::TimeDelta delta = base::Time::Now() - i->second[0];
[email protected]d8c70062013-04-24 00:22:34442 return delta.InSeconds() <= kCrashesInterval;
[email protected]47214d882012-02-29 06:28:48443}
444
[email protected]e67385f2011-12-21 06:00:56445void PluginServiceImpl::RefreshPlugins() {
[email protected]29e2fb42013-07-19 01:13:47446 PluginList::Singleton()->RefreshPlugins();
[email protected]f520b5b2011-11-08 02:42:14447}
448
[email protected]8f3372122013-07-18 04:34:14449void PluginServiceImpl::RegisterInternalPlugin(
[email protected]d7bd3e52013-07-21 04:29:20450 const WebPluginInfo& info,
[email protected]8f3372122013-07-18 04:34:14451 bool add_at_beginning) {
[email protected]29e2fb42013-07-19 01:13:47452 PluginList::Singleton()->RegisterInternalPlugin(info, add_at_beginning);
[email protected]f520b5b2011-11-08 02:42:14453}
454
[email protected]2dec8ec2013-02-07 19:20:34455void PluginServiceImpl::UnregisterInternalPlugin(const base::FilePath& path) {
[email protected]29e2fb42013-07-19 01:13:47456 PluginList::Singleton()->UnregisterInternalPlugin(path);
[email protected]f520b5b2011-11-08 02:42:14457}
458
[email protected]8f3372122013-07-18 04:34:14459void PluginServiceImpl::GetInternalPlugins(
[email protected]d7bd3e52013-07-21 04:29:20460 std::vector<WebPluginInfo>* plugins) {
[email protected]29e2fb42013-07-19 01:13:47461 PluginList::Singleton()->GetInternalPlugins(plugins);
[email protected]8f3372122013-07-18 04:34:14462}
463
[email protected]aec5ed52014-06-20 07:51:42464bool PluginServiceImpl::PpapiDevChannelSupported(
465 BrowserContext* browser_context,
466 const GURL& document_url) {
wfh6be06282015-07-20 18:04:02467 return GetContentClient()->browser()->IsPluginAllowedToUseDevChannelAPIs(
468 browser_context, document_url);
[email protected]8ddc6b7c2013-12-12 20:42:06469}
470
[email protected]130757672012-10-24 00:26:19471} // namespace content