blob: ec071f3b89c16febad73f77a1b17fe864874e371 [file] [log] [blame]
Jeremy Romanb7024742018-06-18 22:00:221// Copyright 2018 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 "content/browser/renderer_host/plugin_registry_impl.h"
6
7#include "base/no_destructor.h"
8#include "content/browser/plugin_service_impl.h"
9#include "content/public/browser/plugin_service_filter.h"
10
11namespace content {
12
13namespace {
14constexpr auto kPluginRefreshThreshold = base::TimeDelta::FromSeconds(3);
15} // namespace
16
17PluginRegistryImpl::PluginRegistryImpl(ResourceContext* resource_context)
18 : resource_context_(resource_context), weak_factory_(this) {}
19
20PluginRegistryImpl::~PluginRegistryImpl() {}
21
22void PluginRegistryImpl::Bind(blink::mojom::PluginRegistryRequest request) {
23 bindings_.AddBinding(this, std::move(request));
24}
25
26void PluginRegistryImpl::GetPlugins(bool refresh,
27 const url::Origin& main_frame_origin,
28 GetPluginsCallback callback) {
29 auto* plugin_service = PluginServiceImpl::GetInstance();
30
31 // Don't refresh if the specified threshold has not been passed. Note that
32 // this check is performed before off-loading to the file thread. The reason
33 // we do this is that some pages tend to request that the list of plugins be
34 // refreshed at an excessive rate. This instigates disk scanning, as the list
35 // is accumulated by doing multiple reads from disk. This effect is
36 // multiplied when we have several pages requesting this operation.
37 if (refresh) {
38 const base::TimeTicks now = base::TimeTicks::Now();
39 if (now - last_plugin_refresh_time_ >= kPluginRefreshThreshold) {
40 // Only refresh if the threshold hasn't been exceeded yet.
41 plugin_service->RefreshPlugins();
42 last_plugin_refresh_time_ = now;
43 }
44 }
45
46 plugin_service->GetPlugins(base::BindOnce(
47 &PluginRegistryImpl::GetPluginsComplete, weak_factory_.GetWeakPtr(),
48 main_frame_origin, std::move(callback)));
49}
50
51void PluginRegistryImpl::GetPluginsComplete(
52 const url::Origin& main_frame_origin,
53 GetPluginsCallback callback,
54 const std::vector<WebPluginInfo>& all_plugins) {
55 PluginServiceFilter* filter = PluginServiceImpl::GetInstance()->GetFilter();
56 std::vector<blink::mojom::PluginInfoPtr> plugins;
57
58 const int child_process_id = -1;
59 const int routing_id = MSG_ROUTING_NONE;
60 // In this loop, copy the WebPluginInfo (and do not use a reference) because
61 // the filter might mutate it.
62 for (WebPluginInfo plugin : all_plugins) {
63 // TODO(crbug.com/621724): Pass an url::Origin instead of a GURL.
64 if (!filter ||
65 filter->IsPluginAvailable(child_process_id, routing_id,
66 resource_context_, main_frame_origin.GetURL(),
67 main_frame_origin, &plugin)) {
68 auto plugin_blink = blink::mojom::PluginInfo::New();
69 plugin_blink->name = plugin.name;
70 plugin_blink->description = plugin.desc;
71 plugin_blink->filename = plugin.path.BaseName();
72 plugin_blink->background_color = plugin.background_color;
73 for (const auto& mime_type : plugin.mime_types) {
74 auto mime_type_blink = blink::mojom::PluginMimeType::New();
75 mime_type_blink->mime_type = mime_type.mime_type;
76 mime_type_blink->description = mime_type.description;
77 mime_type_blink->file_extensions = mime_type.file_extensions;
78 plugin_blink->mime_types.push_back(std::move(mime_type_blink));
79 }
80 plugins.push_back(std::move(plugin_blink));
81 }
82 }
83
84 std::move(callback).Run(std::move(plugins));
85}
86
87} // namespace content