blob: 7e6afb105aad13a5cfa1d0d32ff5ac624db59c01 [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
[email protected]d33e7cc2011-09-23 01:43:569#include "base/bind.h"
[email protected]d48f1e0c2009-02-12 20:57:5410#include "base/command_line.h"
[email protected]7b3ee8b2011-04-01 18:48:1911#include "base/compiler_specific.h"
[email protected]57999812013-02-24 05:40:5212#include "base/files/file_path.h"
skyostil95082a62015-06-05 19:53:0713#include "base/location.h"
asvitkine30330812016-08-30 04:01:0814#include "base/metrics/histogram_macros.h"
skyostil95082a62015-06-05 19:53:0715#include "base/single_thread_task_runner.h"
[email protected]348fbaac2013-06-11 06:31:5116#include "base/strings/string_util.h"
[email protected]74ebfb12013-06-07 20:48:0017#include "base/strings/utf_string_conversions.h"
[email protected]7f070d42011-03-09 20:25:3218#include "base/synchronization/waitable_event.h"
[email protected]34b99632011-01-01 01:01:0619#include "base/threading/thread.h"
avib7348942015-12-25 20:57:1020#include "build/build_config.h"
[email protected]a01efd22011-03-01 00:38:3221#include "content/browser/ppapi_plugin_process_host.h"
[email protected]f3b1a082011-11-18 00:34:3022#include "content/browser/renderer_host/render_process_host_impl.h"
[email protected]b3c41c0b2012-03-06 15:48:3223#include "content/browser/renderer_host/render_view_host_impl.h"
wfh1a90e032015-04-14 17:10:1724#include "content/common/content_switches_internal.h"
[email protected]dac6a5a2013-07-25 05:06:4825#include "content/common/pepper_plugin_list.h"
[email protected]29e2fb42013-07-19 01:13:4726#include "content/common/plugin_list.h"
[email protected]38b592902011-04-16 02:08:4227#include "content/common/view_messages.h"
[email protected]c38831a12011-10-28 12:44:4928#include "content/public/browser/browser_thread.h"
[email protected]87f3c082011-10-19 18:07:4429#include "content/public/browser/content_browser_client.h"
[email protected]31f376c2012-03-13 16:43:0930#include "content/public/browser/plugin_service_filter.h"
[email protected]ce967862012-02-09 22:47:0531#include "content/public/browser/resource_context.h"
[email protected]73270292013-08-09 03:48:0732#include "content/public/common/content_constants.h"
[email protected]c08950d22011-10-13 22:20:2933#include "content/public/common/content_switches.h"
[email protected]bd5d6cf2011-12-01 00:39:1234#include "content/public/common/process_type.h"
[email protected]d7bd3e52013-07-21 04:29:2035#include "content/public/common/webplugininfo.h"
[email protected]191eb3f72010-12-21 06:27:5036
[email protected]130757672012-10-24 00:26:1937namespace content {
[email protected]d33e7cc2011-09-23 01:43:5638namespace {
39
[email protected]fd8d8d6c2013-02-28 02:48:3340// This enum is used to collect Flash usage data.
41enum FlashUsage {
[email protected]fd8d8d6c2013-02-28 02:48:3342 // Number of browser processes that have started at least one PPAPI Flash
43 // process during their lifetime.
pimane8c57ea2016-04-06 01:19:3644 START_PPAPI_FLASH_AT_LEAST_ONCE = 1,
[email protected]fd8d8d6c2013-02-28 02:48:3345 // Total number of browser processes.
46 TOTAL_BROWSER_PROCESSES,
47 FLASH_USAGE_ENUM_COUNT
48};
49
[email protected]49125952011-09-27 18:05:1550// Callback set on the PluginList to assert that plugin loading happens on the
51// correct thread.
[email protected]1b517202012-12-19 17:16:1052void WillLoadPluginsCallback(
[email protected]a33fa9d2012-05-16 14:47:4953 base::SequencedWorkerPool::SequenceToken token) {
pimane8c57ea2016-04-06 01:19:3654 CHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread(
55 token));
[email protected]a79912252012-05-16 11:52:1956}
[email protected]d33e7cc2011-09-23 01:43:5657
[email protected]07b71c82013-01-08 19:07:3158} // namespace
59
[email protected]3a5180ae2011-12-21 02:39:3860// static
61PluginService* PluginService::GetInstance() {
[email protected]e67385f2011-12-21 06:00:5662 return PluginServiceImpl::GetInstance();
[email protected]3a5180ae2011-12-21 02:39:3863}
64
65void PluginService::PurgePluginListCache(BrowserContext* browser_context,
66 bool reload_pages) {
67 for (RenderProcessHost::iterator it = RenderProcessHost::AllHostsIterator();
68 !it.IsAtEnd(); it.Advance()) {
69 RenderProcessHost* host = it.GetCurrentValue();
70 if (!browser_context || host->GetBrowserContext() == browser_context)
71 host->Send(new ViewMsg_PurgePluginListCache(reload_pages));
72 }
73}
74
initial.commit09911bf2008-07-26 23:55:2975// static
[email protected]e67385f2011-12-21 06:00:5676PluginServiceImpl* PluginServiceImpl::GetInstance() {
olli.raula36aa8be2015-09-10 11:14:2277 return base::Singleton<PluginServiceImpl>::get();
initial.commit09911bf2008-07-26 23:55:2978}
79
[email protected]e67385f2011-12-21 06:00:5680PluginServiceImpl::PluginServiceImpl()
pimane8c57ea2016-04-06 01:19:3681 : filter_(NULL) {
[email protected]fd8d8d6c2013-02-28 02:48:3382 // Collect the total number of browser processes (which create
83 // PluginServiceImpl objects, to be precise). The number is used to normalize
84 // the number of processes which start at least one NPAPI/PPAPI Flash process.
85 static bool counted = false;
86 if (!counted) {
87 counted = true;
88 UMA_HISTOGRAM_ENUMERATION("Plugin.FlashUsage", TOTAL_BROWSER_PROCESSES,
89 FLASH_USAGE_ENUM_COUNT);
90 }
[email protected]ee066172011-11-10 23:20:0591}
92
[email protected]e67385f2011-12-21 06:00:5693PluginServiceImpl::~PluginServiceImpl() {
[email protected]ee066172011-11-10 23:20:0594}
95
[email protected]e67385f2011-12-21 06:00:5696void PluginServiceImpl::Init() {
mostynbc965fd6c2016-01-08 14:22:0797 plugin_list_token_ = base::SequencedWorkerPool::GetSequenceToken();
[email protected]29e2fb42013-07-19 01:13:4798 PluginList::Singleton()->set_will_load_plugins_callback(
[email protected]1b517202012-12-19 17:16:1099 base::Bind(&WillLoadPluginsCallback, plugin_list_token_));
[email protected]49125952011-09-27 18:05:15100
[email protected]4e0616e2010-05-28 14:55:53101 RegisterPepperPlugins();
initial.commit09911bf2008-07-26 23:55:29102}
103
[email protected]e67385f2011-12-21 06:00:56104PpapiPluginProcessHost* PluginServiceImpl::FindPpapiPluginProcess(
[email protected]2dec8ec2013-02-07 19:20:34105 const base::FilePath& plugin_path,
106 const base::FilePath& profile_data_directory) {
[email protected]4967f792012-01-20 22:14:40107 for (PpapiPluginProcessHostIterator iter; !iter.Done(); ++iter) {
[email protected]dd9a0952012-05-31 20:11:31108 if (iter->plugin_path() == plugin_path &&
109 iter->profile_data_directory() == profile_data_directory) {
[email protected]4967f792012-01-20 22:14:40110 return *iter;
[email protected]dd9a0952012-05-31 20:11:31111 }
[email protected]a08ebea2011-02-13 17:50:20112 }
[email protected]a08ebea2011-02-13 17:50:20113 return NULL;
114}
115
[email protected]e67385f2011-12-21 06:00:56116PpapiPluginProcessHost* PluginServiceImpl::FindPpapiBrokerProcess(
[email protected]2dec8ec2013-02-07 19:20:34117 const base::FilePath& broker_path) {
[email protected]4967f792012-01-20 22:14:40118 for (PpapiBrokerProcessHostIterator iter; !iter.Done(); ++iter) {
119 if (iter->plugin_path() == broker_path)
120 return *iter;
[email protected]eb415bf0e2011-04-14 02:45:42121 }
122
123 return NULL;
124}
125
[email protected]e67385f2011-12-21 06:00:56126PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiPluginProcess(
[email protected]6be31d202013-02-01 18:20:54127 int render_process_id,
[email protected]2dec8ec2013-02-07 19:20:34128 const base::FilePath& plugin_path,
[email protected]8522332e2013-08-28 19:42:59129 const base::FilePath& profile_data_directory) {
mostynb4c27d042015-03-18 21:47:47130 DCHECK_CURRENTLY_ON(BrowserThread::IO);
[email protected]a08ebea2011-02-13 17:50:20131
[email protected]132bca82013-12-10 09:14:47132 if (filter_ && !filter_->CanLoadPlugin(render_process_id, plugin_path)) {
133 VLOG(1) << "Unable to load ppapi plugin: " << plugin_path.MaybeAsASCII();
[email protected]6be31d202013-02-01 18:20:54134 return NULL;
[email protected]132bca82013-12-10 09:14:47135 }
[email protected]6be31d202013-02-01 18:20:54136
[email protected]dd9a0952012-05-31 20:11:31137 PpapiPluginProcessHost* plugin_host =
138 FindPpapiPluginProcess(plugin_path, profile_data_directory);
[email protected]a08ebea2011-02-13 17:50:20139 if (plugin_host)
140 return plugin_host;
141
[email protected]eb415bf0e2011-04-14 02:45:42142 // Validate that the plugin is actually registered.
[email protected]130757672012-10-24 00:26:19143 PepperPluginInfo* info = GetRegisteredPpapiPluginInfo(plugin_path);
[email protected]132bca82013-12-10 09:14:47144 if (!info) {
145 VLOG(1) << "Unable to find ppapi plugin registration for: "
146 << plugin_path.MaybeAsASCII();
[email protected]a08ebea2011-02-13 17:50:20147 return NULL;
[email protected]132bca82013-12-10 09:14:47148 }
[email protected]a08ebea2011-02-13 17:50:20149
[email protected]fd8d8d6c2013-02-28 02:48:33150 // Record when PPAPI Flash process is started for the first time.
151 static bool counted = false;
152 if (!counted && info->name == kFlashPluginName) {
153 counted = true;
154 UMA_HISTOGRAM_ENUMERATION("Plugin.FlashUsage",
155 START_PPAPI_FLASH_AT_LEAST_ONCE,
156 FLASH_USAGE_ENUM_COUNT);
157 }
158
[email protected]a08ebea2011-02-13 17:50:20159 // This plugin isn't loaded by any plugin process, so create a new process.
[email protected]132bca82013-12-10 09:14:47160 plugin_host = PpapiPluginProcessHost::CreatePluginHost(
[email protected]8522332e2013-08-28 19:42:59161 *info, profile_data_directory);
[email protected]132bca82013-12-10 09:14:47162 if (!plugin_host) {
163 VLOG(1) << "Unable to create ppapi plugin process for: "
164 << plugin_path.MaybeAsASCII();
165 }
166
167 return plugin_host;
[email protected]a08ebea2011-02-13 17:50:20168}
169
[email protected]e67385f2011-12-21 06:00:56170PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiBrokerProcess(
[email protected]6be31d202013-02-01 18:20:54171 int render_process_id,
[email protected]2dec8ec2013-02-07 19:20:34172 const base::FilePath& plugin_path) {
mostynb4c27d042015-03-18 21:47:47173 DCHECK_CURRENTLY_ON(BrowserThread::IO);
[email protected]eb415bf0e2011-04-14 02:45:42174
[email protected]6be31d202013-02-01 18:20:54175 if (filter_ && !filter_->CanLoadPlugin(render_process_id, plugin_path))
176 return NULL;
177
[email protected]a50432d2011-09-30 16:32:14178 PpapiPluginProcessHost* plugin_host = FindPpapiBrokerProcess(plugin_path);
[email protected]eb415bf0e2011-04-14 02:45:42179 if (plugin_host)
180 return plugin_host;
181
182 // Validate that the plugin is actually registered.
[email protected]130757672012-10-24 00:26:19183 PepperPluginInfo* info = GetRegisteredPpapiPluginInfo(plugin_path);
[email protected]eb415bf0e2011-04-14 02:45:42184 if (!info)
185 return NULL;
186
187 // TODO(ddorwin): Uncomment once out of process is supported.
188 // DCHECK(info->is_out_of_process);
189
190 // This broker isn't loaded by any broker process, so create a new process.
[email protected]a50432d2011-09-30 16:32:14191 return PpapiPluginProcessHost::CreateBrokerHost(*info);
[email protected]eb415bf0e2011-04-14 02:45:42192}
193
[email protected]e67385f2011-12-21 06:00:56194void PluginServiceImpl::OpenChannelToPpapiPlugin(
[email protected]6be31d202013-02-01 18:20:54195 int render_process_id,
[email protected]2dec8ec2013-02-07 19:20:34196 const base::FilePath& plugin_path,
197 const base::FilePath& profile_data_directory,
[email protected]a50432d2011-09-30 16:32:14198 PpapiPluginProcessHost::PluginClient* client) {
[email protected]d259a8e2011-05-18 22:31:09199 PpapiPluginProcessHost* plugin_host = FindOrStartPpapiPluginProcess(
[email protected]8522332e2013-08-28 19:42:59200 render_process_id, plugin_path, profile_data_directory);
[email protected]1bf0fb22012-04-12 21:44:16201 if (plugin_host) {
[email protected]a08ebea2011-02-13 17:50:20202 plugin_host->OpenChannelToPlugin(client);
[email protected]1bf0fb22012-04-12 21:44:16203 } else {
204 // Send error.
[email protected]108fd342013-01-04 20:46:54205 client->OnPpapiChannelOpened(IPC::ChannelHandle(), base::kNullProcessId, 0);
[email protected]1bf0fb22012-04-12 21:44:16206 }
[email protected]a08ebea2011-02-13 17:50:20207}
208
[email protected]e67385f2011-12-21 06:00:56209void PluginServiceImpl::OpenChannelToPpapiBroker(
[email protected]6be31d202013-02-01 18:20:54210 int render_process_id,
[email protected]2dec8ec2013-02-07 19:20:34211 const base::FilePath& path,
[email protected]a50432d2011-09-30 16:32:14212 PpapiPluginProcessHost::BrokerClient* client) {
[email protected]6be31d202013-02-01 18:20:54213 PpapiPluginProcessHost* plugin_host = FindOrStartPpapiBrokerProcess(
214 render_process_id, path);
[email protected]1bf0fb22012-04-12 21:44:16215 if (plugin_host) {
[email protected]a50432d2011-09-30 16:32:14216 plugin_host->OpenChannelToPlugin(client);
[email protected]1bf0fb22012-04-12 21:44:16217 } else {
218 // Send error.
[email protected]108fd342013-01-04 20:46:54219 client->OnPpapiChannelOpened(IPC::ChannelHandle(), base::kNullProcessId, 0);
[email protected]1bf0fb22012-04-12 21:44:16220 }
[email protected]eb415bf0e2011-04-14 02:45:42221}
222
[email protected]e67385f2011-12-21 06:00:56223bool PluginServiceImpl::GetPluginInfoArray(
[email protected]51b63f62011-10-05 18:55:42224 const GURL& url,
225 const std::string& mime_type,
226 bool allow_wildcard,
[email protected]d7bd3e52013-07-21 04:29:20227 std::vector<WebPluginInfo>* plugins,
[email protected]51b63f62011-10-05 18:55:42228 std::vector<std::string>* actual_mime_types) {
229 bool use_stale = false;
[email protected]29e2fb42013-07-19 01:13:47230 PluginList::Singleton()->GetPluginInfoArray(
pimane8c57ea2016-04-06 01:19:36231 url, mime_type, allow_wildcard, &use_stale, plugins, actual_mime_types);
[email protected]51b63f62011-10-05 18:55:42232 return use_stale;
233}
234
[email protected]e67385f2011-12-21 06:00:56235bool PluginServiceImpl::GetPluginInfo(int render_process_id,
[email protected]60eca4eb2013-12-06 00:02:16236 int render_frame_id,
[email protected]130757672012-10-24 00:26:19237 ResourceContext* context,
[email protected]e67385f2011-12-21 06:00:56238 const GURL& url,
239 const GURL& page_url,
240 const std::string& mime_type,
241 bool allow_wildcard,
242 bool* is_stale,
[email protected]d7bd3e52013-07-21 04:29:20243 WebPluginInfo* info,
[email protected]e67385f2011-12-21 06:00:56244 std::string* actual_mime_type) {
[email protected]d7bd3e52013-07-21 04:29:20245 std::vector<WebPluginInfo> plugins;
[email protected]68598072011-07-29 08:21:28246 std::vector<std::string> mime_types;
[email protected]88ca4912011-10-12 14:00:43247 bool stale = GetPluginInfoArray(
248 url, mime_type, allow_wildcard, &plugins, &mime_types);
249 if (is_stale)
250 *is_stale = stale;
[email protected]dfba8762011-09-02 12:49:54251
[email protected]68598072011-07-29 08:21:28252 for (size_t i = 0; i < plugins.size(); ++i) {
[email protected]05f511282013-02-05 15:02:50253 if (!filter_ || filter_->IsPluginAvailable(render_process_id,
[email protected]60eca4eb2013-12-06 00:02:16254 render_frame_id,
[email protected]05f511282013-02-05 15:02:50255 context,
256 url,
257 page_url,
258 &plugins[i])) {
[email protected]68598072011-07-29 08:21:28259 *info = plugins[i];
260 if (actual_mime_type)
261 *actual_mime_type = mime_types[i];
262 return true;
263 }
264 }
265 return false;
[email protected]6fdd4182010-10-14 23:59:26266}
267
[email protected]2dec8ec2013-02-07 19:20:34268bool PluginServiceImpl::GetPluginInfoByPath(const base::FilePath& plugin_path,
[email protected]d7bd3e52013-07-21 04:29:20269 WebPluginInfo* info) {
270 std::vector<WebPluginInfo> plugins;
[email protected]29e2fb42013-07-19 01:13:47271 PluginList::Singleton()->GetPluginsNoRefresh(&plugins);
[email protected]88ca4912011-10-12 14:00:43272
[email protected]d7bd3e52013-07-21 04:29:20273 for (std::vector<WebPluginInfo>::iterator it = plugins.begin();
[email protected]88ca4912011-10-12 14:00:43274 it != plugins.end();
275 ++it) {
276 if (it->path == plugin_path) {
277 *info = *it;
278 return true;
279 }
280 }
281
282 return false;
283}
284
[email protected]fcf75d42013-12-03 20:11:26285base::string16 PluginServiceImpl::GetPluginDisplayNameByPath(
[email protected]2dec8ec2013-02-07 19:20:34286 const base::FilePath& path) {
[email protected]fcf75d42013-12-03 20:11:26287 base::string16 plugin_name = path.LossyDisplayName();
[email protected]d7bd3e52013-07-21 04:29:20288 WebPluginInfo info;
[email protected]8be45842012-04-13 19:49:29289 if (PluginService::GetInstance()->GetPluginInfoByPath(path, &info) &&
290 !info.name.empty()) {
291 plugin_name = info.name;
292#if defined(OS_MACOSX)
293 // Many plugins on the Mac have .plugin in the actual name, which looks
294 // terrible, so look for that and strip it off if present.
295 const std::string kPluginExtension = ".plugin";
brettwa7ff1b292015-07-16 17:49:29296 if (base::EndsWith(plugin_name, base::ASCIIToUTF16(kPluginExtension),
297 base::CompareCase::SENSITIVE))
[email protected]8be45842012-04-13 19:49:29298 plugin_name.erase(plugin_name.length() - kPluginExtension.length());
299#endif // OS_MACOSX
300 }
301 return plugin_name;
302}
303
[email protected]e67385f2011-12-21 06:00:56304void PluginServiceImpl::GetPlugins(const GetPluginsCallback& callback) {
skyostil95082a62015-06-05 19:53:07305 scoped_refptr<base::SingleThreadTaskRunner> target_task_runner(
306 base::ThreadTaskRunnerHandle::Get());
[email protected]49125952011-09-27 18:05:15307
pimane8c57ea2016-04-06 01:19:36308 BrowserThread::GetBlockingPool()->PostSequencedWorkerTaskWithShutdownBehavior(
309 plugin_list_token_, FROM_HERE,
310 base::Bind(&PluginServiceImpl::GetPluginsInternal, base::Unretained(this),
311 base::RetainedRef(target_task_runner), callback),
312 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
[email protected]d33e7cc2011-09-23 01:43:56313}
314
[email protected]e67385f2011-12-21 06:00:56315void PluginServiceImpl::GetPluginsInternal(
skyostil95082a62015-06-05 19:53:07316 base::SingleThreadTaskRunner* target_task_runner,
317 const PluginService::GetPluginsCallback& callback) {
[email protected]a33fa9d2012-05-16 14:47:49318 DCHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread(
319 plugin_list_token_));
[email protected]d33e7cc2011-09-23 01:43:56320
[email protected]d7bd3e52013-07-21 04:29:20321 std::vector<WebPluginInfo> plugins;
pimane8c57ea2016-04-06 01:19:36322 PluginList::Singleton()->GetPlugins(&plugins);
[email protected]d33e7cc2011-09-23 01:43:56323
skyostil95082a62015-06-05 19:53:07324 target_task_runner->PostTask(FROM_HERE, base::Bind(callback, plugins));
[email protected]dfba8762011-09-02 12:49:54325}
326
[email protected]e67385f2011-12-21 06:00:56327void PluginServiceImpl::RegisterPepperPlugins() {
[email protected]dac6a5a2013-07-25 05:06:48328 ComputePepperPluginList(&ppapi_plugins_);
[email protected]a08ebea2011-02-13 17:50:20329 for (size_t i = 0; i < ppapi_plugins_.size(); ++i) {
[email protected]c6f3dea2012-01-14 02:23:11330 RegisterInternalPlugin(ppapi_plugins_[i].ToWebPluginInfo(), true);
[email protected]4e0616e2010-05-28 14:55:53331 }
332}
[email protected]634d23d2011-01-19 10:38:19333
[email protected]eb415bf0e2011-04-14 02:45:42334// There should generally be very few plugins so a brute-force search is fine.
[email protected]130757672012-10-24 00:26:19335PepperPluginInfo* PluginServiceImpl::GetRegisteredPpapiPluginInfo(
[email protected]2dec8ec2013-02-07 19:20:34336 const base::FilePath& plugin_path) {
[email protected]3627aa3f2013-09-17 22:32:51337 for (size_t i = 0; i < ppapi_plugins_.size(); ++i) {
thestig76ee1f42016-07-08 18:54:00338 if (ppapi_plugins_[i].path == plugin_path)
339 return &ppapi_plugins_[i];
[email protected]eb415bf0e2011-04-14 02:45:42340 }
[email protected]076117592011-08-17 03:16:41341 // We did not find the plugin in our list. But wait! the plugin can also
342 // be a latecomer, as it happens with pepper flash. This information
343 // can be obtained from the PluginList singleton and we can use it to
344 // construct it and add it to the list. This same deal needs to be done
345 // in the renderer side in PepperPluginRegistry.
[email protected]d7bd3e52013-07-21 04:29:20346 WebPluginInfo webplugin_info;
[email protected]88ca4912011-10-12 14:00:43347 if (!GetPluginInfoByPath(plugin_path, &webplugin_info))
thestig76ee1f42016-07-08 18:54:00348 return nullptr;
[email protected]130757672012-10-24 00:26:19349 PepperPluginInfo new_pepper_info;
[email protected]076117592011-08-17 03:16:41350 if (!MakePepperPluginInfo(webplugin_info, &new_pepper_info))
thestig76ee1f42016-07-08 18:54:00351 return nullptr;
[email protected]076117592011-08-17 03:16:41352 ppapi_plugins_.push_back(new_pepper_info);
thestig76ee1f42016-07-08 18:54:00353 return &ppapi_plugins_.back();
[email protected]eb415bf0e2011-04-14 02:45:42354}
355
[email protected]130757672012-10-24 00:26:19356void PluginServiceImpl::SetFilter(PluginServiceFilter* filter) {
[email protected]3a5180ae2011-12-21 02:39:38357 filter_ = filter;
358}
359
[email protected]130757672012-10-24 00:26:19360PluginServiceFilter* PluginServiceImpl::GetFilter() {
[email protected]3a5180ae2011-12-21 02:39:38361 return filter_;
362}
363
[email protected]47214d882012-02-29 06:28:48364static const unsigned int kMaxCrashesPerInterval = 3;
365static const unsigned int kCrashesInterval = 120;
366
[email protected]2dec8ec2013-02-07 19:20:34367void PluginServiceImpl::RegisterPluginCrash(const base::FilePath& path) {
mostynb4c27d042015-03-18 21:47:47368 DCHECK_CURRENTLY_ON(BrowserThread::IO);
[email protected]2dec8ec2013-02-07 19:20:34369 std::map<base::FilePath, std::vector<base::Time> >::iterator i =
[email protected]47214d882012-02-29 06:28:48370 crash_times_.find(path);
371 if (i == crash_times_.end()) {
372 crash_times_[path] = std::vector<base::Time>();
373 i = crash_times_.find(path);
374 }
375 if (i->second.size() == kMaxCrashesPerInterval) {
376 i->second.erase(i->second.begin());
377 }
378 base::Time time = base::Time::Now();
379 i->second.push_back(time);
380}
381
[email protected]2dec8ec2013-02-07 19:20:34382bool PluginServiceImpl::IsPluginUnstable(const base::FilePath& path) {
mostynb4c27d042015-03-18 21:47:47383 DCHECK_CURRENTLY_ON(BrowserThread::IO);
[email protected]2dec8ec2013-02-07 19:20:34384 std::map<base::FilePath, std::vector<base::Time> >::const_iterator i =
[email protected]47214d882012-02-29 06:28:48385 crash_times_.find(path);
386 if (i == crash_times_.end()) {
387 return false;
388 }
389 if (i->second.size() != kMaxCrashesPerInterval) {
390 return false;
391 }
392 base::TimeDelta delta = base::Time::Now() - i->second[0];
[email protected]d8c70062013-04-24 00:22:34393 return delta.InSeconds() <= kCrashesInterval;
[email protected]47214d882012-02-29 06:28:48394}
395
[email protected]e67385f2011-12-21 06:00:56396void PluginServiceImpl::RefreshPlugins() {
[email protected]29e2fb42013-07-19 01:13:47397 PluginList::Singleton()->RefreshPlugins();
[email protected]f520b5b2011-11-08 02:42:14398}
399
[email protected]8f3372122013-07-18 04:34:14400void PluginServiceImpl::RegisterInternalPlugin(
[email protected]d7bd3e52013-07-21 04:29:20401 const WebPluginInfo& info,
[email protected]8f3372122013-07-18 04:34:14402 bool add_at_beginning) {
[email protected]29e2fb42013-07-19 01:13:47403 PluginList::Singleton()->RegisterInternalPlugin(info, add_at_beginning);
[email protected]f520b5b2011-11-08 02:42:14404}
405
[email protected]2dec8ec2013-02-07 19:20:34406void PluginServiceImpl::UnregisterInternalPlugin(const base::FilePath& path) {
[email protected]29e2fb42013-07-19 01:13:47407 PluginList::Singleton()->UnregisterInternalPlugin(path);
[email protected]f520b5b2011-11-08 02:42:14408}
409
[email protected]8f3372122013-07-18 04:34:14410void PluginServiceImpl::GetInternalPlugins(
[email protected]d7bd3e52013-07-21 04:29:20411 std::vector<WebPluginInfo>* plugins) {
[email protected]29e2fb42013-07-19 01:13:47412 PluginList::Singleton()->GetInternalPlugins(plugins);
[email protected]8f3372122013-07-18 04:34:14413}
414
[email protected]aec5ed52014-06-20 07:51:42415bool PluginServiceImpl::PpapiDevChannelSupported(
416 BrowserContext* browser_context,
417 const GURL& document_url) {
wfh6be06282015-07-20 18:04:02418 return GetContentClient()->browser()->IsPluginAllowedToUseDevChannelAPIs(
419 browser_context, document_url);
[email protected]8ddc6b7c2013-12-12 20:42:06420}
421
[email protected]130757672012-10-24 00:26:19422} // namespace content