mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Add plugin placeholder and policy support (issue #1708)
- Default plugin loading policy can be specified using the new `--plugin-policy=[allow|block|detect]` command-line flag. - Move CefRequestHandler::OnBeforePluginLoad to CefRequestContextHandler and add a new policy argument that supports different actions (allow, block, detect, disable) on a per-plugin-instance basis. - Add CefContextMenuHandler::RunContextMenu for providing a custom context menu implementation. - Add CefResourceBundleHandler::GetDataResourceForScale for returning scaled resources (issue #1272). - Add CefResourceBundle for retrieving resources from the resource bundle (*.pak) files loaded by CEF during startup or via the CefResourceBundleHandler. - Linux: Fix Debug build IO access warning with CefGetMimeType. - cef_unittests: Move the refcounting implementation from TestHandler to subclasses in order to support interface inheritance from subclasses.
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
|
||||
#include "libcef/browser/extensions/extensions_browser_client.h"
|
||||
|
||||
#include "libcef/browser/content_browser_client.h"
|
||||
#include "libcef/browser/browser_context_impl.h"
|
||||
#include "libcef/browser/extensions/component_extension_resource_manager.h"
|
||||
#include "libcef/browser/extensions/extension_system_factory.h"
|
||||
#include "libcef/browser/extensions/extension_web_contents_observer.h"
|
||||
@@ -124,8 +124,7 @@ bool CefExtensionsBrowserClient::AllowCrossRendererResourceLoad(
|
||||
|
||||
PrefService* CefExtensionsBrowserClient::GetPrefServiceForContext(
|
||||
BrowserContext* context) {
|
||||
// TODO(extensions): Do we need a per-context PrefService?
|
||||
return CefContentBrowserClient::Get()->pref_service();
|
||||
return CefBrowserContextImpl::GetForContext(context)->GetPrefs();
|
||||
}
|
||||
|
||||
void CefExtensionsBrowserClient::GetEarlyExtensionPrefsObservers(
|
||||
|
@@ -1,245 +0,0 @@
|
||||
// Copyright 2015 The Chromium Embedded Framework Authors.
|
||||
// Portions copyright 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "libcef/browser/extensions/plugin_info_message_filter.h"
|
||||
|
||||
#include "libcef/common/cef_messages.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/thread_task_runner_handle.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/plugin_service.h"
|
||||
#include "content/public/browser/plugin_service_filter.h"
|
||||
#include "content/public/common/content_constants.h"
|
||||
#include "content/public/common/webplugininfo.h"
|
||||
#include "extensions/browser/guest_view/web_view/web_view_renderer_state.h"
|
||||
#include "extensions/common/constants.h"
|
||||
#include "extensions/common/extension.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
using content::PluginService;
|
||||
using content::WebPluginInfo;
|
||||
|
||||
namespace extensions {
|
||||
|
||||
namespace {
|
||||
|
||||
#if defined(OS_WIN) || defined(OS_MACOSX)
|
||||
// These are the mime-types of plugins which are known to have PPAPI versions.
|
||||
const char* kPepperPluginMimeTypes[] = {
|
||||
"application/pdf",
|
||||
"application/x-google-chrome-pdf",
|
||||
"application/x-nacl",
|
||||
"application/x-pnacl",
|
||||
"application/vnd.chromium.remoting-viewer",
|
||||
"application/x-shockwave-flash",
|
||||
"application/futuresplash",
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
CefPluginInfoMessageFilter::Context::Context(
|
||||
int render_process_id,
|
||||
content::BrowserContext* browser_context)
|
||||
: render_process_id_(render_process_id),
|
||||
resource_context_(browser_context->GetResourceContext()) {
|
||||
}
|
||||
|
||||
CefPluginInfoMessageFilter::Context::~Context() {
|
||||
}
|
||||
|
||||
CefPluginInfoMessageFilter::CefPluginInfoMessageFilter(
|
||||
int render_process_id,
|
||||
content::BrowserContext* browser_context)
|
||||
: BrowserMessageFilter(ExtensionMsgStart),
|
||||
context_(render_process_id, browser_context),
|
||||
main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()),
|
||||
weak_ptr_factory_(this) {
|
||||
}
|
||||
|
||||
bool CefPluginInfoMessageFilter::OnMessageReceived(const IPC::Message& message) {
|
||||
IPC_BEGIN_MESSAGE_MAP(CefPluginInfoMessageFilter, message)
|
||||
IPC_MESSAGE_HANDLER_DELAY_REPLY(CefViewHostMsg_GetPluginInfo,
|
||||
OnGetPluginInfo)
|
||||
IPC_MESSAGE_HANDLER(CefViewHostMsg_IsInternalPluginAvailableForMimeType,
|
||||
OnIsInternalPluginAvailableForMimeType)
|
||||
IPC_MESSAGE_UNHANDLED(return false)
|
||||
IPC_END_MESSAGE_MAP()
|
||||
return true;
|
||||
}
|
||||
|
||||
void CefPluginInfoMessageFilter::OnDestruct() const {
|
||||
const_cast<CefPluginInfoMessageFilter*>(this)->
|
||||
weak_ptr_factory_.InvalidateWeakPtrs();
|
||||
|
||||
// Destroy on the UI thread because we contain a |PrefMember|.
|
||||
content::BrowserThread::DeleteOnUIThread::Destruct(this);
|
||||
}
|
||||
|
||||
CefPluginInfoMessageFilter::~CefPluginInfoMessageFilter() {}
|
||||
|
||||
struct CefPluginInfoMessageFilter::GetPluginInfo_Params {
|
||||
int render_frame_id;
|
||||
GURL url;
|
||||
GURL top_origin_url;
|
||||
std::string mime_type;
|
||||
};
|
||||
|
||||
void CefPluginInfoMessageFilter::OnGetPluginInfo(
|
||||
int render_frame_id,
|
||||
const GURL& url,
|
||||
const GURL& top_origin_url,
|
||||
const std::string& mime_type,
|
||||
IPC::Message* reply_msg) {
|
||||
GetPluginInfo_Params params = {
|
||||
render_frame_id,
|
||||
url,
|
||||
top_origin_url,
|
||||
mime_type
|
||||
};
|
||||
PluginService::GetInstance()->GetPlugins(
|
||||
base::Bind(&CefPluginInfoMessageFilter::PluginsLoaded,
|
||||
weak_ptr_factory_.GetWeakPtr(),
|
||||
params, reply_msg));
|
||||
}
|
||||
|
||||
void CefPluginInfoMessageFilter::PluginsLoaded(
|
||||
const GetPluginInfo_Params& params,
|
||||
IPC::Message* reply_msg,
|
||||
const std::vector<WebPluginInfo>& plugins) {
|
||||
CefViewHostMsg_GetPluginInfo_Output output;
|
||||
// This also fills in |actual_mime_type|.
|
||||
if (context_.FindEnabledPlugin(params.render_frame_id, params.url,
|
||||
params.top_origin_url, params.mime_type,
|
||||
&output.status, &output.plugin,
|
||||
&output.actual_mime_type)) {
|
||||
context_.DecidePluginStatus(params, output.plugin, &output.status);
|
||||
}
|
||||
|
||||
CefViewHostMsg_GetPluginInfo::WriteReplyParams(reply_msg, output);
|
||||
Send(reply_msg);
|
||||
}
|
||||
|
||||
void CefPluginInfoMessageFilter::Context::DecidePluginStatus(
|
||||
const GetPluginInfo_Params& params,
|
||||
const WebPluginInfo& plugin,
|
||||
CefViewHostMsg_GetPluginInfo_Status* status) const {
|
||||
if (plugin.type == WebPluginInfo::PLUGIN_TYPE_NPAPI) {
|
||||
CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
|
||||
// NPAPI plugins are not supported inside <webview> guests.
|
||||
if (extensions::WebViewRendererState::GetInstance()->IsGuest(
|
||||
render_process_id_)) {
|
||||
*status = CefViewHostMsg_GetPluginInfo_Status::kNPAPINotSupported;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the plugin is crashing too much.
|
||||
if (PluginService::GetInstance()->IsPluginUnstable(plugin.path)) {
|
||||
*status = CefViewHostMsg_GetPluginInfo_Status::kUnauthorized;
|
||||
return;
|
||||
}
|
||||
|
||||
if (*status == CefViewHostMsg_GetPluginInfo_Status::kAllowed) {
|
||||
// Allow an embedder of <webview> to block a plugin from being loaded inside
|
||||
// the guest. In order to do this, set the status to 'Unauthorized' here,
|
||||
// and update the status as appropriate depending on the response from the
|
||||
// embedder.
|
||||
if (extensions::WebViewRendererState::GetInstance()->IsGuest(
|
||||
render_process_id_)) {
|
||||
*status = CefViewHostMsg_GetPluginInfo_Status::kUnauthorized;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CefPluginInfoMessageFilter::Context::FindEnabledPlugin(
|
||||
int render_frame_id,
|
||||
const GURL& url,
|
||||
const GURL& top_origin_url,
|
||||
const std::string& mime_type,
|
||||
CefViewHostMsg_GetPluginInfo_Status* status,
|
||||
WebPluginInfo* plugin,
|
||||
std::string* actual_mime_type) const {
|
||||
*status = CefViewHostMsg_GetPluginInfo_Status::kAllowed;
|
||||
|
||||
bool allow_wildcard = true;
|
||||
std::vector<WebPluginInfo> matching_plugins;
|
||||
std::vector<std::string> mime_types;
|
||||
PluginService::GetInstance()->GetPluginInfoArray(
|
||||
url, mime_type, allow_wildcard, &matching_plugins, &mime_types);
|
||||
if (matching_plugins.empty()) {
|
||||
*status = CefViewHostMsg_GetPluginInfo_Status::kNotFound;
|
||||
#if defined(OS_WIN) || defined(OS_MACOSX)
|
||||
if (!PluginService::GetInstance()->NPAPIPluginsSupported()) {
|
||||
// At this point it is not known for sure this is an NPAPI plugin as it
|
||||
// could be a not-yet-installed Pepper plugin. To avoid notifying on
|
||||
// these types, bail early based on a blacklist of pepper mime types.
|
||||
for (auto pepper_mime_type : kPepperPluginMimeTypes)
|
||||
if (pepper_mime_type == mime_type)
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
content::PluginServiceFilter* filter =
|
||||
PluginService::GetInstance()->GetFilter();
|
||||
size_t i = 0;
|
||||
for (; i < matching_plugins.size(); ++i) {
|
||||
if (!filter || filter->IsPluginAvailable(render_process_id_,
|
||||
render_frame_id,
|
||||
resource_context_,
|
||||
url,
|
||||
top_origin_url,
|
||||
&matching_plugins[i])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we broke out of the loop, we have found an enabled plugin.
|
||||
bool enabled = i < matching_plugins.size();
|
||||
if (!enabled) {
|
||||
// Otherwise, we only found disabled plugins, so we take the first one.
|
||||
i = 0;
|
||||
*status = CefViewHostMsg_GetPluginInfo_Status::kDisabled;
|
||||
}
|
||||
|
||||
*plugin = matching_plugins[i];
|
||||
*actual_mime_type = mime_types[i];
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
void CefPluginInfoMessageFilter::OnIsInternalPluginAvailableForMimeType(
|
||||
const std::string& mime_type,
|
||||
bool* is_available,
|
||||
std::vector<base::string16>* additional_param_names,
|
||||
std::vector<base::string16>* additional_param_values) {
|
||||
std::vector<WebPluginInfo> plugins;
|
||||
PluginService::GetInstance()->GetInternalPlugins(&plugins);
|
||||
|
||||
for (size_t i = 0; i < plugins.size(); ++i) {
|
||||
const WebPluginInfo& plugin = plugins[i];
|
||||
const std::vector<content::WebPluginMimeType>& mime_types =
|
||||
plugin.mime_types;
|
||||
for (size_t j = 0; j < mime_types.size(); ++j) {
|
||||
if (mime_types[j].mime_type == mime_type) {
|
||||
// TODO(cef): Maybe allow plugins to be disabled here.
|
||||
*is_available = true;
|
||||
*additional_param_names = mime_types[j].additional_param_names;
|
||||
*additional_param_values = mime_types[j].additional_param_values;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*is_available = false;
|
||||
}
|
||||
|
||||
} // namespace extensions
|
@@ -1,101 +0,0 @@
|
||||
// Copyright 2015 The Chromium Embedded Framework Authors.
|
||||
// Portions copyright 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_LIBCEF_BROWSER_EXTENSIONS_PLUGIN_INFO_MESSAGE_FILTER_H_
|
||||
#define CEF_LIBCEF_BROWSER_EXTENSIONS_PLUGIN_INFO_MESSAGE_FILTER_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/prefs/pref_member.h"
|
||||
#include "base/sequenced_task_runner_helpers.h"
|
||||
#include "content/public/browser/browser_message_filter.h"
|
||||
|
||||
struct CefViewHostMsg_GetPluginInfo_Output;
|
||||
enum class CefViewHostMsg_GetPluginInfo_Status;
|
||||
class GURL;
|
||||
|
||||
namespace content {
|
||||
class BrowserContext;
|
||||
class ResourceContext;
|
||||
struct WebPluginInfo;
|
||||
}
|
||||
|
||||
namespace extensions {
|
||||
|
||||
// This class filters out incoming IPC messages requesting plugin information.
|
||||
class CefPluginInfoMessageFilter : public content::BrowserMessageFilter {
|
||||
public:
|
||||
struct GetPluginInfo_Params;
|
||||
|
||||
// Contains all the information needed by the CefPluginInfoMessageFilter.
|
||||
class Context {
|
||||
public:
|
||||
Context(int render_process_id, content::BrowserContext* browser_context);
|
||||
|
||||
~Context();
|
||||
|
||||
void DecidePluginStatus(
|
||||
const GetPluginInfo_Params& params,
|
||||
const content::WebPluginInfo& plugin,
|
||||
CefViewHostMsg_GetPluginInfo_Status* status) const;
|
||||
bool FindEnabledPlugin(int render_frame_id,
|
||||
const GURL& url,
|
||||
const GURL& top_origin_url,
|
||||
const std::string& mime_type,
|
||||
CefViewHostMsg_GetPluginInfo_Status* status,
|
||||
content::WebPluginInfo* plugin,
|
||||
std::string* actual_mime_type) const;
|
||||
|
||||
private:
|
||||
int render_process_id_;
|
||||
content::ResourceContext* resource_context_;
|
||||
};
|
||||
|
||||
CefPluginInfoMessageFilter(int render_process_id,
|
||||
content::BrowserContext* browser_context);
|
||||
|
||||
// content::BrowserMessageFilter methods:
|
||||
bool OnMessageReceived(const IPC::Message& message) override;
|
||||
void OnDestruct() const override;
|
||||
|
||||
private:
|
||||
friend struct content::BrowserThread::DeleteOnThread<
|
||||
content::BrowserThread::UI>;
|
||||
friend class base::DeleteHelper<CefPluginInfoMessageFilter>;
|
||||
|
||||
~CefPluginInfoMessageFilter() override;
|
||||
|
||||
void OnGetPluginInfo(int render_frame_id,
|
||||
const GURL& url,
|
||||
const GURL& top_origin_url,
|
||||
const std::string& mime_type,
|
||||
IPC::Message* reply_msg);
|
||||
void OnIsInternalPluginAvailableForMimeType(
|
||||
const std::string& mime_type,
|
||||
bool* is_available,
|
||||
std::vector<base::string16>* additional_param_names,
|
||||
std::vector<base::string16>* additional_param_values);
|
||||
|
||||
// |params| wraps the parameters passed to |OnGetPluginInfo|, because
|
||||
// |base::Bind| doesn't support the required arity <http://crbug.com/98542>.
|
||||
void PluginsLoaded(const GetPluginInfo_Params& params,
|
||||
IPC::Message* reply_msg,
|
||||
const std::vector<content::WebPluginInfo>& plugins);
|
||||
|
||||
Context context_;
|
||||
|
||||
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
|
||||
base::WeakPtrFactory<CefPluginInfoMessageFilter> weak_ptr_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefPluginInfoMessageFilter);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_EXTENSIONS_PLUGIN_INFO_MESSAGE_FILTER_H_
|
Reference in New Issue
Block a user