Add PDF extension support (issue #1565)
This commit is contained in:
parent
aefb5ccce8
commit
b7a56d9343
|
@ -289,6 +289,7 @@ if(OS_LINUX)
|
|||
cef.pak
|
||||
cef_100_percent.pak
|
||||
cef_200_percent.pak
|
||||
cef_extensions.pak
|
||||
devtools_resources.pak
|
||||
icudtl.dat
|
||||
locales
|
||||
|
@ -457,6 +458,7 @@ if(OS_WINDOWS)
|
|||
cef.pak
|
||||
cef_100_percent.pak
|
||||
cef_200_percent.pak
|
||||
cef_extensions.pak
|
||||
devtools_resources.pak
|
||||
icudtl.dat
|
||||
locales
|
||||
|
|
136
cef.gyp
136
cef.gyp
|
@ -656,6 +656,7 @@
|
|||
'<(DEPTH)/ui/strings/ui_strings.gyp:ui_strings',
|
||||
'<(DEPTH)/components/components_strings.gyp:components_strings',
|
||||
'<(DEPTH)/content/app/strings/content_strings.gyp:content_strings',
|
||||
'<(DEPTH)/extensions/extensions_strings.gyp:extensions_strings',
|
||||
'cef_strings',
|
||||
],
|
||||
'actions': [
|
||||
|
@ -733,6 +734,59 @@
|
|||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
# Create the pack file for component extension resources.
|
||||
'target_name': 'component_extension_resources',
|
||||
'type': 'none',
|
||||
'actions': [
|
||||
{
|
||||
'action_name': 'component_extension_resources',
|
||||
'variables': {
|
||||
'grit_grd_file': '../chrome/browser/resources/component_extension_resources.grd',
|
||||
},
|
||||
'includes': [ '../build/grit_action.gypi' ],
|
||||
},
|
||||
],
|
||||
'includes': [ '../build/grit_target.gypi' ],
|
||||
'copies': [
|
||||
{
|
||||
'destination': '<(PRODUCT_DIR)',
|
||||
'files': [
|
||||
'<(grit_out_dir)/component_extension_resources.pak'
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
# Combine all extensions-related non-localized pack file resources into a
|
||||
# single CEF pack file. Scaled resources are still in cef_pak.
|
||||
'target_name': 'cef_extensions_pak',
|
||||
'type': 'none',
|
||||
'dependencies': [
|
||||
'<(DEPTH)/extensions/extensions_resources.gyp:extensions_resources',
|
||||
'<(DEPTH)/extensions/extensions_strings.gyp:extensions_strings',
|
||||
'<(DEPTH)/ui/resources/ui_resources.gyp:ui_resources',
|
||||
'component_extension_resources',
|
||||
],
|
||||
'variables': {
|
||||
'make_pack_header_path': 'tools/make_pack_header.py',
|
||||
},
|
||||
'actions': [
|
||||
{
|
||||
'action_name': 'repack_cef_extensions_pack',
|
||||
'variables': {
|
||||
'pak_inputs': [
|
||||
'<(SHARED_INTERMEDIATE_DIR)/extensions/extensions_renderer_resources.pak',
|
||||
'<(SHARED_INTERMEDIATE_DIR)/extensions/extensions_resources.pak',
|
||||
'<(SHARED_INTERMEDIATE_DIR)/ui/resources/webui_resources.pak',
|
||||
'<(grit_out_dir)/component_extension_resources.pak',
|
||||
],
|
||||
'pak_output': '<(PRODUCT_DIR)/cef_extensions.pak',
|
||||
},
|
||||
'includes': [ '../build/repack_action.gypi' ],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
# Combine all non-localized pack file resources into a single CEF pack file.
|
||||
'target_name': 'cef_pak',
|
||||
|
@ -745,6 +799,7 @@
|
|||
'<(DEPTH)/content/browser/devtools/devtools_resources.gyp:devtools_resources',
|
||||
'<(DEPTH)/net/net.gyp:net_resources',
|
||||
'<(DEPTH)/ui/resources/ui_resources.gyp:ui_resources',
|
||||
'cef_extensions_pak',
|
||||
'cef_locales',
|
||||
'cef_resources',
|
||||
],
|
||||
|
@ -773,6 +828,7 @@
|
|||
'<(SHARED_INTERMEDIATE_DIR)/blink/public/resources/blink_image_resources_100_percent.pak',
|
||||
'<(SHARED_INTERMEDIATE_DIR)/components/components_resources_100_percent.pak',
|
||||
'<(SHARED_INTERMEDIATE_DIR)/content/app/resources/content_resources_100_percent.pak',
|
||||
'<(SHARED_INTERMEDIATE_DIR)/extensions/extensions_browser_resources_100_percent.pak',
|
||||
'<(SHARED_INTERMEDIATE_DIR)/ui/resources/ui_resources_100_percent.pak',
|
||||
],
|
||||
'pak_output': '<(PRODUCT_DIR)/cef_100_percent.pak',
|
||||
|
@ -786,6 +842,7 @@
|
|||
'<(SHARED_INTERMEDIATE_DIR)/blink/public/resources/blink_image_resources_200_percent.pak',
|
||||
'<(SHARED_INTERMEDIATE_DIR)/components/components_resources_200_percent.pak',
|
||||
'<(SHARED_INTERMEDIATE_DIR)/content/app/resources/content_resources_200_percent.pak',
|
||||
'<(SHARED_INTERMEDIATE_DIR)/extensions/extensions_browser_resources_200_percent.pak',
|
||||
'<(SHARED_INTERMEDIATE_DIR)/ui/resources/ui_resources_200_percent.pak',
|
||||
],
|
||||
'pak_output': '<(PRODUCT_DIR)/cef_200_percent.pak',
|
||||
|
@ -799,9 +856,14 @@
|
|||
'<(SHARED_INTERMEDIATE_DIR)/blink/grit/devtools_resources.h',
|
||||
'<(SHARED_INTERMEDIATE_DIR)/blink/public/resources/grit/blink_resources.h',
|
||||
'<(SHARED_INTERMEDIATE_DIR)/content/grit/content_resources.h',
|
||||
'<(SHARED_INTERMEDIATE_DIR)/extensions/grit/extensions_browser_resources.h',
|
||||
'<(SHARED_INTERMEDIATE_DIR)/extensions/grit/extensions_renderer_resources.h',
|
||||
'<(SHARED_INTERMEDIATE_DIR)/extensions/grit/extensions_resources.h',
|
||||
'<(SHARED_INTERMEDIATE_DIR)/net/grit/net_resources.h',
|
||||
'<(SHARED_INTERMEDIATE_DIR)/ui/resources/grit/ui_resources.h',
|
||||
'<(SHARED_INTERMEDIATE_DIR)/ui/resources/grit/webui_resources.h',
|
||||
'<(grit_out_dir)/grit/cef_resources.h',
|
||||
'<(grit_out_dir)/grit/component_extension_resources.h',
|
||||
],
|
||||
},
|
||||
'inputs': [
|
||||
|
@ -820,6 +882,7 @@
|
|||
'header_inputs': [
|
||||
'<(SHARED_INTERMEDIATE_DIR)/components/strings/grit/components_strings.h',
|
||||
'<(SHARED_INTERMEDIATE_DIR)/content/app/strings/grit/content_strings.h',
|
||||
'<(SHARED_INTERMEDIATE_DIR)/extensions/strings/grit/extensions_strings.h',
|
||||
'<(SHARED_INTERMEDIATE_DIR)/ui/strings/grit/ui_strings.h',
|
||||
'<(grit_out_dir)/grit/cef_strings.h',
|
||||
],
|
||||
|
@ -874,16 +937,19 @@
|
|||
# zip_analyzer_results.h via chrome_utility_messages.h
|
||||
'<(DEPTH)/chrome/chrome.gyp:safe_browsing_proto',
|
||||
'<(DEPTH)/components/components.gyp:crash_component_breakpad_mac_to_be_deleted',
|
||||
'<(DEPTH)/components/components.gyp:crx_file',
|
||||
'<(DEPTH)/components/components.gyp:devtools_discovery',
|
||||
'<(DEPTH)/components/components.gyp:devtools_http_handler',
|
||||
'<(DEPTH)/components/components.gyp:keyed_service_content',
|
||||
'<(DEPTH)/components/components.gyp:keyed_service_core',
|
||||
'<(DEPTH)/components/components.gyp:navigation_interception',
|
||||
'<(DEPTH)/components/components.gyp:pdf_browser',
|
||||
'<(DEPTH)/components/components.gyp:pdf_renderer',
|
||||
'<(DEPTH)/components/components.gyp:plugins_renderer',
|
||||
'<(DEPTH)/components/components.gyp:pref_registry',
|
||||
'<(DEPTH)/components/components.gyp:printing_common',
|
||||
'<(DEPTH)/components/components.gyp:printing_renderer',
|
||||
'<(DEPTH)/components/components.gyp:update_client',
|
||||
'<(DEPTH)/components/components.gyp:user_prefs',
|
||||
'<(DEPTH)/components/components.gyp:web_cache_renderer',
|
||||
'<(DEPTH)/content/content.gyp:content_app_both',
|
||||
|
@ -896,6 +962,14 @@
|
|||
'<(DEPTH)/content/content.gyp:content_resources',
|
||||
'<(DEPTH)/content/content.gyp:content_utility',
|
||||
'<(DEPTH)/crypto/crypto.gyp:crypto',
|
||||
'<(DEPTH)/device/core/core.gyp:device_core',
|
||||
'<(DEPTH)/device/hid/hid.gyp:device_hid',
|
||||
'<(DEPTH)/extensions/browser/api/api_registration.gyp:extensions_api_registration',
|
||||
'<(DEPTH)/extensions/common/api/api.gyp:extensions_api',
|
||||
'<(DEPTH)/extensions/extensions.gyp:extensions_browser',
|
||||
'<(DEPTH)/extensions/extensions.gyp:extensions_renderer',
|
||||
'<(DEPTH)/extensions/extensions.gyp:extensions_utility',
|
||||
'<(DEPTH)/extensions/extensions_resources.gyp:extensions_resources',
|
||||
'<(DEPTH)/gpu/gpu.gyp:gpu',
|
||||
'<(DEPTH)/ipc/ipc.gyp:ipc',
|
||||
'<(DEPTH)/media/blink/media_blink.gyp:media_blink',
|
||||
|
@ -903,6 +977,7 @@
|
|||
'<(DEPTH)/net/net.gyp:net',
|
||||
'<(DEPTH)/net/net.gyp:net_browser_services',
|
||||
'<(DEPTH)/net/net.gyp:net_with_v8',
|
||||
'<(DEPTH)/pdf/pdf.gyp:pdf',
|
||||
'<(DEPTH)/skia/skia.gyp:skia',
|
||||
'<(DEPTH)/storage/storage_browser.gyp:storage',
|
||||
'<(DEPTH)/sync/sync.gyp:sync',
|
||||
|
@ -917,6 +992,9 @@
|
|||
'<(DEPTH)/v8/tools/gyp/v8.gyp:v8',
|
||||
# Necessary to generate the grit include files.
|
||||
'cef_pak',
|
||||
# Necessary to generate API bindings for extensions.
|
||||
'libcef/browser/extensions/api/api_registration.gyp:cef_api_registration',
|
||||
'libcef/common/extensions/api/api.gyp:cef_api',
|
||||
],
|
||||
'sources': [
|
||||
'<@(includes_common)',
|
||||
|
@ -966,6 +1044,36 @@
|
|||
'libcef/browser/download_item_impl.h',
|
||||
'libcef/browser/download_manager_delegate.cc',
|
||||
'libcef/browser/download_manager_delegate.h',
|
||||
'libcef/browser/extensions/api/streams_private/streams_private_api.cc',
|
||||
'libcef/browser/extensions/api/streams_private/streams_private_api.h',
|
||||
'libcef/browser/extensions/browser_context_keyed_service_factories.cc',
|
||||
'libcef/browser/extensions/browser_context_keyed_service_factories.h',
|
||||
'libcef/browser/extensions/browser_extensions_util.cc',
|
||||
'libcef/browser/extensions/browser_extensions_util.h',
|
||||
'libcef/browser/extensions/component_extension_resource_manager.cc',
|
||||
'libcef/browser/extensions/component_extension_resource_manager.h',
|
||||
'libcef/browser/extensions/event_router_forwarder.cc',
|
||||
'libcef/browser/extensions/event_router_forwarder.h',
|
||||
'libcef/browser/extensions/extensions_api_client.cc',
|
||||
'libcef/browser/extensions/extensions_api_client.h',
|
||||
'libcef/browser/extensions/extensions_browser_client.cc',
|
||||
'libcef/browser/extensions/extensions_browser_client.h',
|
||||
'libcef/browser/extensions/extension_system.cc',
|
||||
'libcef/browser/extensions/extension_system.h',
|
||||
'libcef/browser/extensions/extension_system_factory.cc',
|
||||
'libcef/browser/extensions/extension_system_factory.h',
|
||||
'libcef/browser/extensions/extension_web_contents_observer.cc',
|
||||
'libcef/browser/extensions/extension_web_contents_observer.h',
|
||||
'libcef/browser/extensions/mime_handler_view_guest_delegate.cc',
|
||||
'libcef/browser/extensions/mime_handler_view_guest_delegate.h',
|
||||
'libcef/browser/extensions/pdf_extension_util.cc',
|
||||
'libcef/browser/extensions/pdf_extension_util.h',
|
||||
'libcef/browser/extensions/pdf_web_contents_helper_client.cc',
|
||||
'libcef/browser/extensions/pdf_web_contents_helper_client.h',
|
||||
'libcef/browser/extensions/plugin_info_message_filter.cc',
|
||||
'libcef/browser/extensions/plugin_info_message_filter.h',
|
||||
'libcef/browser/extensions/url_request_util.cc',
|
||||
'libcef/browser/extensions/url_request_util.h',
|
||||
'libcef/browser/frame_host_impl.cc',
|
||||
'libcef/browser/frame_host_impl.h',
|
||||
'libcef/browser/geolocation_impl.cc',
|
||||
|
@ -1074,6 +1182,10 @@
|
|||
'libcef/common/crash_reporter_client.h',
|
||||
'libcef/common/drag_data_impl.cc',
|
||||
'libcef/common/drag_data_impl.h',
|
||||
'libcef/common/extensions/extensions_client.cc',
|
||||
'libcef/common/extensions/extensions_client.h',
|
||||
'libcef/common/extensions/extensions_util.cc',
|
||||
'libcef/common/extensions/extensions_util.h',
|
||||
'libcef/common/http_header_utils.cc',
|
||||
'libcef/common/http_header_utils.h',
|
||||
'libcef/common/json_impl.cc',
|
||||
|
@ -1123,10 +1235,15 @@
|
|||
'libcef/renderer/dom_document_impl.h',
|
||||
'libcef/renderer/dom_node_impl.cc',
|
||||
'libcef/renderer/dom_node_impl.h',
|
||||
'libcef/renderer/extensions/extensions_renderer_client.cc',
|
||||
'libcef/renderer/extensions/extensions_renderer_client.h',
|
||||
'libcef/renderer/extensions/print_web_view_helper_delegate.cc',
|
||||
'libcef/renderer/extensions/print_web_view_helper_delegate.h',
|
||||
'libcef/renderer/frame_impl.cc',
|
||||
'libcef/renderer/frame_impl.h',
|
||||
'libcef/renderer/pepper/pepper_helper.cc',
|
||||
'libcef/renderer/pepper/pepper_helper.h',
|
||||
'libcef/renderer/pepper/pepper_uma_host.cc',
|
||||
'libcef/renderer/pepper/renderer_pepper_host_factory.cc',
|
||||
'libcef/renderer/pepper/renderer_pepper_host_factory.h',
|
||||
'libcef/renderer/render_frame_observer.cc',
|
||||
|
@ -1185,8 +1302,6 @@
|
|||
'<(DEPTH)/chrome/browser/printing/printer_query.h',
|
||||
'<(DEPTH)/chrome/common/extensions/extension_constants.cc',
|
||||
'<(DEPTH)/chrome/common/extensions/extension_constants.h',
|
||||
'<(DEPTH)/extensions/common/constants.cc',
|
||||
'<(DEPTH)/extensions/common/constants.h',
|
||||
# Include header for stub creation (BrowserProcess) so print_job_worker can
|
||||
# determine the current locale.
|
||||
'<(DEPTH)/chrome/browser/browser_process.cc',
|
||||
|
@ -1258,13 +1373,21 @@
|
|||
# Include sources required by chrome_utility_messages.h.
|
||||
'<(DEPTH)/chrome/common/safe_browsing/zip_analyzer_results.h',
|
||||
'<(DEPTH)/chrome/common/safe_browsing/zip_analyzer_results.cc',
|
||||
# Include sources for pepper PDF support.
|
||||
'<(DEPTH)/chrome/child/pdf_child_init.cc',
|
||||
'<(DEPTH)/chrome/child/pdf_child_init.h',
|
||||
'<(DEPTH)/chrome/renderer/pepper/chrome_pdf_print_client.cc',
|
||||
'<(DEPTH)/chrome/renderer/pepper/chrome_pdf_print_client.h',
|
||||
# Include sources for extensions support.
|
||||
'<(DEPTH)/chrome/common/pepper_permission_util.cc',
|
||||
'<(DEPTH)/chrome/common/pepper_permission_util.h',
|
||||
'<(DEPTH)/extensions/shell/browser/shell_display_info_provider.cc',
|
||||
'<(DEPTH)/extensions/shell/browser/shell_display_info_provider.h',
|
||||
'<(DEPTH)/extensions/shell/browser/shell_web_contents_modal_dialog_manager.cc',
|
||||
'<(grit_out_dir)/grit/component_extension_resources_map.cc',
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="win"', {
|
||||
'dependencies': [
|
||||
# For printing using PDF.
|
||||
'<(DEPTH)/pdf/pdf.gyp:pdf',
|
||||
],
|
||||
'sources': [
|
||||
'<@(includes_win)',
|
||||
'libcef/browser/browser_host_impl_win.cc',
|
||||
|
@ -1363,6 +1486,7 @@
|
|||
'<(PRODUCT_DIR)/cef.pak',
|
||||
'<(PRODUCT_DIR)/cef_100_percent.pak',
|
||||
'<(PRODUCT_DIR)/cef_200_percent.pak',
|
||||
'<(PRODUCT_DIR)/cef_extensions.pak',
|
||||
'<(PRODUCT_DIR)/devtools_resources.pak',
|
||||
'<(PRODUCT_DIR)/icudtl.dat',
|
||||
'<(PRODUCT_DIR)/natives_blob.bin',
|
||||
|
|
|
@ -214,6 +214,8 @@
|
|||
'tests/cefclient/resources/logo.png',
|
||||
'tests/cefclient/resources/osr_test.html',
|
||||
'tests/cefclient/resources/other_tests.html',
|
||||
'tests/cefclient/resources/pdf.html',
|
||||
'tests/cefclient/resources/pdf.pdf',
|
||||
'tests/cefclient/resources/performance.html',
|
||||
'tests/cefclient/resources/performance2.html',
|
||||
'tests/cefclient/resources/transparency.html',
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#include "libcef/browser/browser_context.h"
|
||||
#include "libcef/browser/content_browser_client.h"
|
||||
#include "libcef/browser/extensions/extension_system.h"
|
||||
#include "libcef/common/extensions/extensions_util.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "components/keyed_service/content/browser_context_dependency_manager.h"
|
||||
|
@ -15,16 +17,7 @@ base::AtomicRefCount CefBrowserContext::DebugObjCt = 0;
|
|||
#endif
|
||||
|
||||
CefBrowserContext::CefBrowserContext()
|
||||
: resource_context_(new CefResourceContext) {
|
||||
BrowserContextDependencyManager::GetInstance()->CreateBrowserContextServices(
|
||||
this);
|
||||
|
||||
// Spell checking support and possibly other subsystems retrieve the
|
||||
// PrefService associated with a BrowserContext via UserPrefs::Get().
|
||||
PrefService* pref_service = CefContentBrowserClient::Get()->pref_service();
|
||||
DCHECK(pref_service);
|
||||
user_prefs::UserPrefs::Set(this, pref_service);
|
||||
|
||||
: extension_system_(NULL) {
|
||||
#ifndef NDEBUG
|
||||
base::AtomicRefCountInc(&DebugObjCt);
|
||||
#endif
|
||||
|
@ -47,6 +40,33 @@ CefBrowserContext::~CefBrowserContext() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void CefBrowserContext::Initialize() {
|
||||
const bool extensions_enabled = extensions::ExtensionsEnabled();
|
||||
if (extensions_enabled) {
|
||||
// Create the custom ExtensionSystem first because other KeyedServices
|
||||
// depend on it.
|
||||
extension_system_ = static_cast<extensions::CefExtensionSystem*>(
|
||||
extensions::ExtensionSystem::Get(this));
|
||||
extension_system_->InitForRegularProfile(true);
|
||||
}
|
||||
|
||||
resource_context_.reset(new CefResourceContext(
|
||||
IsOffTheRecord(),
|
||||
extensions_enabled ? extension_system_->info_map() : NULL));
|
||||
|
||||
BrowserContextDependencyManager::GetInstance()->CreateBrowserContextServices(
|
||||
this);
|
||||
|
||||
// Spell checking support and possibly other subsystems retrieve the
|
||||
// PrefService associated with a BrowserContext via UserPrefs::Get().
|
||||
PrefService* pref_service = CefContentBrowserClient::Get()->pref_service();
|
||||
DCHECK(pref_service);
|
||||
user_prefs::UserPrefs::Set(this, pref_service);
|
||||
|
||||
if (extensions_enabled)
|
||||
extension_system_->Init();
|
||||
}
|
||||
|
||||
content::ResourceContext* CefBrowserContext::GetResourceContext() {
|
||||
return resource_context_.get();
|
||||
}
|
||||
|
|
|
@ -104,6 +104,10 @@
|
|||
// CefURLRequestContextGetter* destruction.
|
||||
*/
|
||||
|
||||
namespace extensions {
|
||||
class CefExtensionSystem;
|
||||
}
|
||||
|
||||
// Main entry point for configuring behavior on a per-browser basis. An instance
|
||||
// of this class is passed to WebContents::Create in CefBrowserHostImpl::
|
||||
// CreateInternal. Only accessed on the UI thread unless otherwise indicated.
|
||||
|
@ -114,13 +118,12 @@ class CefBrowserContext
|
|||
public:
|
||||
CefBrowserContext();
|
||||
|
||||
// Must be called immediately after this object is created.
|
||||
virtual void Initialize();
|
||||
|
||||
// BrowserContext methods.
|
||||
content::ResourceContext* GetResourceContext() override;
|
||||
|
||||
// Returns true if this is a CefBrowserContextProxy object. Safe to call from
|
||||
// any thread.
|
||||
virtual bool IsProxy() const = 0;
|
||||
|
||||
// Returns the settings associated with this object. Safe to call from any
|
||||
// thread.
|
||||
virtual const CefRequestContextSettings& GetSettings() const = 0;
|
||||
|
@ -140,7 +143,10 @@ class CefBrowserContext
|
|||
content::URLRequestInterceptorScopedVector request_interceptors) = 0;
|
||||
|
||||
CefResourceContext* resource_context() const {
|
||||
return resource_context_.get();
|
||||
return resource_context_.get();
|
||||
}
|
||||
extensions::CefExtensionSystem* extension_system() const {
|
||||
return extension_system_;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
@ -159,6 +165,9 @@ class CefBrowserContext
|
|||
|
||||
scoped_ptr<CefResourceContext> resource_context_;
|
||||
|
||||
// Owned by the KeyedService system.
|
||||
extensions::CefExtensionSystem* extension_system_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefBrowserContext);
|
||||
};
|
||||
|
||||
|
|
|
@ -6,18 +6,21 @@
|
|||
|
||||
#include <map>
|
||||
|
||||
#include "libcef/browser/browser_context_proxy.h"
|
||||
#include "libcef/browser/content_browser_client.h"
|
||||
#include "libcef/browser/context.h"
|
||||
#include "libcef/browser/download_manager_delegate.h"
|
||||
#include "libcef/browser/permission_manager.h"
|
||||
#include "libcef/browser/ssl_host_state_delegate.h"
|
||||
#include "libcef/browser/thread_util.h"
|
||||
#include "libcef/common/extensions/extensions_util.h"
|
||||
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/lazy_instance.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
#include "chrome/browser/net/proxy_service_factory.h"
|
||||
#include "components/guest_view/browser/guest_view_manager.h"
|
||||
#include "content/public/browser/download_manager.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/storage_partition.h"
|
||||
|
@ -27,15 +30,64 @@ using content::BrowserThread;
|
|||
|
||||
namespace {
|
||||
|
||||
// Manages the global mapping of cache path to Impl instance.
|
||||
// Manages the global list of Impl instances.
|
||||
class ImplManager {
|
||||
public:
|
||||
typedef std::vector<CefBrowserContextImpl*> Vector;
|
||||
|
||||
ImplManager() {}
|
||||
~ImplManager() {
|
||||
DCHECK(all_.empty());
|
||||
DCHECK(map_.empty());
|
||||
}
|
||||
|
||||
CefBrowserContextImpl* GetImpl(const base::FilePath& path) {
|
||||
void AddImpl(CefBrowserContextImpl* impl) {
|
||||
CEF_REQUIRE_UIT();
|
||||
DCHECK(!IsValidImpl(impl));
|
||||
all_.push_back(impl);
|
||||
}
|
||||
|
||||
void RemoveImpl(CefBrowserContextImpl* impl, const base::FilePath& path) {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
Vector::iterator it = GetImplPos(impl);
|
||||
DCHECK(it != all_.end());
|
||||
all_.erase(it);
|
||||
|
||||
if (!path.empty()) {
|
||||
PathMap::iterator it = map_.find(path);
|
||||
DCHECK(it != map_.end());
|
||||
if (it != map_.end())
|
||||
map_.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
bool IsValidImpl(const CefBrowserContextImpl* impl) {
|
||||
CEF_REQUIRE_UIT();
|
||||
return GetImplPos(impl) != all_.end();
|
||||
}
|
||||
|
||||
CefBrowserContextImpl* GetImplForContext(
|
||||
const content::BrowserContext* context) {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
Vector::iterator it = all_.begin();
|
||||
for (; it != all_.end(); ++it) {
|
||||
if (*it == context || (*it)->HasProxy(context))
|
||||
return *it;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void SetImplPath(CefBrowserContextImpl* impl, const base::FilePath& path) {
|
||||
CEF_REQUIRE_UIT();
|
||||
DCHECK(!path.empty());
|
||||
DCHECK(IsValidImpl(impl));
|
||||
DCHECK(GetImplForPath(path) == NULL);
|
||||
map_.insert(std::make_pair(path, impl));
|
||||
}
|
||||
|
||||
CefBrowserContextImpl* GetImplForPath(const base::FilePath& path) {
|
||||
CEF_REQUIRE_UIT();
|
||||
DCHECK(!path.empty());
|
||||
PathMap::const_iterator it = map_.find(path);
|
||||
|
@ -44,26 +96,23 @@ class ImplManager {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void AddImpl(const base::FilePath& path, CefBrowserContextImpl* impl) {
|
||||
CEF_REQUIRE_UIT();
|
||||
DCHECK(!path.empty());
|
||||
DCHECK(GetImpl(path) == NULL);
|
||||
map_.insert(std::make_pair(path, impl));
|
||||
}
|
||||
|
||||
void RemoveImpl(const base::FilePath& path) {
|
||||
CEF_REQUIRE_UIT();
|
||||
DCHECK(!path.empty());
|
||||
PathMap::iterator it = map_.find(path);
|
||||
DCHECK(it != map_.end());
|
||||
if (it != map_.end())
|
||||
map_.erase(it);
|
||||
}
|
||||
const Vector GetAllImpl() const { return all_; }
|
||||
|
||||
private:
|
||||
Vector::iterator GetImplPos(const CefBrowserContextImpl* impl) {
|
||||
Vector::iterator it = all_.begin();
|
||||
for (; it != all_.end(); ++it) {
|
||||
if (*it == impl)
|
||||
return it;
|
||||
}
|
||||
return all_.end();
|
||||
}
|
||||
|
||||
typedef std::map<base::FilePath, CefBrowserContextImpl*> PathMap;
|
||||
PathMap map_;
|
||||
|
||||
Vector all_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ImplManager);
|
||||
};
|
||||
|
||||
|
@ -74,6 +123,7 @@ base::LazyInstance<ImplManager> g_manager = LAZY_INSTANCE_INITIALIZER;
|
|||
CefBrowserContextImpl::CefBrowserContextImpl(
|
||||
const CefRequestContextSettings& settings)
|
||||
: settings_(settings) {
|
||||
g_manager.Get().AddImpl(this);
|
||||
}
|
||||
|
||||
CefBrowserContextImpl::~CefBrowserContextImpl() {
|
||||
|
@ -84,8 +134,7 @@ CefBrowserContextImpl::~CefBrowserContextImpl() {
|
|||
if (download_manager_delegate_.get())
|
||||
download_manager_delegate_.reset(NULL);
|
||||
|
||||
if (!cache_path_.empty())
|
||||
g_manager.Get().RemoveImpl(cache_path_);
|
||||
g_manager.Get().RemoveImpl(this, cache_path_);
|
||||
}
|
||||
|
||||
void CefBrowserContextImpl::Initialize() {
|
||||
|
@ -102,7 +151,7 @@ void CefBrowserContextImpl::Initialize() {
|
|||
}
|
||||
|
||||
if (!cache_path_.empty())
|
||||
g_manager.Get().AddImpl(cache_path_, this);
|
||||
g_manager.Get().SetImplPath(this, cache_path_);
|
||||
|
||||
if (settings_.accept_language_list.length == 0) {
|
||||
// Use the global language list setting.
|
||||
|
@ -110,6 +159,8 @@ void CefBrowserContextImpl::Initialize() {
|
|||
CefString(&CefContext::Get()->settings().accept_language_list);
|
||||
}
|
||||
|
||||
CefBrowserContext::Initialize();
|
||||
|
||||
// Initialize proxy configuration tracker.
|
||||
pref_proxy_config_tracker_.reset(
|
||||
ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState(
|
||||
|
@ -123,10 +174,52 @@ void CefBrowserContextImpl::Initialize() {
|
|||
DCHECK(url_request_getter_.get());
|
||||
}
|
||||
|
||||
void CefBrowserContextImpl::AddProxy(const CefBrowserContextProxy* proxy) {
|
||||
CEF_REQUIRE_UIT();
|
||||
DCHECK(!HasProxy(proxy));
|
||||
proxy_list_.push_back(proxy);
|
||||
}
|
||||
|
||||
void CefBrowserContextImpl::RemoveProxy(const CefBrowserContextProxy* proxy) {
|
||||
CEF_REQUIRE_UIT();
|
||||
bool found = false;
|
||||
ProxyList::iterator it = proxy_list_.begin();
|
||||
for (; it != proxy_list_.end(); ++it) {
|
||||
if (*it == proxy) {
|
||||
proxy_list_.erase(it);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
DCHECK(found);
|
||||
}
|
||||
|
||||
bool CefBrowserContextImpl::HasProxy(
|
||||
const content::BrowserContext* context) const {
|
||||
CEF_REQUIRE_UIT();
|
||||
ProxyList::const_iterator it = proxy_list_.begin();
|
||||
for (; it != proxy_list_.end(); ++it) {
|
||||
if (*it == context)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
scoped_refptr<CefBrowserContextImpl> CefBrowserContextImpl::GetForCachePath(
|
||||
const base::FilePath& cache_path) {
|
||||
return g_manager.Get().GetImpl(cache_path);
|
||||
return g_manager.Get().GetImplForPath(cache_path);
|
||||
}
|
||||
|
||||
// static
|
||||
CefRefPtr<CefBrowserContextImpl> CefBrowserContextImpl::GetForContext(
|
||||
content::BrowserContext* context) {
|
||||
return g_manager.Get().GetImplForContext(context);
|
||||
}
|
||||
|
||||
// static
|
||||
std::vector<CefBrowserContextImpl*> CefBrowserContextImpl::GetAll() {
|
||||
return g_manager.Get().GetAllImpl();
|
||||
}
|
||||
|
||||
base::FilePath CefBrowserContextImpl::GetPath() const {
|
||||
|
@ -181,7 +274,8 @@ net::URLRequestContextGetter*
|
|||
}
|
||||
|
||||
content::BrowserPluginGuestManager* CefBrowserContextImpl::GetGuestManager() {
|
||||
return NULL;
|
||||
DCHECK(extensions::ExtensionsEnabled());
|
||||
return guest_view::GuestViewManager::FromBrowserContext(this);
|
||||
}
|
||||
|
||||
storage::SpecialStoragePolicy*
|
||||
|
@ -207,10 +301,6 @@ content::PermissionManager* CefBrowserContextImpl::GetPermissionManager() {
|
|||
return permission_manager_.get();
|
||||
}
|
||||
|
||||
bool CefBrowserContextImpl::IsProxy() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
const CefRequestContextSettings& CefBrowserContextImpl::GetSettings() const {
|
||||
return settings_;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ class DownloadManagerDelegate;
|
|||
class SpeechRecognitionPreferences;
|
||||
}
|
||||
|
||||
class CefBrowserContextProxy;
|
||||
class CefDownloadManagerDelegate;
|
||||
class CefSSLHostStateDelegate;
|
||||
|
||||
|
@ -36,8 +37,20 @@ class CefBrowserContextImpl : public CefBrowserContext {
|
|||
static scoped_refptr<CefBrowserContextImpl> GetForCachePath(
|
||||
const base::FilePath& cache_path);
|
||||
|
||||
// Returns the underlying CefBrowserContextImpl if any.
|
||||
static CefRefPtr<CefBrowserContextImpl> GetForContext(
|
||||
content::BrowserContext* context);
|
||||
|
||||
// Returns all existing CefBrowserContextImpl.
|
||||
static std::vector<CefBrowserContextImpl*> GetAll();
|
||||
|
||||
// Must be called immediately after this object is created.
|
||||
void Initialize();
|
||||
void Initialize() override;
|
||||
|
||||
// Track associated proxy objects.
|
||||
void AddProxy(const CefBrowserContextProxy* proxy);
|
||||
void RemoveProxy(const CefBrowserContextProxy* proxy);
|
||||
bool HasProxy(const content::BrowserContext* context) const;
|
||||
|
||||
// BrowserContext methods.
|
||||
base::FilePath GetPath() const override;
|
||||
|
@ -62,7 +75,6 @@ class CefBrowserContextImpl : public CefBrowserContext {
|
|||
content::PermissionManager* GetPermissionManager() override;
|
||||
|
||||
// CefBrowserContext methods.
|
||||
bool IsProxy() const override;
|
||||
const CefRequestContextSettings& GetSettings() const override;
|
||||
CefRefPtr<CefRequestContextHandler> GetHandler() const override;
|
||||
net::URLRequestContextGetter* CreateRequestContext(
|
||||
|
@ -93,6 +105,10 @@ class CefBrowserContextImpl : public CefBrowserContext {
|
|||
CefRequestContextSettings settings_;
|
||||
base::FilePath cache_path_;
|
||||
|
||||
// Not owned by this class.
|
||||
typedef std::vector<const CefBrowserContextProxy*> ProxyList;
|
||||
ProxyList proxy_list_;
|
||||
|
||||
scoped_ptr<PrefProxyConfigTracker> pref_proxy_config_tracker_;
|
||||
|
||||
scoped_ptr<CefDownloadManagerDelegate> download_manager_delegate_;
|
||||
|
|
|
@ -19,9 +19,11 @@ CefBrowserContextProxy::CefBrowserContextProxy(
|
|||
parent_(parent) {
|
||||
DCHECK(handler_.get());
|
||||
DCHECK(parent_.get());
|
||||
parent_->AddProxy(this);
|
||||
}
|
||||
|
||||
CefBrowserContextProxy::~CefBrowserContextProxy() {
|
||||
parent_->RemoveProxy(this);
|
||||
}
|
||||
|
||||
base::FilePath CefBrowserContextProxy::GetPath() const {
|
||||
|
@ -99,10 +101,6 @@ content::PermissionManager* CefBrowserContextProxy::GetPermissionManager() {
|
|||
return parent_->GetPermissionManager();
|
||||
}
|
||||
|
||||
bool CefBrowserContextProxy::IsProxy() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
const CefRequestContextSettings& CefBrowserContextProxy::GetSettings() const {
|
||||
return parent_->GetSettings();
|
||||
}
|
||||
|
|
|
@ -52,7 +52,6 @@ class CefBrowserContextProxy : public CefBrowserContext {
|
|||
content::PermissionManager* GetPermissionManager() override;
|
||||
|
||||
// CefBrowserContext methods.
|
||||
bool IsProxy() const override;
|
||||
const CefRequestContextSettings& GetSettings() const override;
|
||||
CefRefPtr<CefRequestContextHandler> GetHandler() const override;
|
||||
net::URLRequestContextGetter* CreateRequestContext(
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "libcef/browser/context.h"
|
||||
#include "libcef/browser/devtools_delegate.h"
|
||||
#include "libcef/browser/devtools_frontend.h"
|
||||
#include "libcef/browser/extensions/browser_extensions_util.h"
|
||||
#include "libcef/browser/media_capture_devices_dispatcher.h"
|
||||
#include "libcef/browser/navigate_params.h"
|
||||
#include "libcef/browser/navigation_entry_impl.h"
|
||||
|
@ -28,6 +29,7 @@
|
|||
#include "libcef/common/cef_messages.h"
|
||||
#include "libcef/common/cef_switches.h"
|
||||
#include "libcef/common/drag_data_impl.h"
|
||||
#include "libcef/common/extensions/extensions_util.h"
|
||||
#include "libcef/common/http_header_utils.h"
|
||||
#include "libcef/common/main_delegate.h"
|
||||
#include "libcef/common/process_message_impl.h"
|
||||
|
@ -73,6 +75,63 @@
|
|||
|
||||
namespace {
|
||||
|
||||
// Manages the global list of Impl instances.
|
||||
class ImplManager {
|
||||
public:
|
||||
typedef std::vector<CefBrowserHostImpl*> Vector;
|
||||
|
||||
ImplManager() {}
|
||||
~ImplManager() {
|
||||
DCHECK(all_.empty());
|
||||
}
|
||||
|
||||
void AddImpl(CefBrowserHostImpl* impl) {
|
||||
CEF_REQUIRE_UIT();
|
||||
DCHECK(!IsValidImpl(impl));
|
||||
all_.push_back(impl);
|
||||
}
|
||||
|
||||
void RemoveImpl(CefBrowserHostImpl* impl) {
|
||||
CEF_REQUIRE_UIT();
|
||||
Vector::iterator it = GetImplPos(impl);
|
||||
DCHECK(it != all_.end());
|
||||
all_.erase(it);
|
||||
}
|
||||
|
||||
bool IsValidImpl(const CefBrowserHostImpl* impl) {
|
||||
CEF_REQUIRE_UIT();
|
||||
return GetImplPos(impl) != all_.end();
|
||||
}
|
||||
|
||||
CefBrowserHostImpl* GetImplForWebContents(
|
||||
const content::WebContents* web_contents) {
|
||||
CEF_REQUIRE_UIT();
|
||||
Vector::const_iterator it = all_.begin();
|
||||
for (; it != all_.end(); ++it) {
|
||||
if ((*it)->web_contents() == web_contents)
|
||||
return *it;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
Vector::iterator GetImplPos(const CefBrowserHostImpl* impl) {
|
||||
Vector::iterator it = all_.begin();
|
||||
for (; it != all_.end(); ++it) {
|
||||
if (*it == impl)
|
||||
return it;
|
||||
}
|
||||
return all_.end();
|
||||
}
|
||||
|
||||
Vector all_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ImplManager);
|
||||
};
|
||||
|
||||
base::LazyInstance<ImplManager> g_manager = LAZY_INSTANCE_INITIALIZER;
|
||||
|
||||
|
||||
class CreateBrowserHelper {
|
||||
public:
|
||||
CreateBrowserHelper(const CefWindowInfo& windowInfo,
|
||||
|
@ -520,7 +579,7 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::GetBrowserForHost(
|
|||
content::WebContents* web_contents =
|
||||
content::WebContents::FromRenderViewHost(host);
|
||||
if (web_contents)
|
||||
return static_cast<CefBrowserHostImpl*>(web_contents->GetDelegate());
|
||||
return GetBrowserForContents(web_contents);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -533,21 +592,20 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::GetBrowserForHost(
|
|||
content::WebContents::FromRenderFrameHost(
|
||||
const_cast<content::RenderFrameHost*>(host));
|
||||
if (web_contents)
|
||||
return static_cast<CefBrowserHostImpl*>(web_contents->GetDelegate());
|
||||
return GetBrowserForContents(web_contents);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// static
|
||||
CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::GetBrowserForContents(
|
||||
content::WebContents* contents) {
|
||||
const content::WebContents* contents) {
|
||||
DCHECK(contents);
|
||||
CEF_REQUIRE_UIT();
|
||||
return static_cast<CefBrowserHostImpl*>(contents->GetDelegate());
|
||||
return g_manager.Get().GetImplForWebContents(contents);
|
||||
}
|
||||
|
||||
// static
|
||||
CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::GetBrowserForRequest(
|
||||
net::URLRequest* request) {
|
||||
const net::URLRequest* request) {
|
||||
DCHECK(request);
|
||||
CEF_REQUIRE_IOT();
|
||||
int render_process_id = -1;
|
||||
|
@ -584,7 +642,7 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::GetBrowserForView(
|
|||
render_routing_id);
|
||||
if (info.get()) {
|
||||
CefRefPtr<CefBrowserHostImpl> browser = info->browser();
|
||||
if (!browser.get()) {
|
||||
if (!browser.get() && !info->is_mime_handler_view()) {
|
||||
LOG(WARNING) << "Found browser id " << info->browser_id() <<
|
||||
" but no browser object matching view process id " <<
|
||||
render_process_id << " and routing id " <<
|
||||
|
@ -617,7 +675,7 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::GetBrowserForFrame(
|
|||
render_routing_id);
|
||||
if (info.get()) {
|
||||
CefRefPtr<CefBrowserHostImpl> browser = info->browser();
|
||||
if (!browser.get()) {
|
||||
if (!browser.get() && !info->is_mime_handler_view()) {
|
||||
LOG(WARNING) << "Found browser id " << info->browser_id() <<
|
||||
" but no browser object matching frame process id " <<
|
||||
render_process_id << " and routing id " <<
|
||||
|
@ -836,10 +894,11 @@ void CefBrowserHostImpl::StartDownload(const CefString& url) {
|
|||
|
||||
void CefBrowserHostImpl::Print() {
|
||||
if (CEF_CURRENTLY_ON_UIT()) {
|
||||
if (!web_contents_)
|
||||
content::WebContents* actionable_contents = GetActionableWebContents();
|
||||
if (!actionable_contents)
|
||||
return;
|
||||
printing::PrintViewManager::FromWebContents(
|
||||
web_contents_.get())->PrintNow();
|
||||
actionable_contents)->PrintNow();
|
||||
} else {
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::Bind(&CefBrowserHostImpl::Print, this));
|
||||
|
@ -850,7 +909,8 @@ void CefBrowserHostImpl::PrintToPDF(const CefString& path,
|
|||
const CefPdfPrintSettings& settings,
|
||||
CefRefPtr<CefPdfPrintCallback> callback) {
|
||||
if (CEF_CURRENTLY_ON_UIT()) {
|
||||
if (!web_contents_)
|
||||
content::WebContents* actionable_contents = GetActionableWebContents();
|
||||
if (!actionable_contents)
|
||||
return;
|
||||
|
||||
printing::PrintViewManager::PdfPrintCallback pdf_callback;
|
||||
|
@ -858,7 +918,7 @@ void CefBrowserHostImpl::PrintToPDF(const CefString& path,
|
|||
pdf_callback = base::Bind(&CefPdfPrintCallback::OnPdfPrintFinished,
|
||||
callback.get(), path);
|
||||
}
|
||||
printing::PrintViewManager::FromWebContents(web_contents_.get())->
|
||||
printing::PrintViewManager::FromWebContents(actionable_contents)->
|
||||
PrintToPDF(base::FilePath(path), settings, pdf_callback);
|
||||
} else {
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
|
@ -1538,6 +1598,8 @@ void CefBrowserHostImpl::DestroyBrowser() {
|
|||
queued_messages_.pop();
|
||||
}
|
||||
|
||||
g_manager.Get().RemoveImpl(this);
|
||||
|
||||
registrar_.reset(NULL);
|
||||
response_manager_.reset(NULL);
|
||||
content::WebContentsObserver::Observe(NULL);
|
||||
|
@ -2265,9 +2327,17 @@ bool CefBrowserHostImpl::TakeFocus(content::WebContents* source,
|
|||
|
||||
bool CefBrowserHostImpl::HandleContextMenu(
|
||||
const content::ContextMenuParams& params) {
|
||||
if (!menu_creator_.get())
|
||||
menu_creator_.reset(new CefMenuCreator(this));
|
||||
return menu_creator_->CreateContextMenu(params);
|
||||
return HandleContextMenu(web_contents(), params);
|
||||
}
|
||||
|
||||
content::WebContents* CefBrowserHostImpl::GetActionableWebContents() {
|
||||
if (web_contents() && extensions::ExtensionsEnabled()) {
|
||||
content::WebContents* guest_contents =
|
||||
extensions::GetGuestForOwnerContents(web_contents());
|
||||
if (guest_contents)
|
||||
return guest_contents;
|
||||
}
|
||||
return web_contents();
|
||||
}
|
||||
|
||||
bool CefBrowserHostImpl::PreHandleKeyboardEvent(
|
||||
|
@ -2451,6 +2521,14 @@ void CefBrowserHostImpl::RunFileChooser(
|
|||
web_contents, params.mode));
|
||||
}
|
||||
|
||||
bool CefBrowserHostImpl::HandleContextMenu(
|
||||
content::WebContents* web_contents,
|
||||
const content::ContextMenuParams& params) {
|
||||
if (!menu_creator_.get())
|
||||
menu_creator_.reset(new CefMenuCreator(web_contents, this));
|
||||
return menu_creator_->CreateContextMenu(params);
|
||||
}
|
||||
|
||||
bool CefBrowserHostImpl::SetPendingPopupInfo(
|
||||
scoped_ptr<PendingPopupInfo> info) {
|
||||
base::AutoLock lock_scope(pending_popup_info_lock_);
|
||||
|
@ -2911,6 +2989,8 @@ CefBrowserHostImpl::CefBrowserHostImpl(
|
|||
web_contents_.reset(web_contents);
|
||||
web_contents->SetDelegate(this);
|
||||
|
||||
g_manager.Get().AddImpl(this);
|
||||
|
||||
registrar_.reset(new content::NotificationRegistrar);
|
||||
registrar_->Add(this, content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
|
||||
content::Source<content::WebContents>(web_contents));
|
||||
|
|
|
@ -131,10 +131,10 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
|||
const content::RenderFrameHost* host);
|
||||
// Returns the browser associated with the specified WebContents.
|
||||
static CefRefPtr<CefBrowserHostImpl> GetBrowserForContents(
|
||||
content::WebContents* contents);
|
||||
const content::WebContents* contents);
|
||||
// Returns the browser associated with the specified URLRequest.
|
||||
static CefRefPtr<CefBrowserHostImpl> GetBrowserForRequest(
|
||||
net::URLRequest* request);
|
||||
const net::URLRequest* request);
|
||||
// Returns the browser associated with the specified view routing IDs.
|
||||
static CefRefPtr<CefBrowserHostImpl> GetBrowserForView(
|
||||
int render_process_id, int render_routing_id);
|
||||
|
@ -333,6 +333,16 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
|||
void RunFileChooser(const FileChooserParams& params,
|
||||
const RunFileChooserCallback& callback);
|
||||
|
||||
bool HandleContextMenu(
|
||||
content::WebContents* web_contents,
|
||||
const content::ContextMenuParams& params);
|
||||
|
||||
// Returns the WebContents most likely to handle an action. If extensions are
|
||||
// enabled and this browser has a full-page guest (for example, a full-page
|
||||
// PDF viewer extension) then the guest's WebContents will be returned.
|
||||
// Otherwise, the browser's WebContents will be returned.
|
||||
content::WebContents* GetActionableWebContents();
|
||||
|
||||
// Used when creating a new popup window.
|
||||
struct PendingPopupInfo {
|
||||
CefWindowInfo window_info;
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
CefBrowserInfo::CefBrowserInfo(int browser_id, bool is_popup)
|
||||
: browser_id_(browser_id),
|
||||
is_popup_(is_popup),
|
||||
is_windowless_(false) {
|
||||
is_windowless_(false),
|
||||
is_mime_handler_view_(false) {
|
||||
DCHECK_GT(browser_id, 0);
|
||||
}
|
||||
|
||||
|
@ -19,6 +20,10 @@ void CefBrowserInfo::set_windowless(bool windowless) {
|
|||
is_windowless_ = windowless;
|
||||
}
|
||||
|
||||
void CefBrowserInfo::set_mime_handler_view(bool mime_handler_view) {
|
||||
is_mime_handler_view_ = mime_handler_view;
|
||||
}
|
||||
|
||||
void CefBrowserInfo::add_render_view_id(
|
||||
int render_process_id, int render_routing_id) {
|
||||
add_render_id(&render_view_id_set_, render_process_id, render_routing_id);
|
||||
|
|
|
@ -24,8 +24,10 @@ class CefBrowserInfo : public base::RefCountedThreadSafe<CefBrowserInfo> {
|
|||
int browser_id() const { return browser_id_; };
|
||||
bool is_popup() const { return is_popup_; }
|
||||
bool is_windowless() const { return is_windowless_; }
|
||||
bool is_mime_handler_view() const { return is_mime_handler_view_; }
|
||||
|
||||
void set_windowless(bool windowless);
|
||||
void set_mime_handler_view(bool mime_handler_view);
|
||||
|
||||
// Adds an ID pair if it doesn't already exist.
|
||||
void add_render_view_id(int render_process_id, int render_routing_id);
|
||||
|
@ -62,6 +64,7 @@ class CefBrowserInfo : public base::RefCountedThreadSafe<CefBrowserInfo> {
|
|||
int browser_id_;
|
||||
bool is_popup_;
|
||||
bool is_windowless_;
|
||||
bool is_mime_handler_view_;
|
||||
|
||||
base::Lock lock_;
|
||||
|
||||
|
|
|
@ -12,7 +12,12 @@
|
|||
#include "libcef/browser/content_browser_client.h"
|
||||
#include "libcef/browser/context.h"
|
||||
#include "libcef/browser/devtools_delegate.h"
|
||||
#include "libcef/browser/extensions/browser_context_keyed_service_factories.h"
|
||||
#include "libcef/browser/extensions/extensions_browser_client.h"
|
||||
#include "libcef/browser/extensions/extension_system_factory.h"
|
||||
#include "libcef/browser/thread_util.h"
|
||||
#include "libcef/common/extensions/extensions_client.h"
|
||||
#include "libcef/common/extensions/extensions_util.h"
|
||||
#include "libcef/common/net_resource_provider.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
|
@ -20,9 +25,12 @@
|
|||
#include "base/message_loop/message_loop.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "content/browser/webui/content_web_ui_controller_factory.h"
|
||||
#include "content/public/browser/child_process_security_policy.h"
|
||||
#include "content/public/browser/gpu_data_manager.h"
|
||||
#include "content/public/browser/web_ui_controller_factory.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "extensions/browser/extension_system.h"
|
||||
#include "extensions/common/constants.h"
|
||||
#include "net/base/net_module.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
|
||||
|
@ -123,6 +131,20 @@ int CefBrowserMainParts::PreCreateThreads() {
|
|||
}
|
||||
|
||||
void CefBrowserMainParts::PreMainMessageLoopRun() {
|
||||
if (extensions::ExtensionsEnabled()) {
|
||||
// Initialize extension global objects before creating the global
|
||||
// BrowserContext.
|
||||
extensions_client_.reset(new extensions::CefExtensionsClient());
|
||||
extensions::ExtensionsClient::Set(extensions_client_.get());
|
||||
extensions_browser_client_.reset(new extensions::CefExtensionsBrowserClient);
|
||||
extensions::ExtensionsBrowserClient::Set(extensions_browser_client_.get());
|
||||
|
||||
// Register additional KeyedService factories here. See
|
||||
// ChromeBrowserMainExtraPartsProfiles for details.
|
||||
extensions::cef::EnsureBrowserContextKeyedServiceFactoriesBuilt();
|
||||
extensions::CefExtensionSystemFactory::GetInstance();
|
||||
}
|
||||
|
||||
CefRequestContextSettings settings;
|
||||
CefContext::Get()->PopulateRequestContextSettings(&settings);
|
||||
|
||||
|
@ -150,6 +172,11 @@ void CefBrowserMainParts::PreMainMessageLoopRun() {
|
|||
}
|
||||
|
||||
void CefBrowserMainParts::PostMainMessageLoopRun() {
|
||||
if (extensions::ExtensionsEnabled()) {
|
||||
extensions::ExtensionsBrowserClient::Set(NULL);
|
||||
extensions_browser_client_.reset();
|
||||
}
|
||||
|
||||
if (devtools_delegate_) {
|
||||
devtools_delegate_->Stop();
|
||||
devtools_delegate_ = NULL;
|
||||
|
|
|
@ -27,6 +27,11 @@ namespace content {
|
|||
struct MainFunctionParams;
|
||||
}
|
||||
|
||||
namespace extensions {
|
||||
class ExtensionsBrowserClient;
|
||||
class ExtensionsClient;
|
||||
}
|
||||
|
||||
class CefDevToolsDelegate;
|
||||
|
||||
class CefBrowserMainParts : public content::BrowserMainParts {
|
||||
|
@ -63,6 +68,9 @@ class CefBrowserMainParts : public content::BrowserMainParts {
|
|||
scoped_refptr<CefBrowserPrefStore> pref_store_;
|
||||
scoped_ptr<PrefService> pref_service_;
|
||||
|
||||
scoped_ptr<extensions::ExtensionsClient> extensions_client_;
|
||||
scoped_ptr<extensions::ExtensionsBrowserClient> extensions_browser_client_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefBrowserMainParts);
|
||||
};
|
||||
|
||||
|
|
|
@ -101,6 +101,7 @@ void CefBrowserMessageFilter::OnGetNewBrowserInfo(
|
|||
params->browser_id = info->browser_id();
|
||||
params->is_popup = info->is_popup();
|
||||
params->is_windowless = info->is_windowless();
|
||||
params->is_mime_handler_view = info->is_mime_handler_view();
|
||||
}
|
||||
|
||||
void CefBrowserMessageFilter::OnCreateWindow(
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include "chrome/browser/prefs/proxy_config_dictionary.h"
|
||||
#include "chrome/common/chrome_switches.h"
|
||||
#include "chrome/common/pref_names.h"
|
||||
#include "components/pref_registry/pref_registry_syncable.h"
|
||||
#include "extensions/browser/extension_prefs.h"
|
||||
#include "grit/cef_strings.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
|
||||
|
@ -82,11 +84,13 @@ scoped_ptr<PrefService> CefBrowserPrefStore::CreateService() {
|
|||
new CommandLinePrefStore(command_line));
|
||||
factory.set_user_prefs(this);
|
||||
|
||||
scoped_refptr<PrefRegistrySimple> registry(new PrefRegistrySimple());
|
||||
scoped_refptr< user_prefs::PrefRegistrySyncable> registry(
|
||||
new user_prefs::PrefRegistrySyncable());
|
||||
|
||||
// Default settings.
|
||||
CefMediaCaptureDevicesDispatcher::RegisterPrefs(registry.get());
|
||||
PrefProxyConfigTrackerImpl::RegisterPrefs(registry.get());
|
||||
extensions::ExtensionPrefs::RegisterProfilePrefs(registry.get());
|
||||
|
||||
// Print settings.
|
||||
registry->RegisterBooleanPref(prefs::kPrintingEnabled, true);
|
||||
|
|
|
@ -31,6 +31,9 @@
|
|||
#include "grit/cef_resources.h"
|
||||
#include "ipc/ipc_channel.h"
|
||||
#include "net/url_request/url_request.h"
|
||||
#include "ui/base/webui/web_ui_util.h"
|
||||
#include "ui/resources/grit/webui_resources.h"
|
||||
#include "ui/resources/grit/webui_resources_map.h"
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
namespace scheme {
|
||||
|
@ -41,12 +44,14 @@ namespace {
|
|||
|
||||
const char kChromeCreditsDomain[] = "credits";
|
||||
const char kChromeLicenseDomain[] = "license";
|
||||
const char kChromeResourcesDomain[] = "resources";
|
||||
const char kChromeVersionDomain[] = "version";
|
||||
|
||||
enum ChromeDomain {
|
||||
CHROME_UNKNOWN = 0,
|
||||
CHROME_CREDITS,
|
||||
CHROME_LICENSE,
|
||||
CHROME_RESOURCES,
|
||||
CHROME_VERSION,
|
||||
};
|
||||
|
||||
|
@ -57,6 +62,7 @@ ChromeDomain GetChromeDomain(const std::string& domain_name) {
|
|||
} domains[] = {
|
||||
{ kChromeCreditsDomain, CHROME_CREDITS },
|
||||
{ kChromeLicenseDomain, CHROME_LICENSE },
|
||||
{ kChromeResourcesDomain, CHROME_RESOURCES },
|
||||
{ kChromeVersionDomain, CHROME_VERSION },
|
||||
};
|
||||
|
||||
|
@ -177,6 +183,48 @@ class TemplateParser {
|
|||
std::string ident_end_;
|
||||
};
|
||||
|
||||
// From content/browser/webui/shared_resources_data_source.cc.
|
||||
using ResourcesMap = base::hash_map<std::string, int>;
|
||||
|
||||
// TODO(rkc): Once we have a separate source for apps, remove '*/apps/' aliases.
|
||||
const char* kPathAliases[][2] = {
|
||||
{"../../../third_party/polymer/v1_0/components-chromium/", "polymer/v1_0/"},
|
||||
{"../../../third_party/web-animations-js/sources/",
|
||||
"polymer/v1_0/web-animations-js/"},
|
||||
{"../../views/resources/default_100_percent/common/", "images/apps/"},
|
||||
{"../../views/resources/default_200_percent/common/", "images/2x/apps/"},
|
||||
{"../../webui/resources/cr_elements/", "cr_elements/"}};
|
||||
|
||||
void AddResource(const std::string& path,
|
||||
int resource_id,
|
||||
ResourcesMap* resources_map) {
|
||||
if (!resources_map->insert(std::make_pair(path, resource_id)).second)
|
||||
NOTREACHED() << "Redefinition of '" << path << "'";
|
||||
}
|
||||
|
||||
const ResourcesMap* CreateResourcesMap() {
|
||||
ResourcesMap* result = new ResourcesMap();
|
||||
for (size_t i = 0; i < kWebuiResourcesSize; ++i) {
|
||||
const std::string resource_name = kWebuiResources[i].name;
|
||||
const int resource_id = kWebuiResources[i].value;
|
||||
AddResource(resource_name, resource_id, result);
|
||||
for (const char* (&alias)[2]: kPathAliases) {
|
||||
if (StartsWithASCII(resource_name, alias[0], true)) {
|
||||
AddResource(alias[1] + resource_name.substr(strlen(alias[0])),
|
||||
resource_id, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const ResourcesMap& GetResourcesMap() {
|
||||
// This pointer will be intentionally leaked on shutdown.
|
||||
static const ResourcesMap* resources_map = CreateResourcesMap();
|
||||
return *resources_map;
|
||||
}
|
||||
|
||||
class Delegate : public InternalHandlerDelegate {
|
||||
public:
|
||||
Delegate() {}
|
||||
|
@ -199,6 +247,9 @@ class Delegate : public InternalHandlerDelegate {
|
|||
case CHROME_LICENSE:
|
||||
handled = OnLicense(action);
|
||||
break;
|
||||
case CHROME_RESOURCES:
|
||||
handled = OnResources(path, action);
|
||||
break;
|
||||
case CHROME_VERSION:
|
||||
handled = OnVersion(browser, action);
|
||||
break;
|
||||
|
@ -209,11 +260,15 @@ class Delegate : public InternalHandlerDelegate {
|
|||
if (!handled && domain != CHROME_VERSION) {
|
||||
LOG(INFO) << "Reguest for unknown chrome resource: " <<
|
||||
url.spec().c_str();
|
||||
action->redirect_url =
|
||||
GURL(std::string(kChromeURL) + kChromeVersionDomain);
|
||||
|
||||
if (domain != CHROME_RESOURCES) {
|
||||
action->redirect_url =
|
||||
GURL(std::string(kChromeURL) + kChromeVersionDomain);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return handled;
|
||||
}
|
||||
|
||||
bool OnCredits(const std::string& path, Action* action) {
|
||||
|
@ -245,6 +300,31 @@ class Delegate : public InternalHandlerDelegate {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool OnResources(const std::string& path, Action* action) {
|
||||
// Implementation based on SharedResourcesDataSource::StartDataRequest.
|
||||
const ResourcesMap& resources_map = GetResourcesMap();
|
||||
auto it = resources_map.find(path);
|
||||
int resource_id = (it != resources_map.end()) ? it->second : -1;
|
||||
|
||||
if (resource_id == -1) {
|
||||
NOTREACHED() << "Failed to find resource id for " << path;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (resource_id == IDR_WEBUI_CSS_TEXT_DEFAULTS) {
|
||||
const std::string& css = webui::GetWebUiCssTextDefaults();
|
||||
DCHECK(!css.empty());
|
||||
action->mime_type = "text/css";
|
||||
action->stream = CefStreamReader::CreateForData(
|
||||
const_cast<char*>(css.c_str()), css.length());
|
||||
action->stream_size = css.length();
|
||||
} else {
|
||||
action->resource_id = resource_id;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnVersion(CefRefPtr<CefBrowser> browser,
|
||||
Action* action) {
|
||||
base::StringPiece piece = CefContentClient::Get()->GetDataResource(
|
||||
|
@ -273,8 +353,8 @@ class Delegate : public InternalHandlerDelegate {
|
|||
parser.Add("USERAGENT", CefContentClient::Get()->GetUserAgent());
|
||||
parser.Add("COMMANDLINE", GetCommandLine());
|
||||
parser.Add("MODULEPATH", GetModulePath());
|
||||
parser.Add("CACHEPATH",
|
||||
browser->GetHost()->GetRequestContext()->GetCachePath());
|
||||
parser.Add("CACHEPATH", browser.get() ?
|
||||
browser->GetHost()->GetRequestContext()->GetCachePath() : "");
|
||||
|
||||
std::string tmpl = piece.as_string();
|
||||
parser.Parse(&tmpl);
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
#include "libcef/browser/chrome_scheme_handler.h"
|
||||
#include "libcef/browser/context.h"
|
||||
#include "libcef/browser/devtools_delegate.h"
|
||||
#include "libcef/browser/extensions/browser_extensions_util.h"
|
||||
#include "libcef/browser/extensions/extension_system.h"
|
||||
#include "libcef/browser/extensions/plugin_info_message_filter.h"
|
||||
#include "libcef/browser/media_capture_devices_dispatcher.h"
|
||||
#include "libcef/browser/pepper/browser_pepper_host_factory.h"
|
||||
#include "libcef/browser/printing/printing_message_filter.h"
|
||||
|
@ -22,9 +25,11 @@
|
|||
#include "libcef/browser/ssl_info_impl.h"
|
||||
#include "libcef/browser/thread_util.h"
|
||||
#include "libcef/browser/web_plugin_impl.h"
|
||||
#include "libcef/common/cef_messages.h"
|
||||
#include "libcef/common/cef_switches.h"
|
||||
#include "libcef/common/command_line_impl.h"
|
||||
#include "libcef/common/content_client.h"
|
||||
#include "libcef/common/extensions/extensions_util.h"
|
||||
#include "libcef/common/scheme_registration.h"
|
||||
|
||||
#include "base/base_switches.h"
|
||||
|
@ -46,6 +51,12 @@
|
|||
#include "content/public/common/content_switches.h"
|
||||
#include "content/public/common/storage_quota_params.h"
|
||||
#include "content/public/common/web_preferences.h"
|
||||
#include "extensions/browser/extension_message_filter.h"
|
||||
#include "extensions/browser/extension_protocols.h"
|
||||
#include "extensions/browser/extension_registry.h"
|
||||
#include "extensions/browser/guest_view/extensions_guest_view_message_filter.h"
|
||||
#include "extensions/browser/io_thread_extension_message_filter.h"
|
||||
#include "extensions/common/constants.h"
|
||||
#include "gin/v8_initializer.h"
|
||||
#include "net/ssl/ssl_cert_request_info.h"
|
||||
#include "third_party/WebKit/public/web/WebWindowFeatures.h"
|
||||
|
@ -561,6 +572,49 @@ void CefContentBrowserClient::RenderProcessWillLaunch(
|
|||
host->AddFilter(new SpellCheckMessageFilterMac(id));
|
||||
#endif
|
||||
}
|
||||
|
||||
content::BrowserContext* browser_context = host->GetBrowserContext();
|
||||
|
||||
if (extensions::ExtensionsEnabled()) {
|
||||
host->AddFilter(
|
||||
new extensions::CefPluginInfoMessageFilter(id, browser_context));
|
||||
host->AddFilter(
|
||||
new extensions::ExtensionMessageFilter(id, browser_context));
|
||||
host->AddFilter(
|
||||
new extensions::IOThreadExtensionMessageFilter(id, browser_context));
|
||||
host->AddFilter(
|
||||
new extensions::ExtensionsGuestViewMessageFilter(id, browser_context));
|
||||
}
|
||||
|
||||
host->Send(new CefProcessMsg_SetIsIncognitoProcess(
|
||||
browser_context->IsOffTheRecord()));
|
||||
}
|
||||
|
||||
bool CefContentBrowserClient::ShouldUseProcessPerSite(
|
||||
content::BrowserContext* browser_context,
|
||||
const GURL& effective_url) {
|
||||
if (!extensions::ExtensionsEnabled())
|
||||
return false;
|
||||
|
||||
if (!effective_url.SchemeIs(extensions::kExtensionScheme))
|
||||
return false;
|
||||
|
||||
extensions::ExtensionRegistry* registry =
|
||||
extensions::ExtensionRegistry::Get(browser_context);
|
||||
if (!registry)
|
||||
return false;
|
||||
|
||||
const extensions::Extension* extension =
|
||||
registry->enabled_extensions().GetByID(effective_url.host());
|
||||
if (!extension)
|
||||
return false;
|
||||
|
||||
// TODO(extensions): Extra checks required if type is TYPE_HOSTED_APP.
|
||||
|
||||
// Hosted apps that have script access to their background page must use
|
||||
// process per site, since all instances can make synchronous calls to the
|
||||
// background window. Other extensions should use process per site as well.
|
||||
return true;
|
||||
}
|
||||
|
||||
net::URLRequestContextGetter* CefContentBrowserClient::CreateRequestContext(
|
||||
|
@ -569,6 +623,19 @@ net::URLRequestContextGetter* CefContentBrowserClient::CreateRequestContext(
|
|||
content::URLRequestInterceptorScopedVector request_interceptors) {
|
||||
scoped_refptr<CefBrowserContext> context =
|
||||
static_cast<CefBrowserContext*>(content_browser_context);
|
||||
|
||||
if (extensions::ExtensionsEnabled()) {
|
||||
// Handle only chrome-extension:// requests. CEF does not support
|
||||
// chrome-extension-resource:// requests (it does not store shared extension
|
||||
// data in its installation directory).
|
||||
extensions::InfoMap* extension_info_map =
|
||||
context->extension_system()->info_map();
|
||||
(*protocol_handlers)[extensions::kExtensionScheme] =
|
||||
linked_ptr<net::URLRequestJobFactory::ProtocolHandler>(
|
||||
extensions::CreateExtensionProtocolHandler(
|
||||
context->IsOffTheRecord(), extension_info_map));
|
||||
}
|
||||
|
||||
return context->CreateRequestContext(
|
||||
protocol_handlers,
|
||||
request_interceptors.Pass());
|
||||
|
@ -635,6 +702,8 @@ void CefContentBrowserClient::AppendExtraCommandLineSwitches(
|
|||
// any associated values) if present in the browser command line.
|
||||
static const char* const kSwitchNames[] = {
|
||||
switches::kContextSafetyImplementation,
|
||||
switches::kDisableExtensions,
|
||||
switches::kDisablePdfExtension,
|
||||
switches::kDisableScrollBounce,
|
||||
switches::kDisableSpellChecking,
|
||||
switches::kEnableSpeechInput,
|
||||
|
@ -802,11 +871,8 @@ bool CefContentBrowserClient::CanCreateWindow(
|
|||
CefBrowserHostImpl::GetBrowserForView(
|
||||
last_create_window_params_.opener_process_id,
|
||||
last_create_window_params_.opener_view_id);
|
||||
DCHECK(browser.get());
|
||||
if (!browser.get()) {
|
||||
LOG(WARNING) << "CanCreateWindow called before browser was created";
|
||||
if (!browser.get())
|
||||
return false;
|
||||
}
|
||||
|
||||
CefRefPtr<CefClient> client = browser->GetClient();
|
||||
bool allow = true;
|
||||
|
@ -886,12 +952,20 @@ void CefContentBrowserClient::OverrideWebkitPrefs(
|
|||
|
||||
CefRefPtr<CefBrowserHostImpl> browser =
|
||||
CefBrowserHostImpl::GetBrowserForHost(rvh);
|
||||
DCHECK(browser.get());
|
||||
if (!browser.get() && extensions::ExtensionsEnabled()) {
|
||||
// Retrieve the owner browser, if any.
|
||||
content::WebContents* owner = extensions::GetOwnerForGuestContents(
|
||||
content::WebContents::FromRenderViewHost(rvh));
|
||||
if (owner)
|
||||
browser = CefBrowserHostImpl::GetBrowserForContents(owner);
|
||||
}
|
||||
|
||||
// Populate WebPreferences based on CefBrowserSettings.
|
||||
BrowserToWebSettings(browser->settings(), *prefs);
|
||||
if (browser.get()) {
|
||||
// Populate WebPreferences based on CefBrowserSettings.
|
||||
BrowserToWebSettings(browser->settings(), *prefs);
|
||||
}
|
||||
|
||||
prefs->base_background_color = GetBaseBackgroundColor(rvh);
|
||||
prefs->base_background_color = GetBaseBackgroundColor(browser);
|
||||
if (rvh->GetView())
|
||||
rvh->GetView()->SetBackgroundColor(prefs->base_background_color);
|
||||
|
||||
|
@ -1013,27 +1087,26 @@ PrefService* CefContentBrowserClient::pref_service() const {
|
|||
return browser_main_parts_->pref_service();
|
||||
}
|
||||
|
||||
// static
|
||||
SkColor CefContentBrowserClient::GetBaseBackgroundColor(
|
||||
content::RenderViewHost* rvh) {
|
||||
CefRefPtr<CefBrowserHostImpl> browser =
|
||||
CefBrowserHostImpl::GetBrowserForHost(rvh);
|
||||
DCHECK(browser.get());
|
||||
|
||||
const CefBrowserSettings& browser_settings = browser->settings();
|
||||
if (CefColorGetA(browser_settings.background_color) > 0) {
|
||||
return SkColorSetRGB(
|
||||
CefColorGetR(browser_settings.background_color),
|
||||
CefColorGetG(browser_settings.background_color),
|
||||
CefColorGetB(browser_settings.background_color));
|
||||
} else {
|
||||
const CefSettings& settings = CefContext::Get()->settings();
|
||||
if (CefColorGetA(settings.background_color) > 0) {
|
||||
CefRefPtr<CefBrowserHostImpl> browser) {
|
||||
if (browser.get()) {
|
||||
const CefBrowserSettings& browser_settings = browser->settings();
|
||||
if (CefColorGetA(browser_settings.background_color) > 0) {
|
||||
return SkColorSetRGB(
|
||||
CefColorGetR(settings.background_color),
|
||||
CefColorGetG(settings.background_color),
|
||||
CefColorGetB(settings.background_color));
|
||||
CefColorGetR(browser_settings.background_color),
|
||||
CefColorGetG(browser_settings.background_color),
|
||||
CefColorGetB(browser_settings.background_color));
|
||||
}
|
||||
}
|
||||
|
||||
const CefSettings& settings = CefContext::Get()->settings();
|
||||
if (CefColorGetA(settings.background_color) > 0) {
|
||||
return SkColorSetRGB(
|
||||
CefColorGetR(settings.background_color),
|
||||
CefColorGetG(settings.background_color),
|
||||
CefColorGetB(settings.background_color));
|
||||
}
|
||||
|
||||
return SK_ColorWHITE;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "third_party/skia/include/core/SkColor.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
class CefBrowserHostImpl;
|
||||
class CefBrowserInfo;
|
||||
class CefBrowserMainParts;
|
||||
class CefDevToolsDelegate;
|
||||
|
@ -73,6 +74,8 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
|
|||
const content::MainFunctionParams& parameters) override;
|
||||
void RenderProcessWillLaunch(
|
||||
content::RenderProcessHost* host) override;
|
||||
bool ShouldUseProcessPerSite(content::BrowserContext* browser_context,
|
||||
const GURL& effective_url) override;
|
||||
net::URLRequestContextGetter* CreateRequestContext(
|
||||
content::BrowserContext* browser_context,
|
||||
content::ProtocolHandlerMap* protocol_handlers,
|
||||
|
@ -165,7 +168,7 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
|
|||
PrefService* pref_service() const;
|
||||
|
||||
private:
|
||||
SkColor GetBaseBackgroundColor(content::RenderViewHost* rvh);
|
||||
static SkColor GetBaseBackgroundColor(CefRefPtr<CefBrowserHostImpl> browser);
|
||||
|
||||
CefBrowserMainParts* browser_main_parts_;
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
# Copyright 2014 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.
|
||||
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'cef_api_registration',
|
||||
'type': 'static_library',
|
||||
# TODO(jschuh): http://crbug.com/167187 size_t -> int
|
||||
'msvs_disabled_warnings': [ 4267 ],
|
||||
'includes': [
|
||||
'../../../../../build/json_schema_bundle_registration_compile.gypi',
|
||||
'../../../common/extensions/api/schemas.gypi',
|
||||
],
|
||||
'dependencies': [
|
||||
'../../../common/extensions/api/api.gyp:cef_api',
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
// Copyright (c) 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/api/streams_private/streams_private_api.h"
|
||||
|
||||
#include "base/lazy_instance.h"
|
||||
#include "base/values.h"
|
||||
#include "cef/libcef/common/extensions/api/streams_private.h"
|
||||
#include "content/public/browser/stream_handle.h"
|
||||
#include "content/public/browser/stream_info.h"
|
||||
#include "extensions/browser/event_router.h"
|
||||
#include "extensions/browser/extension_function_registry.h"
|
||||
#include "extensions/browser/extension_registry.h"
|
||||
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_stream_manager.h"
|
||||
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
|
||||
#include "extensions/common/manifest_handlers/mime_types_handler.h"
|
||||
#include "net/http/http_response_headers.h"
|
||||
|
||||
namespace extensions {
|
||||
namespace {
|
||||
|
||||
void CreateResponseHeadersDictionary(const net::HttpResponseHeaders* headers,
|
||||
base::DictionaryValue* result) {
|
||||
if (!headers)
|
||||
return;
|
||||
|
||||
void* iter = NULL;
|
||||
std::string header_name;
|
||||
std::string header_value;
|
||||
while (headers->EnumerateHeaderLines(&iter, &header_name, &header_value)) {
|
||||
base::Value* existing_value = NULL;
|
||||
if (result->Get(header_name, &existing_value)) {
|
||||
base::StringValue* existing_string_value =
|
||||
static_cast<base::StringValue*>(existing_value);
|
||||
existing_string_value->GetString()->append(", ").append(header_value);
|
||||
} else {
|
||||
result->SetString(header_name, header_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace streams_private = api::streams_private;
|
||||
|
||||
// static
|
||||
StreamsPrivateAPI* StreamsPrivateAPI::Get(content::BrowserContext* context) {
|
||||
return GetFactoryInstance()->Get(context);
|
||||
}
|
||||
|
||||
StreamsPrivateAPI::StreamsPrivateAPI(content::BrowserContext* context)
|
||||
: browser_context_(context),
|
||||
extension_registry_observer_(this),
|
||||
weak_ptr_factory_(this) {
|
||||
extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_));
|
||||
}
|
||||
|
||||
StreamsPrivateAPI::~StreamsPrivateAPI() {
|
||||
}
|
||||
|
||||
void StreamsPrivateAPI::ExecuteMimeTypeHandler(
|
||||
const std::string& extension_id,
|
||||
int tab_id,
|
||||
scoped_ptr<content::StreamInfo> stream,
|
||||
const std::string& view_id,
|
||||
int64 expected_content_size,
|
||||
bool embedded,
|
||||
int render_process_id,
|
||||
int render_frame_id) {
|
||||
const Extension* extension = ExtensionRegistry::Get(browser_context_)
|
||||
->enabled_extensions()
|
||||
.GetByID(extension_id);
|
||||
if (!extension)
|
||||
return;
|
||||
|
||||
MimeTypesHandler* handler = MimeTypesHandler::GetHandler(extension);
|
||||
// If the mime handler uses MimeHandlerViewGuest, the MimeHandlerViewGuest
|
||||
// will take ownership of the stream. Otherwise, store the stream handle in
|
||||
// |streams_| and fire an event notifying the extension.
|
||||
if (!handler->handler_url().empty()) {
|
||||
GURL handler_url(Extension::GetBaseURLFromExtensionId(extension_id).spec() +
|
||||
handler->handler_url());
|
||||
scoped_ptr<StreamContainer> stream_container(new StreamContainer(
|
||||
stream.Pass(), tab_id, embedded, handler_url, extension_id));
|
||||
MimeHandlerStreamManager::Get(browser_context_)
|
||||
->AddStream(view_id, stream_container.Pass(), render_process_id,
|
||||
render_frame_id);
|
||||
return;
|
||||
}
|
||||
// Create the event's arguments value.
|
||||
streams_private::StreamInfo info;
|
||||
info.mime_type = stream->mime_type;
|
||||
info.original_url = stream->original_url.spec();
|
||||
info.stream_url = stream->handle->GetURL().spec();
|
||||
info.tab_id = tab_id;
|
||||
info.embedded = embedded;
|
||||
|
||||
if (!view_id.empty()) {
|
||||
info.view_id.reset(new std::string(view_id));
|
||||
}
|
||||
|
||||
int size = -1;
|
||||
if (expected_content_size <= INT_MAX)
|
||||
size = expected_content_size;
|
||||
info.expected_content_size = size;
|
||||
|
||||
CreateResponseHeadersDictionary(stream->response_headers.get(),
|
||||
&info.response_headers.additional_properties);
|
||||
|
||||
scoped_ptr<Event> event(
|
||||
new Event(streams_private::OnExecuteMimeTypeHandler::kEventName,
|
||||
streams_private::OnExecuteMimeTypeHandler::Create(info)));
|
||||
|
||||
EventRouter::Get(browser_context_)
|
||||
->DispatchEventToExtension(extension_id, event.Pass());
|
||||
|
||||
GURL url = stream->handle->GetURL();
|
||||
streams_[extension_id][url] = make_linked_ptr(stream->handle.release());
|
||||
}
|
||||
|
||||
void StreamsPrivateAPI::AbortStream(const std::string& extension_id,
|
||||
const GURL& stream_url,
|
||||
const base::Closure& callback) {
|
||||
StreamMap::iterator extension_it = streams_.find(extension_id);
|
||||
if (extension_it == streams_.end()) {
|
||||
callback.Run();
|
||||
return;
|
||||
}
|
||||
|
||||
StreamMap::mapped_type* url_map = &extension_it->second;
|
||||
StreamMap::mapped_type::iterator url_it = url_map->find(stream_url);
|
||||
if (url_it == url_map->end()) {
|
||||
callback.Run();
|
||||
return;
|
||||
}
|
||||
|
||||
url_it->second->AddCloseListener(callback);
|
||||
url_map->erase(url_it);
|
||||
}
|
||||
|
||||
void StreamsPrivateAPI::OnExtensionUnloaded(
|
||||
content::BrowserContext* browser_context,
|
||||
const Extension* extension,
|
||||
UnloadedExtensionInfo::Reason reason) {
|
||||
streams_.erase(extension->id());
|
||||
}
|
||||
|
||||
StreamsPrivateAbortFunction::StreamsPrivateAbortFunction() {
|
||||
}
|
||||
|
||||
ExtensionFunction::ResponseAction StreamsPrivateAbortFunction::Run() {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &stream_url_));
|
||||
StreamsPrivateAPI::Get(browser_context())->AbortStream(
|
||||
extension_id(), GURL(stream_url_), base::Bind(
|
||||
&StreamsPrivateAbortFunction::OnClose, this));
|
||||
return RespondLater();
|
||||
}
|
||||
|
||||
void StreamsPrivateAbortFunction::OnClose() {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
Respond(NoArguments());
|
||||
}
|
||||
|
||||
static base::LazyInstance<BrowserContextKeyedAPIFactory<StreamsPrivateAPI> >
|
||||
g_factory = LAZY_INSTANCE_INITIALIZER;
|
||||
|
||||
// static
|
||||
BrowserContextKeyedAPIFactory<StreamsPrivateAPI>*
|
||||
StreamsPrivateAPI::GetFactoryInstance() {
|
||||
return g_factory.Pointer();
|
||||
}
|
||||
|
||||
} // namespace extensions
|
|
@ -0,0 +1,104 @@
|
|||
// Copyright (c) 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_API_STREAMS_PRIVATE_STREAMS_PRIVATE_API_H_
|
||||
#define CEF_LIBCEF_BROWSER_EXTENSIONS_API_STREAMS_PRIVATE_STREAMS_PRIVATE_API_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "base/scoped_observer.h"
|
||||
#include "extensions/browser/browser_context_keyed_api_factory.h"
|
||||
#include "extensions/browser/extension_function.h"
|
||||
#include "extensions/browser/extension_registry_observer.h"
|
||||
|
||||
namespace content {
|
||||
class BrowserContext;
|
||||
class StreamHandle;
|
||||
struct StreamInfo;
|
||||
}
|
||||
|
||||
namespace extensions {
|
||||
class ExtensionRegistry;
|
||||
|
||||
class StreamsPrivateAPI : public BrowserContextKeyedAPI,
|
||||
public ExtensionRegistryObserver {
|
||||
public:
|
||||
// Convenience method to get the StreamsPrivateAPI for a BrowserContext.
|
||||
static StreamsPrivateAPI* Get(content::BrowserContext* context);
|
||||
|
||||
explicit StreamsPrivateAPI(content::BrowserContext* context);
|
||||
~StreamsPrivateAPI() override;
|
||||
|
||||
// Send the onExecuteMimeTypeHandler event to |extension_id|.
|
||||
// |tab_id| is used to determine the tabId where the document is being
|
||||
// opened. The data for the document will be readable from |stream|, and
|
||||
// should be |expected_content_size| bytes long. If the viewer is being opened
|
||||
// in a BrowserPlugin, specify a non-empty |view_id| of the plugin. |embedded|
|
||||
// should be set to whether the document is embedded within another document.
|
||||
void ExecuteMimeTypeHandler(const std::string& extension_id,
|
||||
int tab_id,
|
||||
scoped_ptr<content::StreamInfo> stream,
|
||||
const std::string& view_id,
|
||||
int64 expected_content_size,
|
||||
bool embedded,
|
||||
int render_process_id,
|
||||
int render_frame_id);
|
||||
|
||||
void AbortStream(const std::string& extension_id,
|
||||
const GURL& stream_url,
|
||||
const base::Closure& callback);
|
||||
|
||||
// BrowserContextKeyedAPI implementation.
|
||||
static BrowserContextKeyedAPIFactory<StreamsPrivateAPI>* GetFactoryInstance();
|
||||
|
||||
private:
|
||||
friend class BrowserContextKeyedAPIFactory<StreamsPrivateAPI>;
|
||||
typedef std::map<std::string,
|
||||
std::map<GURL,
|
||||
linked_ptr<content::StreamHandle> > > StreamMap;
|
||||
|
||||
// ExtensionRegistryObserver implementation.
|
||||
void OnExtensionUnloaded(content::BrowserContext* browser_context,
|
||||
const Extension* extension,
|
||||
UnloadedExtensionInfo::Reason reason) override;
|
||||
|
||||
// BrowserContextKeyedAPI implementation.
|
||||
static const char* service_name() {
|
||||
return "StreamsPrivateAPI";
|
||||
}
|
||||
static const bool kServiceIsNULLWhileTesting = true;
|
||||
static const bool kServiceRedirectedInIncognito = true;
|
||||
|
||||
content::BrowserContext* const browser_context_;
|
||||
StreamMap streams_;
|
||||
|
||||
// Listen to extension unloaded notifications.
|
||||
ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
|
||||
extension_registry_observer_;
|
||||
|
||||
base::WeakPtrFactory<StreamsPrivateAPI> weak_ptr_factory_;
|
||||
|
||||
};
|
||||
|
||||
class StreamsPrivateAbortFunction : public UIThreadExtensionFunction {
|
||||
public:
|
||||
StreamsPrivateAbortFunction();
|
||||
DECLARE_EXTENSION_FUNCTION("streamsPrivate.abort", STREAMSPRIVATE_ABORT)
|
||||
|
||||
protected:
|
||||
~StreamsPrivateAbortFunction() override {}
|
||||
|
||||
// ExtensionFunction:
|
||||
ExtensionFunction::ResponseAction Run() override;
|
||||
|
||||
private:
|
||||
void OnClose();
|
||||
|
||||
std::string stream_url_;
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_EXTENSIONS_API_STREAMS_PRIVATE_STREAMS_PRIVATE_API_H_
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright 2015 The Chromium Embedded Framework 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/browser_context_keyed_service_factories.h"
|
||||
|
||||
#include "libcef/browser/extensions/api/streams_private/streams_private_api.h"
|
||||
|
||||
#include "extensions/browser/renderer_startup_helper.h"
|
||||
|
||||
namespace extensions {
|
||||
namespace cef {
|
||||
|
||||
void EnsureBrowserContextKeyedServiceFactoriesBuilt() {
|
||||
RendererStartupHelperFactory::GetInstance();
|
||||
StreamsPrivateAPI::GetFactoryInstance();
|
||||
}
|
||||
|
||||
} // namespace cef
|
||||
} // namespace extensions
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright 2015 The Chromium Embedded Framework 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_BROWSER_CONTEXT_KEYED_SERVICE_FACTORIES_H_
|
||||
#define CEF_LIBCEF_BROWSER_EXTENSIONS_BROWSER_CONTEXT_KEYED_SERVICE_FACTORIES_H_
|
||||
|
||||
namespace extensions {
|
||||
namespace cef {
|
||||
|
||||
// Ensures the existence of any BrowserContextKeyedServiceFactory provided by
|
||||
// the CEF extensions code or otherwise required by CEF. See
|
||||
// libcef/common/extensions/api/README.txt for additional details.
|
||||
void EnsureBrowserContextKeyedServiceFactoriesBuilt();
|
||||
|
||||
} // namespace cef
|
||||
} // namespace extensions
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_EXTENSIONS_BROWSER_CONTEXT_KEYED_SERVICE_FACTORIES_H_
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) 2015 The Chromium Embedded Framework 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/browser_extensions_util.h"
|
||||
|
||||
#include "content/browser/browser_plugin/browser_plugin_embedder.h"
|
||||
#include "content/browser/browser_plugin/browser_plugin_guest.h"
|
||||
#include "content/browser/web_contents/web_contents_impl.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
content::WebContents* GetGuestForOwnerContents(content::WebContents* guest) {
|
||||
content::WebContentsImpl* guest_impl =
|
||||
static_cast<content::WebContentsImpl*>(guest);
|
||||
content::BrowserPluginEmbedder* embedder =
|
||||
guest_impl->GetBrowserPluginEmbedder();
|
||||
if (embedder) {
|
||||
content::BrowserPluginGuest* guest = embedder->GetFullPageGuest();
|
||||
if (guest)
|
||||
return guest->web_contents();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
content::WebContents* GetOwnerForGuestContents(content::WebContents* owner) {
|
||||
content::WebContentsImpl* owner_impl =
|
||||
static_cast<content::WebContentsImpl*>(owner);
|
||||
content::BrowserPluginGuest* guest = owner_impl->GetBrowserPluginGuest();
|
||||
if (guest)
|
||||
return guest->embedder_web_contents();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} // namespace extensions
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (c) 2015 The Chromium Embedded Framework 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_BROWSER_EXTENSIONS_UTIL_H_
|
||||
#define CEF_LIBCEF_BROWSER_EXTENSIONS_BROWSER_EXTENSIONS_UTIL_H_
|
||||
|
||||
namespace content {
|
||||
class WebContents;
|
||||
}
|
||||
|
||||
namespace extensions {
|
||||
|
||||
// Returns the WebContents that owns the specified |guest|, if any.
|
||||
content::WebContents* GetGuestForOwnerContents(content::WebContents* guest);
|
||||
|
||||
// Returns the guest WebContents for the specified |owner|, if any.
|
||||
content::WebContents* GetOwnerForGuestContents(content::WebContents* owner);
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_EXTENSIONS_BROWSER_EXTENSIONS_UTIL_H_
|
|
@ -0,0 +1,58 @@
|
|||
// Copyright 2014 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/component_extension_resource_manager.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/path_service.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "grit/component_extension_resources_map.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
CefComponentExtensionResourceManager::CefComponentExtensionResourceManager() {
|
||||
AddComponentResourceEntries(
|
||||
kComponentExtensionResources,
|
||||
kComponentExtensionResourcesSize);
|
||||
}
|
||||
|
||||
CefComponentExtensionResourceManager::~CefComponentExtensionResourceManager() {}
|
||||
|
||||
bool CefComponentExtensionResourceManager::IsComponentExtensionResource(
|
||||
const base::FilePath& extension_path,
|
||||
const base::FilePath& resource_path,
|
||||
int* resource_id) const {
|
||||
base::FilePath directory_path = extension_path;
|
||||
base::FilePath resources_dir;
|
||||
base::FilePath relative_path;
|
||||
if (!PathService::Get(chrome::DIR_RESOURCES, &resources_dir) ||
|
||||
!resources_dir.AppendRelativePath(directory_path, &relative_path)) {
|
||||
return false;
|
||||
}
|
||||
relative_path = relative_path.Append(resource_path);
|
||||
relative_path = relative_path.NormalizePathSeparators();
|
||||
|
||||
std::map<base::FilePath, int>::const_iterator entry =
|
||||
path_to_resource_id_.find(relative_path);
|
||||
if (entry != path_to_resource_id_.end())
|
||||
*resource_id = entry->second;
|
||||
|
||||
return entry != path_to_resource_id_.end();
|
||||
}
|
||||
|
||||
void CefComponentExtensionResourceManager::AddComponentResourceEntries(
|
||||
const GritResourceMap* entries,
|
||||
size_t size) {
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
base::FilePath resource_path = base::FilePath().AppendASCII(
|
||||
entries[i].name);
|
||||
resource_path = resource_path.NormalizePathSeparators();
|
||||
|
||||
DCHECK(path_to_resource_id_.find(resource_path) ==
|
||||
path_to_resource_id_.end());
|
||||
path_to_resource_id_[resource_path] = entries[i].value;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace extensions
|
|
@ -0,0 +1,41 @@
|
|||
// Copyright 2014 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_COMPONENT_EXTENSION_RESOURCE_MANAGER_H_
|
||||
#define CEF_LIBCEF_BROWSER_EXTENSIONS_COMPONENT_EXTENSION_RESOURCE_MANAGER_H_
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "extensions/browser/component_extension_resource_manager.h"
|
||||
|
||||
struct GritResourceMap;
|
||||
|
||||
namespace extensions {
|
||||
|
||||
class CefComponentExtensionResourceManager
|
||||
: public ComponentExtensionResourceManager {
|
||||
public:
|
||||
CefComponentExtensionResourceManager();
|
||||
~CefComponentExtensionResourceManager() override;
|
||||
|
||||
// Overridden from ComponentExtensionResourceManager:
|
||||
bool IsComponentExtensionResource(const base::FilePath& extension_path,
|
||||
const base::FilePath& resource_path,
|
||||
int* resource_id) const override;
|
||||
|
||||
private:
|
||||
void AddComponentResourceEntries(const GritResourceMap* entries, size_t size);
|
||||
|
||||
// A map from a resource path to the resource ID. Used by
|
||||
// IsComponentExtensionResource.
|
||||
std::map<base::FilePath, int> path_to_resource_id_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefComponentExtensionResourceManager);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_EXTENSIONS_COMPONENT_EXTENSION_RESOURCE_MANAGER_H_
|
|
@ -0,0 +1,124 @@
|
|||
// Copyright (c) 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/event_router_forwarder.h"
|
||||
|
||||
#include "libcef/browser/browser_context_impl.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/values.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "extensions/browser/event_router.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace extensions {
|
||||
|
||||
EventRouterForwarder::EventRouterForwarder() {
|
||||
}
|
||||
|
||||
EventRouterForwarder::~EventRouterForwarder() {
|
||||
}
|
||||
|
||||
void EventRouterForwarder::BroadcastEventToRenderers(
|
||||
const std::string& event_name,
|
||||
scoped_ptr<base::ListValue> event_args,
|
||||
const GURL& event_url) {
|
||||
HandleEvent(std::string(), event_name, event_args.Pass(), 0, true, event_url);
|
||||
}
|
||||
|
||||
void EventRouterForwarder::DispatchEventToRenderers(
|
||||
const std::string& event_name,
|
||||
scoped_ptr<base::ListValue> event_args,
|
||||
void* profile,
|
||||
bool use_profile_to_restrict_events,
|
||||
const GURL& event_url) {
|
||||
if (!profile)
|
||||
return;
|
||||
HandleEvent(std::string(),
|
||||
event_name,
|
||||
event_args.Pass(),
|
||||
profile,
|
||||
use_profile_to_restrict_events,
|
||||
event_url);
|
||||
}
|
||||
|
||||
void EventRouterForwarder::BroadcastEventToExtension(
|
||||
const std::string& extension_id,
|
||||
const std::string& event_name,
|
||||
scoped_ptr<base::ListValue> event_args,
|
||||
const GURL& event_url) {
|
||||
HandleEvent(extension_id, event_name, event_args.Pass(), 0, true, event_url);
|
||||
}
|
||||
|
||||
void EventRouterForwarder::DispatchEventToExtension(
|
||||
const std::string& extension_id,
|
||||
const std::string& event_name,
|
||||
scoped_ptr<base::ListValue> event_args,
|
||||
void* profile,
|
||||
bool use_profile_to_restrict_events,
|
||||
const GURL& event_url) {
|
||||
if (!profile)
|
||||
return;
|
||||
HandleEvent(extension_id, event_name, event_args.Pass(), profile,
|
||||
use_profile_to_restrict_events, event_url);
|
||||
}
|
||||
|
||||
void EventRouterForwarder::HandleEvent(const std::string& extension_id,
|
||||
const std::string& event_name,
|
||||
scoped_ptr<base::ListValue> event_args,
|
||||
void* profile_ptr,
|
||||
bool use_profile_to_restrict_events,
|
||||
const GURL& event_url) {
|
||||
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&EventRouterForwarder::HandleEvent, this,
|
||||
extension_id, event_name, base::Passed(&event_args),
|
||||
profile_ptr, use_profile_to_restrict_events, event_url));
|
||||
return;
|
||||
}
|
||||
|
||||
content::BrowserContext* profile = NULL;
|
||||
if (profile_ptr) {
|
||||
profile = reinterpret_cast<content::BrowserContext*>(profile_ptr);
|
||||
if (CefBrowserContextImpl::GetForContext(profile) == NULL)
|
||||
return;
|
||||
}
|
||||
if (profile) {
|
||||
CallEventRouter(profile, extension_id, event_name, event_args.Pass(),
|
||||
use_profile_to_restrict_events ? profile : NULL, event_url);
|
||||
} else {
|
||||
std::vector<CefBrowserContextImpl*> profiles(
|
||||
CefBrowserContextImpl::GetAll());
|
||||
for (size_t i = 0; i < profiles.size(); ++i) {
|
||||
scoped_ptr<base::ListValue> per_profile_event_args(
|
||||
event_args->DeepCopy());
|
||||
CallEventRouter(
|
||||
profiles[i], extension_id, event_name, per_profile_event_args.Pass(),
|
||||
use_profile_to_restrict_events ? profiles[i] : NULL, event_url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EventRouterForwarder::CallEventRouter(
|
||||
content::BrowserContext* profile,
|
||||
const std::string& extension_id,
|
||||
const std::string& event_name,
|
||||
scoped_ptr<base::ListValue> event_args,
|
||||
content::BrowserContext* restrict_to_profile,
|
||||
const GURL& event_url) {
|
||||
scoped_ptr<Event> event(new Event(event_name, event_args.Pass()));
|
||||
event->restrict_to_browser_context = restrict_to_profile;
|
||||
event->event_url = event_url;
|
||||
if (extension_id.empty()) {
|
||||
extensions::EventRouter::Get(profile)->BroadcastEvent(event.Pass());
|
||||
} else {
|
||||
extensions::EventRouter::Get(profile)
|
||||
->DispatchEventToExtension(extension_id, event.Pass());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace extensions
|
|
@ -0,0 +1,107 @@
|
|||
// Copyright (c) 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_EVENT_ROUTER_FORWARDER_H_
|
||||
#define CEF_LIBCEF_BROWSER_EXTENSIONS_EVENT_ROUTER_FORWARDER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/values.h"
|
||||
|
||||
class GURL;
|
||||
|
||||
namespace content {
|
||||
class BrowserContext;
|
||||
}
|
||||
|
||||
namespace extensions {
|
||||
|
||||
// This class forwards events to EventRouters.
|
||||
// The advantages of this class over direct usage of EventRouters are:
|
||||
// - this class is thread-safe, you can call the functions from UI and IO
|
||||
// thread.
|
||||
// - the class can handle if a profile is deleted between the time of sending
|
||||
// the event from the IO thread to the UI thread.
|
||||
// - this class can be used in contexts that are not governed by a profile, e.g.
|
||||
// by system URLRequestContexts. In these cases the |restrict_to_profile|
|
||||
// parameter remains NULL and events are broadcasted to all profiles.
|
||||
class EventRouterForwarder
|
||||
: public base::RefCountedThreadSafe<EventRouterForwarder> {
|
||||
public:
|
||||
EventRouterForwarder();
|
||||
|
||||
// Calls
|
||||
// DispatchEventToRenderers(event_name, event_args, profile, event_url)
|
||||
// on all (original) profiles' EventRouters.
|
||||
// May be called on any thread.
|
||||
void BroadcastEventToRenderers(const std::string& event_name,
|
||||
scoped_ptr<base::ListValue> event_args,
|
||||
const GURL& event_url);
|
||||
|
||||
// Calls
|
||||
// DispatchEventToExtension(extension_id, event_name, event_args,
|
||||
// profile, event_url)
|
||||
// on all (original) profiles' EventRouters.
|
||||
// May be called on any thread.
|
||||
void BroadcastEventToExtension(const std::string& extension_id,
|
||||
const std::string& event_name,
|
||||
scoped_ptr<base::ListValue> event_args,
|
||||
const GURL& event_url);
|
||||
|
||||
// Calls
|
||||
// DispatchEventToRenderers(event_name, event_args,
|
||||
// use_profile_to_restrict_events ? profile : NULL, event_url)
|
||||
// on |profile|'s EventRouter. May be called on any thread.
|
||||
void DispatchEventToRenderers(const std::string& event_name,
|
||||
scoped_ptr<base::ListValue> event_args,
|
||||
void* profile,
|
||||
bool use_profile_to_restrict_events,
|
||||
const GURL& event_url);
|
||||
|
||||
// Calls
|
||||
// DispatchEventToExtension(extension_id, event_name, event_args,
|
||||
// use_profile_to_restrict_events ? profile : NULL, event_url)
|
||||
// on |profile|'s EventRouter. May be called on any thread.
|
||||
void DispatchEventToExtension(const std::string& extension_id,
|
||||
const std::string& event_name,
|
||||
scoped_ptr<base::ListValue> event_args,
|
||||
void* profile,
|
||||
bool use_profile_to_restrict_events,
|
||||
const GURL& event_url);
|
||||
|
||||
protected:
|
||||
// Protected for testing.
|
||||
virtual ~EventRouterForwarder();
|
||||
|
||||
// Helper function for {Broadcast,Dispatch}EventTo{Extension,Renderers}.
|
||||
// Virtual for testing.
|
||||
virtual void HandleEvent(const std::string& extension_id,
|
||||
const std::string& event_name,
|
||||
scoped_ptr<base::ListValue> event_args,
|
||||
void* profile,
|
||||
bool use_profile_to_restrict_events,
|
||||
const GURL& event_url);
|
||||
|
||||
// Calls DispatchEventToRenderers or DispatchEventToExtension (depending on
|
||||
// whether extension_id == "" or not) of |profile|'s EventRouter.
|
||||
// |profile| may never be NULL.
|
||||
// Virtual for testing.
|
||||
virtual void CallEventRouter(content::BrowserContext* profile,
|
||||
const std::string& extension_id,
|
||||
const std::string& event_name,
|
||||
scoped_ptr<base::ListValue> event_args,
|
||||
content::BrowserContext* restrict_to_profile,
|
||||
const GURL& event_url);
|
||||
|
||||
private:
|
||||
friend class base::RefCountedThreadSafe<EventRouterForwarder>;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(EventRouterForwarder);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_EXTENSIONS_EVENT_ROUTER_FORWARDER_H_
|
|
@ -0,0 +1,436 @@
|
|||
// Copyright 2015 The Chromium Embedded Framework Authors.
|
||||
// Portions copyright 2014 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/extension_system.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "libcef/browser/extensions/pdf_extension_util.h"
|
||||
#include "libcef/common/extensions/extensions_util.h"
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/json/json_string_value_serializer.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/strings/string_tokenizer.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "components/crx_file/id_util.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/notification_details.h"
|
||||
#include "content/public/browser/notification_service.h"
|
||||
#include "content/public/browser/notification_source.h"
|
||||
#include "content/public/browser/plugin_service.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "extensions/browser/api/app_runtime/app_runtime_api.h"
|
||||
#include "extensions/browser/extension_prefs.h"
|
||||
#include "extensions/browser/extension_registry.h"
|
||||
#include "extensions/browser/info_map.h"
|
||||
#include "extensions/browser/notification_types.h"
|
||||
#include "extensions/browser/quota_service.h"
|
||||
#include "extensions/browser/runtime_data.h"
|
||||
#include "extensions/common/constants.h"
|
||||
#include "extensions/common/extension_messages.h"
|
||||
#include "extensions/common/file_util.h"
|
||||
#include "extensions/common/manifest_constants.h"
|
||||
#include "extensions/common/manifest_handlers/mime_types_handler.h"
|
||||
#include "extensions/common/switches.h"
|
||||
#include "net/base/mime_util.h"
|
||||
|
||||
using content::BrowserContext;
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace extensions {
|
||||
|
||||
namespace {
|
||||
|
||||
std::string GenerateId(const base::DictionaryValue* manifest,
|
||||
const base::FilePath& path) {
|
||||
std::string raw_key;
|
||||
std::string id_input;
|
||||
CHECK(manifest->GetString(manifest_keys::kPublicKey, &raw_key));
|
||||
CHECK(Extension::ParsePEMKeyBytes(raw_key, &id_input));
|
||||
std::string id = crx_file::id_util::GenerateId(id_input);
|
||||
return id;
|
||||
}
|
||||
|
||||
// Implementation based on ComponentLoader::ParseManifest.
|
||||
base::DictionaryValue* ParseManifest(
|
||||
const std::string& manifest_contents) {
|
||||
JSONStringValueDeserializer deserializer(manifest_contents);
|
||||
scoped_ptr<base::Value> manifest(deserializer.Deserialize(NULL, NULL));
|
||||
|
||||
if (!manifest.get() || !manifest->IsType(base::Value::TYPE_DICTIONARY)) {
|
||||
LOG(ERROR) << "Failed to parse extension manifest.";
|
||||
return NULL;
|
||||
}
|
||||
// Transfer ownership to the caller.
|
||||
return static_cast<base::DictionaryValue*>(manifest.release());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CefExtensionSystem::CefExtensionSystem(BrowserContext* browser_context)
|
||||
: browser_context_(browser_context),
|
||||
registry_(ExtensionRegistry::Get(browser_context)) {
|
||||
}
|
||||
|
||||
CefExtensionSystem::~CefExtensionSystem() {
|
||||
}
|
||||
|
||||
void CefExtensionSystem::Init() {
|
||||
// There's complexity here related to the ordering of message delivery. For
|
||||
// an extension to load correctly both the ExtensionMsg_Loaded and
|
||||
// ExtensionMsg_ActivateExtension messages must be sent. These messages are
|
||||
// currently sent by RendererStartupHelper, ExtensionWebContentsObserver, and
|
||||
// this class. ExtensionMsg_Loaded is handled by Dispatcher::OnLoaded and adds
|
||||
// the extension to |extensions_|. ExtensionMsg_ActivateExtension is handled
|
||||
// by Dispatcher::OnActivateExtension and adds the extension to
|
||||
// |active_extension_ids_|. If these messages are not sent correctly then
|
||||
// ScriptContextSet::Register called from Dispatcher::DidCreateScriptContext
|
||||
// will classify the extension incorrectly and API bindings will not be added.
|
||||
|
||||
// Inform the rest of the extensions system to start.
|
||||
ready_.Signal();
|
||||
content::NotificationService::current()->Notify(
|
||||
NOTIFICATION_EXTENSIONS_READY_DEPRECATED,
|
||||
content::Source<BrowserContext>(browser_context_),
|
||||
content::NotificationService::NoDetails());
|
||||
|
||||
// Add the built-in PDF extension. PDF loading works as follows:
|
||||
// 1. PDF PPAPI plugin is registered to handle kPDFPluginOutOfProcessMimeType
|
||||
// in libcef/common/content_client.cc ComputeBuiltInPlugins.
|
||||
// 2. PDF extension is registered with the below call to AddExtension.
|
||||
// 3. A page requests a plugin to handle "application/pdf" mime type. This
|
||||
// results in a call to CefContentRendererClient::OverrideCreatePlugin
|
||||
// in the renderer process which calls CefContentRendererClient::
|
||||
// CreateBrowserPluginDelegate indirectly to create a
|
||||
// MimeHandlerViewContainer.
|
||||
// 4. CefResourceDispatcherHostDelegate::ShouldInterceptResourceAsStream
|
||||
// intercepts the PDF load in the browser process, associates the load with
|
||||
// the PDF extension and makes the PDF file contents available to the
|
||||
// extension via the Stream API.
|
||||
// 5. A MimeHandlerViewGuest and CefMimeHandlerViewGuestDelegate is created in
|
||||
// the browser process.
|
||||
// 6. MimeHandlerViewGuest navigates to the PDF extension URL.
|
||||
// 7. PDF extension resources are provided from bundle via
|
||||
// CefExtensionsBrowserClient::MaybeCreateResourceBundleRequestJob and
|
||||
// CefComponentExtensionResourceManager.
|
||||
// 8. The PDF extension communicates via the chrome.mimeHandlerPrivate Mojo
|
||||
// API which is implemented as described in
|
||||
// libcef/common/extensions/api/README.txt.
|
||||
// 9. The PDF extension requests a plugin to handle
|
||||
// kPDFPluginOutOfProcessMimeType which loads the PDF PPAPI plugin.
|
||||
// 10.Routing of print-related commands are handled by ChromePDFPrintClient
|
||||
// and CefPrintWebViewHelperDelegate in the renderer process.
|
||||
if (PdfExtensionEnabled()) {
|
||||
AddExtension(pdf_extension_util::GetManifest(),
|
||||
base::FilePath(FILE_PATH_LITERAL("pdf")));
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation based on ComponentLoader::Add.
|
||||
const Extension* CefExtensionSystem::AddExtension(
|
||||
const std::string& manifest_contents,
|
||||
const base::FilePath& root_directory) {
|
||||
base::DictionaryValue* manifest = ParseManifest(manifest_contents);
|
||||
if (!manifest)
|
||||
return NULL;
|
||||
|
||||
ComponentExtensionInfo info(manifest, root_directory);
|
||||
const Extension* extension = LoadExtension(info);
|
||||
delete manifest;
|
||||
|
||||
return extension;
|
||||
}
|
||||
|
||||
// Implementation based on ExtensionService::RemoveComponentExtension.
|
||||
void CefExtensionSystem::RemoveExtension(const std::string& extension_id) {
|
||||
scoped_refptr<const Extension> extension(
|
||||
registry_->enabled_extensions().GetByID(extension_id));
|
||||
UnloadExtension(extension_id, UnloadedExtensionInfo::REASON_UNINSTALL);
|
||||
if (extension.get()) {
|
||||
registry_->TriggerOnUninstalled(
|
||||
extension.get(), extensions::UNINSTALL_REASON_COMPONENT_REMOVED);
|
||||
}
|
||||
}
|
||||
|
||||
void CefExtensionSystem::Shutdown() {
|
||||
}
|
||||
|
||||
void CefExtensionSystem::InitForRegularProfile(bool extensions_enabled) {
|
||||
runtime_data_.reset(new RuntimeData(registry_));
|
||||
quota_service_.reset(new QuotaService);
|
||||
}
|
||||
|
||||
ExtensionService* CefExtensionSystem::extension_service() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RuntimeData* CefExtensionSystem::runtime_data() {
|
||||
return runtime_data_.get();
|
||||
}
|
||||
|
||||
ManagementPolicy* CefExtensionSystem::management_policy() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SharedUserScriptMaster* CefExtensionSystem::shared_user_script_master() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
StateStore* CefExtensionSystem::state_store() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
StateStore* CefExtensionSystem::rules_store() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
InfoMap* CefExtensionSystem::info_map() {
|
||||
if (!info_map_.get())
|
||||
info_map_ = new InfoMap;
|
||||
return info_map_.get();
|
||||
}
|
||||
|
||||
QuotaService* CefExtensionSystem::quota_service() {
|
||||
return quota_service_.get();
|
||||
}
|
||||
|
||||
// Implementation based on
|
||||
// ExtensionSystemImpl::RegisterExtensionWithRequestContexts.
|
||||
void CefExtensionSystem::RegisterExtensionWithRequestContexts(
|
||||
const Extension* extension) {
|
||||
// TODO(extensions): The |incognito_enabled| value should be set based on
|
||||
// manifest settings.
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO,
|
||||
FROM_HERE,
|
||||
base::Bind(&InfoMap::AddExtension,
|
||||
info_map(),
|
||||
make_scoped_refptr(extension),
|
||||
base::Time::Now(),
|
||||
true, // incognito_enabled
|
||||
false)); // notifications_disabled
|
||||
}
|
||||
|
||||
// Implementation based on
|
||||
// ExtensionSystemImpl::UnregisterExtensionWithRequestContexts.
|
||||
void CefExtensionSystem::UnregisterExtensionWithRequestContexts(
|
||||
const std::string& extension_id,
|
||||
const UnloadedExtensionInfo::Reason reason) {
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO,
|
||||
FROM_HERE,
|
||||
base::Bind(&InfoMap::RemoveExtension, info_map(), extension_id, reason));
|
||||
}
|
||||
|
||||
const OneShotEvent& CefExtensionSystem::ready() const {
|
||||
return ready_;
|
||||
}
|
||||
|
||||
ContentVerifier* CefExtensionSystem::content_verifier() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
scoped_ptr<ExtensionSet> CefExtensionSystem::GetDependentExtensions(
|
||||
const Extension* extension) {
|
||||
return make_scoped_ptr(new ExtensionSet());
|
||||
}
|
||||
|
||||
CefExtensionSystem::ComponentExtensionInfo::ComponentExtensionInfo(
|
||||
const base::DictionaryValue* manifest, const base::FilePath& directory)
|
||||
: manifest(manifest),
|
||||
root_directory(directory) {
|
||||
if (!root_directory.IsAbsolute()) {
|
||||
// This path structure is required by
|
||||
// url_request_util::MaybeCreateURLRequestResourceBundleJob.
|
||||
CHECK(PathService::Get(chrome::DIR_RESOURCES, &root_directory));
|
||||
root_directory = root_directory.Append(directory);
|
||||
}
|
||||
extension_id = GenerateId(manifest, root_directory);
|
||||
}
|
||||
|
||||
// Implementation based on ComponentLoader::Load and
|
||||
// ExtensionService::AddExtension.
|
||||
const Extension* CefExtensionSystem::LoadExtension(
|
||||
const ComponentExtensionInfo& info) {
|
||||
// TODO(abarth): We should REQUIRE_MODERN_MANIFEST_VERSION once we've updated
|
||||
// our component extensions to the new manifest version.
|
||||
int flags = Extension::REQUIRE_KEY;
|
||||
|
||||
std::string error;
|
||||
|
||||
scoped_refptr<const Extension> extension(Extension::Create(
|
||||
info.root_directory,
|
||||
Manifest::COMPONENT,
|
||||
*info.manifest,
|
||||
flags,
|
||||
&error));
|
||||
if (!extension.get()) {
|
||||
LOG(ERROR) << error;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CHECK_EQ(info.extension_id, extension->id()) << extension->name();
|
||||
|
||||
registry_->AddEnabled(extension.get());
|
||||
NotifyExtensionLoaded(extension.get());
|
||||
|
||||
return extension.get();
|
||||
}
|
||||
|
||||
// Implementation based on ExtensionService::UnloadExtension.
|
||||
void CefExtensionSystem::UnloadExtension(
|
||||
const std::string& extension_id,
|
||||
UnloadedExtensionInfo::Reason reason) {
|
||||
// Make sure the extension gets deleted after we return from this function.
|
||||
int include_mask =
|
||||
ExtensionRegistry::EVERYTHING & ~ExtensionRegistry::TERMINATED;
|
||||
scoped_refptr<const Extension> extension(
|
||||
registry_->GetExtensionById(extension_id, include_mask));
|
||||
|
||||
// This method can be called via PostTask, so the extension may have been
|
||||
// unloaded by the time this runs.
|
||||
if (!extension.get()) {
|
||||
// In case the extension may have crashed/uninstalled. Allow the profile to
|
||||
// clean up its RequestContexts.
|
||||
UnregisterExtensionWithRequestContexts(extension_id, reason);
|
||||
return;
|
||||
}
|
||||
|
||||
if (registry_->disabled_extensions().Contains(extension->id())) {
|
||||
registry_->RemoveDisabled(extension->id());
|
||||
// Make sure the profile cleans up its RequestContexts when an already
|
||||
// disabled extension is unloaded (since they are also tracking the disabled
|
||||
// extensions).
|
||||
UnregisterExtensionWithRequestContexts(extension_id, reason);
|
||||
// Don't send the unloaded notification. It was sent when the extension
|
||||
// was disabled.
|
||||
} else {
|
||||
// Remove the extension from the enabled list.
|
||||
registry_->RemoveEnabled(extension->id());
|
||||
NotifyExtensionUnloaded(extension.get(), reason);
|
||||
}
|
||||
|
||||
content::NotificationService::current()->Notify(
|
||||
extensions::NOTIFICATION_EXTENSION_REMOVED,
|
||||
content::Source<content::BrowserContext>(browser_context_),
|
||||
content::Details<const Extension>(extension.get()));
|
||||
}
|
||||
|
||||
// Implementation based on ExtensionService::NotifyExtensionLoaded.
|
||||
void CefExtensionSystem::NotifyExtensionLoaded(const Extension* extension) {
|
||||
// The URLRequestContexts need to be first to know that the extension
|
||||
// was loaded, otherwise a race can arise where a renderer that is created
|
||||
// for the extension may try to load an extension URL with an extension id
|
||||
// that the request context doesn't yet know about. The profile is responsible
|
||||
// for ensuring its URLRequestContexts appropriately discover the loaded
|
||||
// extension.
|
||||
RegisterExtensionWithRequestContexts(extension);
|
||||
|
||||
// Tell renderers about the new extension, unless it's a theme (renderers
|
||||
// don't need to know about themes).
|
||||
if (!extension->is_theme()) {
|
||||
for (content::RenderProcessHost::iterator i(
|
||||
content::RenderProcessHost::AllHostsIterator());
|
||||
!i.IsAtEnd(); i.Advance()) {
|
||||
content::RenderProcessHost* host = i.GetCurrentValue();
|
||||
if (host->GetBrowserContext() == browser_context_) {
|
||||
// We don't need to include tab permisisons here, since the extension
|
||||
// was just loaded.
|
||||
std::vector<ExtensionMsg_Loaded_Params> loaded_extensions(
|
||||
1, ExtensionMsg_Loaded_Params(extension,
|
||||
false /* no tab permissions */));
|
||||
host->Send(
|
||||
new ExtensionMsg_Loaded(loaded_extensions));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tell subsystems that use the EXTENSION_LOADED notification about the new
|
||||
// extension.
|
||||
//
|
||||
// NOTE: It is important that this happen after notifying the renderers about
|
||||
// the new extensions so that if we navigate to an extension URL in
|
||||
// ExtensionRegistryObserver::OnLoaded or
|
||||
// NOTIFICATION_EXTENSION_LOADED_DEPRECATED, the
|
||||
// renderer is guaranteed to know about it.
|
||||
registry_->TriggerOnLoaded(extension);
|
||||
|
||||
// Register plugins included with the extension.
|
||||
// Implementation based on PluginManager::OnExtensionLoaded.
|
||||
const MimeTypesHandler* handler = MimeTypesHandler::GetHandler(extension);
|
||||
if (handler && !handler->handler_url().empty()) {
|
||||
content::WebPluginInfo info;
|
||||
info.type = content::WebPluginInfo::PLUGIN_TYPE_BROWSER_PLUGIN;
|
||||
info.name = base::UTF8ToUTF16(extension->name());
|
||||
info.path = base::FilePath::FromUTF8Unsafe(extension->url().spec());
|
||||
|
||||
for (std::set<std::string>::const_iterator mime_type =
|
||||
handler->mime_type_set().begin();
|
||||
mime_type != handler->mime_type_set().end(); ++mime_type) {
|
||||
content::WebPluginMimeType mime_type_info;
|
||||
mime_type_info.mime_type = *mime_type;
|
||||
base::FilePath::StringType file_extension;
|
||||
if (net::GetPreferredExtensionForMimeType(*mime_type, &file_extension)) {
|
||||
mime_type_info.file_extensions.push_back(
|
||||
base::FilePath(file_extension).AsUTF8Unsafe());
|
||||
}
|
||||
info.mime_types.push_back(mime_type_info);
|
||||
}
|
||||
content::PluginService* plugin_service =
|
||||
content::PluginService::GetInstance();
|
||||
plugin_service->RefreshPlugins();
|
||||
plugin_service->RegisterInternalPlugin(info, true);
|
||||
}
|
||||
|
||||
content::NotificationService::current()->Notify(
|
||||
extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
|
||||
content::Source<content::BrowserContext>(browser_context_),
|
||||
content::Details<const Extension>(extension));
|
||||
}
|
||||
|
||||
// Implementation based on ExtensionService::NotifyExtensionUnloaded.
|
||||
void CefExtensionSystem::NotifyExtensionUnloaded(
|
||||
const Extension* extension,
|
||||
UnloadedExtensionInfo::Reason reason) {
|
||||
UnloadedExtensionInfo details(extension, reason);
|
||||
|
||||
// Unregister plugins included with the extension.
|
||||
// Implementation based on PluginManager::OnExtensionUnloaded.
|
||||
const MimeTypesHandler* handler = MimeTypesHandler::GetHandler(extension);
|
||||
if (handler && !handler->handler_url().empty()) {
|
||||
base::FilePath path =
|
||||
base::FilePath::FromUTF8Unsafe(extension->url().spec());
|
||||
content::PluginService* plugin_service =
|
||||
content::PluginService::GetInstance();
|
||||
plugin_service->UnregisterInternalPlugin(path);
|
||||
plugin_service->ForcePluginShutdown(path);
|
||||
plugin_service->RefreshPlugins();
|
||||
}
|
||||
|
||||
registry_->TriggerOnUnloaded(extension, reason);
|
||||
|
||||
content::NotificationService::current()->Notify(
|
||||
extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
|
||||
content::Source<content::BrowserContext>(browser_context_),
|
||||
content::Details<UnloadedExtensionInfo>(&details));
|
||||
|
||||
for (content::RenderProcessHost::iterator i(
|
||||
content::RenderProcessHost::AllHostsIterator());
|
||||
!i.IsAtEnd(); i.Advance()) {
|
||||
content::RenderProcessHost* host = i.GetCurrentValue();
|
||||
if (host->GetBrowserContext() == browser_context_)
|
||||
host->Send(new ExtensionMsg_Unloaded(extension->id()));
|
||||
}
|
||||
|
||||
UnregisterExtensionWithRequestContexts(extension->id(), reason);
|
||||
}
|
||||
|
||||
} // namespace extensions
|
|
@ -0,0 +1,124 @@
|
|||
// Copyright 2015 The Chromium Embedded Framework Authors.
|
||||
// Portions copyright 2014 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_EXTENSION_SYSTEM_H_
|
||||
#define CEF_LIBCEF_BROWSER_EXTENSIONS_EXTENSION_SYSTEM_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "extensions/browser/extension_system.h"
|
||||
#include "extensions/common/one_shot_event.h"
|
||||
|
||||
class BrowserContextKeyedServiceFactory;
|
||||
|
||||
namespace base {
|
||||
class FilePath;
|
||||
}
|
||||
|
||||
namespace content {
|
||||
class BrowserContext;
|
||||
}
|
||||
|
||||
namespace extensions {
|
||||
|
||||
class ExtensionRegistry;
|
||||
class InfoMap;
|
||||
class ProcessManager;
|
||||
class RendererStartupHelper;
|
||||
class SharedUserScriptMaster;
|
||||
|
||||
// Used to manage extensions.
|
||||
class CefExtensionSystem : public ExtensionSystem {
|
||||
public:
|
||||
explicit CefExtensionSystem(content::BrowserContext* browser_context);
|
||||
~CefExtensionSystem() override;
|
||||
|
||||
// Initializes the extension system.
|
||||
void Init();
|
||||
|
||||
// Add an extension. Returns the new Extension object on success or NULL on
|
||||
// failure.
|
||||
const Extension* AddExtension(const std::string& manifest_contents,
|
||||
const base::FilePath& root_directory);
|
||||
|
||||
// Remove an extension.
|
||||
void RemoveExtension(const std::string& extension_id);
|
||||
|
||||
// KeyedService implementation:
|
||||
void Shutdown() override;
|
||||
|
||||
// ExtensionSystem implementation:
|
||||
void InitForRegularProfile(bool extensions_enabled) override;
|
||||
ExtensionService* extension_service() override;
|
||||
RuntimeData* runtime_data() override;
|
||||
ManagementPolicy* management_policy() override;
|
||||
SharedUserScriptMaster* shared_user_script_master() override;
|
||||
StateStore* state_store() override;
|
||||
StateStore* rules_store() override;
|
||||
InfoMap* info_map() override;
|
||||
QuotaService* quota_service() override;
|
||||
void RegisterExtensionWithRequestContexts(
|
||||
const Extension* extension) override;
|
||||
void UnregisterExtensionWithRequestContexts(
|
||||
const std::string& extension_id,
|
||||
const UnloadedExtensionInfo::Reason reason) override;
|
||||
const OneShotEvent& ready() const override;
|
||||
ContentVerifier* content_verifier() override;
|
||||
scoped_ptr<ExtensionSet> GetDependentExtensions(
|
||||
const Extension* extension) override;
|
||||
|
||||
private:
|
||||
// Information about a registered component extension.
|
||||
struct ComponentExtensionInfo {
|
||||
ComponentExtensionInfo(const base::DictionaryValue* manifest,
|
||||
const base::FilePath& root_directory);
|
||||
|
||||
// The parsed contents of the extensions's manifest file.
|
||||
const base::DictionaryValue* manifest;
|
||||
|
||||
// Directory where the extension is stored.
|
||||
base::FilePath root_directory;
|
||||
|
||||
// The component extension's ID.
|
||||
std::string extension_id;
|
||||
};
|
||||
|
||||
// Loads a registered component extension.
|
||||
const Extension* LoadExtension(const ComponentExtensionInfo& info);
|
||||
|
||||
// Unload the specified extension.
|
||||
void UnloadExtension(
|
||||
const std::string& extension_id,
|
||||
extensions::UnloadedExtensionInfo::Reason reason);
|
||||
|
||||
// Handles sending notification that |extension| was loaded.
|
||||
void NotifyExtensionLoaded(const Extension* extension);
|
||||
|
||||
// Handles sending notification that |extension| was unloaded.
|
||||
void NotifyExtensionUnloaded(
|
||||
const Extension* extension,
|
||||
UnloadedExtensionInfo::Reason reason);
|
||||
|
||||
content::BrowserContext* browser_context_; // Not owned.
|
||||
|
||||
// Data to be accessed on the IO thread. Must outlive process_manager_.
|
||||
scoped_refptr<InfoMap> info_map_;
|
||||
|
||||
scoped_ptr<RuntimeData> runtime_data_;
|
||||
scoped_ptr<QuotaService> quota_service_;
|
||||
|
||||
// Signaled when the extension system has completed its startup tasks.
|
||||
OneShotEvent ready_;
|
||||
|
||||
// Sets of enabled/disabled/terminated/blacklisted extensions. Not owned.
|
||||
ExtensionRegistry* registry_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefExtensionSystem);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_EXTENSIONS_EXTENSION_SYSTEM_H_
|
|
@ -0,0 +1,55 @@
|
|||
// Copyright 2014 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/extension_system_factory.h"
|
||||
|
||||
#include "libcef/browser/extensions/extension_system.h"
|
||||
|
||||
#include "components/keyed_service/content/browser_context_dependency_manager.h"
|
||||
#include "extensions/browser/extension_prefs_factory.h"
|
||||
#include "extensions/browser/extension_registry_factory.h"
|
||||
|
||||
using content::BrowserContext;
|
||||
|
||||
namespace extensions {
|
||||
|
||||
ExtensionSystem* CefExtensionSystemFactory::GetForBrowserContext(
|
||||
BrowserContext* context) {
|
||||
return static_cast<CefExtensionSystem*>(
|
||||
GetInstance()->GetServiceForBrowserContext(context, true));
|
||||
}
|
||||
|
||||
// static
|
||||
CefExtensionSystemFactory* CefExtensionSystemFactory::GetInstance() {
|
||||
return Singleton<CefExtensionSystemFactory>::get();
|
||||
}
|
||||
|
||||
CefExtensionSystemFactory::CefExtensionSystemFactory()
|
||||
: ExtensionSystemProvider("CefExtensionSystem",
|
||||
BrowserContextDependencyManager::GetInstance()) {
|
||||
// Other factories that this factory depends on. See
|
||||
// libcef/common/extensions/api/README.txt for additional details.
|
||||
DependsOn(ExtensionPrefsFactory::GetInstance());
|
||||
DependsOn(ExtensionRegistryFactory::GetInstance());
|
||||
}
|
||||
|
||||
CefExtensionSystemFactory::~CefExtensionSystemFactory() {
|
||||
}
|
||||
|
||||
KeyedService* CefExtensionSystemFactory::BuildServiceInstanceFor(
|
||||
BrowserContext* context) const {
|
||||
return new CefExtensionSystem(context);
|
||||
}
|
||||
|
||||
BrowserContext* CefExtensionSystemFactory::GetBrowserContextToUse(
|
||||
BrowserContext* context) const {
|
||||
// Use a separate instance for incognito.
|
||||
return context;
|
||||
}
|
||||
|
||||
bool CefExtensionSystemFactory::ServiceIsCreatedWithBrowserContext() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace extensions
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright 2014 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_EXTENSION_SYSTEM_FACTORY_H_
|
||||
#define CEF_LIBCEF_BROWSER_EXTENSIONS_EXTENSION_SYSTEM_FACTORY_H_
|
||||
|
||||
#include "base/memory/singleton.h"
|
||||
#include "extensions/browser/extension_system_provider.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
// Factory that provides CefExtensionSystem.
|
||||
class CefExtensionSystemFactory : public ExtensionSystemProvider {
|
||||
public:
|
||||
// ExtensionSystemProvider implementation:
|
||||
ExtensionSystem* GetForBrowserContext(
|
||||
content::BrowserContext* context) override;
|
||||
|
||||
static CefExtensionSystemFactory* GetInstance();
|
||||
|
||||
private:
|
||||
friend struct DefaultSingletonTraits<CefExtensionSystemFactory>;
|
||||
|
||||
CefExtensionSystemFactory();
|
||||
~CefExtensionSystemFactory() override;
|
||||
|
||||
// BrowserContextKeyedServiceFactory implementation:
|
||||
KeyedService* BuildServiceInstanceFor(
|
||||
content::BrowserContext* context) const override;
|
||||
content::BrowserContext* GetBrowserContextToUse(
|
||||
content::BrowserContext* context) const override;
|
||||
bool ServiceIsCreatedWithBrowserContext() const override;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefExtensionSystemFactory);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_EXTENSIONS_EXTENSION_SYSTEM_FACTORY_H_
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright 2014 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/extension_web_contents_observer.h"
|
||||
|
||||
DEFINE_WEB_CONTENTS_USER_DATA_KEY(extensions::CefExtensionWebContentsObserver);
|
||||
|
||||
namespace extensions {
|
||||
|
||||
CefExtensionWebContentsObserver::CefExtensionWebContentsObserver(
|
||||
content::WebContents* web_contents)
|
||||
: ExtensionWebContentsObserver(web_contents) {
|
||||
}
|
||||
|
||||
CefExtensionWebContentsObserver::~CefExtensionWebContentsObserver() {
|
||||
}
|
||||
|
||||
} // namespace extensions
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright 2014 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_EXTENSION_WEB_CONTENTS_OBSERVER_H_
|
||||
#define CEF_LIBCEF_BROWSER_EXTENSIONS_EXTENSION_WEB_CONTENTS_OBSERVER_H_
|
||||
|
||||
#include "content/public/browser/web_contents_user_data.h"
|
||||
#include "extensions/browser/extension_web_contents_observer.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
// The CEF version of ExtensionWebContentsObserver.
|
||||
class CefExtensionWebContentsObserver
|
||||
: public ExtensionWebContentsObserver,
|
||||
public content::WebContentsUserData<CefExtensionWebContentsObserver> {
|
||||
private:
|
||||
friend class content::WebContentsUserData<CefExtensionWebContentsObserver>;
|
||||
|
||||
explicit CefExtensionWebContentsObserver(
|
||||
content::WebContents* web_contents);
|
||||
~CefExtensionWebContentsObserver() override;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefExtensionWebContentsObserver);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_EXTENSIONS_EXTENSION_WEB_CONTENTS_OBSERVER_H_
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2015 The Chromium Embedded Framework Authors.
|
||||
// Portions copyright 2014 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/extensions_api_client.h"
|
||||
|
||||
#include "libcef/browser/extensions/mime_handler_view_guest_delegate.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
CefExtensionsAPIClient::CefExtensionsAPIClient() {
|
||||
}
|
||||
|
||||
AppViewGuestDelegate* CefExtensionsAPIClient::CreateAppViewGuestDelegate()
|
||||
const {
|
||||
// TODO(extensions): Implement to support Apps.
|
||||
NOTREACHED();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
scoped_ptr<MimeHandlerViewGuestDelegate>
|
||||
CefExtensionsAPIClient::CreateMimeHandlerViewGuestDelegate(
|
||||
MimeHandlerViewGuest* guest) const {
|
||||
return make_scoped_ptr(new CefMimeHandlerViewGuestDelegate(guest));
|
||||
}
|
||||
|
||||
} // namespace extensions
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2015 The Chromium Embedded Framework Authors.
|
||||
// Portions copyright 2014 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_EXTENSIONS_API_CLIENT_H_
|
||||
#define CEF_LIBCEF_BROWSER_EXTENSIONS_EXTENSIONS_API_CLIENT_H_
|
||||
|
||||
#include "extensions/browser/api/extensions_api_client.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
class CefExtensionsAPIClient : public ExtensionsAPIClient {
|
||||
public:
|
||||
CefExtensionsAPIClient();
|
||||
|
||||
// ExtensionsAPIClient implementation.
|
||||
AppViewGuestDelegate* CreateAppViewGuestDelegate() const override;
|
||||
scoped_ptr<MimeHandlerViewGuestDelegate>
|
||||
CreateMimeHandlerViewGuestDelegate(
|
||||
MimeHandlerViewGuest* guest) const override;
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_EXTENSIONS_EXTENSIONS_API_CLIENT_H_
|
|
@ -0,0 +1,234 @@
|
|||
// Copyright 2015 The Chromium Embedded Framework Authors.
|
||||
// Portions copyright 2014 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/extensions_browser_client.h"
|
||||
|
||||
#include "libcef/browser/content_browser_client.h"
|
||||
#include "libcef/browser/extensions/component_extension_resource_manager.h"
|
||||
#include "libcef/browser/extensions/extension_system_factory.h"
|
||||
#include "libcef/browser/extensions/extensions_api_client.h"
|
||||
#include "libcef/browser/extensions/url_request_util.h"
|
||||
|
||||
#include "cef/libcef/browser/extensions/api/generated_api_registration.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "extensions/browser/api/extensions_api_client.h"
|
||||
#include "extensions/browser/api/generated_api_registration.h"
|
||||
#include "extensions/browser/api/runtime/runtime_api_delegate.h"
|
||||
#include "extensions/browser/app_sorting.h"
|
||||
#include "extensions/browser/event_router.h"
|
||||
#include "extensions/browser/extension_function_registry.h"
|
||||
#include "extensions/browser/extension_host_delegate.h"
|
||||
#include "extensions/browser/mojo/service_registration.h"
|
||||
#include "extensions/browser/null_app_sorting.h"
|
||||
#include "extensions/browser/url_request_util.h"
|
||||
|
||||
using content::BrowserContext;
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace extensions {
|
||||
|
||||
CefExtensionsBrowserClient::CefExtensionsBrowserClient()
|
||||
: api_client_(new CefExtensionsAPIClient),
|
||||
resource_manager_(new CefComponentExtensionResourceManager),
|
||||
event_router_forwarder_(new EventRouterForwarder) {
|
||||
}
|
||||
|
||||
CefExtensionsBrowserClient::~CefExtensionsBrowserClient() {
|
||||
}
|
||||
|
||||
bool CefExtensionsBrowserClient::IsShuttingDown() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CefExtensionsBrowserClient::AreExtensionsDisabled(
|
||||
const base::CommandLine& command_line,
|
||||
BrowserContext* context) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CefExtensionsBrowserClient::IsValidContext(BrowserContext* context) {
|
||||
return CefBrowserContextImpl::GetForContext(context) != NULL;
|
||||
}
|
||||
|
||||
bool CefExtensionsBrowserClient::IsSameContext(BrowserContext* first,
|
||||
BrowserContext* second) {
|
||||
return first == second;
|
||||
}
|
||||
|
||||
bool CefExtensionsBrowserClient::HasOffTheRecordContext(
|
||||
BrowserContext* context) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BrowserContext* CefExtensionsBrowserClient::GetOffTheRecordContext(
|
||||
BrowserContext* context) {
|
||||
// TODO(extensions): Do we need to support this?
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BrowserContext* CefExtensionsBrowserClient::GetOriginalContext(
|
||||
BrowserContext* context) {
|
||||
return context;
|
||||
}
|
||||
|
||||
bool CefExtensionsBrowserClient::IsGuestSession(
|
||||
BrowserContext* context) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CefExtensionsBrowserClient::IsExtensionIncognitoEnabled(
|
||||
const std::string& extension_id,
|
||||
content::BrowserContext* context) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CefExtensionsBrowserClient::CanExtensionCrossIncognito(
|
||||
const Extension* extension,
|
||||
content::BrowserContext* context) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
net::URLRequestJob*
|
||||
CefExtensionsBrowserClient::MaybeCreateResourceBundleRequestJob(
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate,
|
||||
const base::FilePath& directory_path,
|
||||
const std::string& content_security_policy,
|
||||
bool send_cors_header) {
|
||||
return url_request_util::MaybeCreateURLRequestResourceBundleJob(
|
||||
request,
|
||||
network_delegate,
|
||||
directory_path,
|
||||
content_security_policy,
|
||||
send_cors_header);
|
||||
}
|
||||
|
||||
bool CefExtensionsBrowserClient::AllowCrossRendererResourceLoad(
|
||||
net::URLRequest* request,
|
||||
bool is_incognito,
|
||||
const Extension* extension,
|
||||
InfoMap* extension_info_map) {
|
||||
bool allowed = false;
|
||||
if (url_request_util::AllowCrossRendererResourceLoad(
|
||||
request, is_incognito, extension, extension_info_map, &allowed)) {
|
||||
return allowed;
|
||||
}
|
||||
|
||||
// Couldn't determine if resource is allowed. Block the load.
|
||||
return false;
|
||||
}
|
||||
|
||||
PrefService* CefExtensionsBrowserClient::GetPrefServiceForContext(
|
||||
BrowserContext* context) {
|
||||
// TODO(extensions): Do we need a per-context PrefService?
|
||||
return CefContentBrowserClient::Get()->pref_service();
|
||||
}
|
||||
|
||||
void CefExtensionsBrowserClient::GetEarlyExtensionPrefsObservers(
|
||||
content::BrowserContext* context,
|
||||
std::vector<ExtensionPrefsObserver*>* observers) const {
|
||||
}
|
||||
|
||||
ProcessManagerDelegate*
|
||||
CefExtensionsBrowserClient::GetProcessManagerDelegate() const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
scoped_ptr<ExtensionHostDelegate>
|
||||
CefExtensionsBrowserClient::CreateExtensionHostDelegate() {
|
||||
// TODO(extensions): Implement to support Apps.
|
||||
NOTREACHED();
|
||||
return scoped_ptr<ExtensionHostDelegate>();
|
||||
}
|
||||
|
||||
bool CefExtensionsBrowserClient::DidVersionUpdate(BrowserContext* context) {
|
||||
// TODO(jamescook): We might want to tell extensions when app_shell updates.
|
||||
return false;
|
||||
}
|
||||
|
||||
void CefExtensionsBrowserClient::PermitExternalProtocolHandler() {
|
||||
}
|
||||
|
||||
scoped_ptr<AppSorting> CefExtensionsBrowserClient::CreateAppSorting() {
|
||||
return scoped_ptr<AppSorting>(new NullAppSorting);
|
||||
}
|
||||
|
||||
bool CefExtensionsBrowserClient::IsRunningInForcedAppMode() {
|
||||
return false;
|
||||
}
|
||||
|
||||
ApiActivityMonitor* CefExtensionsBrowserClient::GetApiActivityMonitor(
|
||||
BrowserContext* context) {
|
||||
// CEF doesn't monitor API function calls or events.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ExtensionSystemProvider*
|
||||
CefExtensionsBrowserClient::GetExtensionSystemFactory() {
|
||||
return CefExtensionSystemFactory::GetInstance();
|
||||
}
|
||||
|
||||
void CefExtensionsBrowserClient::RegisterExtensionFunctions(
|
||||
ExtensionFunctionRegistry* registry) const {
|
||||
// Register core extension-system APIs.
|
||||
core_api::GeneratedFunctionRegistry::RegisterAll(registry);
|
||||
|
||||
// CEF-only APIs.
|
||||
api::GeneratedFunctionRegistry::RegisterAll(registry);
|
||||
}
|
||||
|
||||
void CefExtensionsBrowserClient::RegisterMojoServices(
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const Extension* extension) const {
|
||||
RegisterServicesForFrame(render_frame_host, extension);
|
||||
}
|
||||
|
||||
scoped_ptr<RuntimeAPIDelegate>
|
||||
CefExtensionsBrowserClient::CreateRuntimeAPIDelegate(
|
||||
content::BrowserContext* context) const {
|
||||
// TODO(extensions): Implement to support Apps.
|
||||
NOTREACHED();
|
||||
return scoped_ptr<RuntimeAPIDelegate>();
|
||||
}
|
||||
|
||||
const ComponentExtensionResourceManager*
|
||||
CefExtensionsBrowserClient::GetComponentExtensionResourceManager() {
|
||||
return resource_manager_.get();
|
||||
}
|
||||
|
||||
void CefExtensionsBrowserClient::BroadcastEventToRenderers(
|
||||
const std::string& event_name,
|
||||
scoped_ptr<base::ListValue> args) {
|
||||
event_router_forwarder_->BroadcastEventToRenderers(
|
||||
event_name, args.Pass(), GURL());
|
||||
}
|
||||
|
||||
net::NetLog* CefExtensionsBrowserClient::GetNetLog() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ExtensionCache* CefExtensionsBrowserClient::GetExtensionCache() {
|
||||
// Only used by Chrome via ExtensionService.
|
||||
NOTREACHED();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool CefExtensionsBrowserClient::IsBackgroundUpdateAllowed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CefExtensionsBrowserClient::IsMinBrowserVersionSupported(
|
||||
const std::string& min_version) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void CefExtensionsBrowserClient::SetAPIClientForTest(
|
||||
ExtensionsAPIClient* api_client) {
|
||||
api_client_.reset(api_client);
|
||||
}
|
||||
|
||||
} // namespace extensions
|
|
@ -0,0 +1,102 @@
|
|||
// Copyright 2015 The Chromium Embedded Framework Authors.
|
||||
// Portions copyright 2014 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_EXTENSIONS_BROWSER_CLIENT_H_
|
||||
#define CEF_LIBCEF_BROWSER_EXTENSIONS_EXTENSIONS_BROWSER_CLIENT_H_
|
||||
|
||||
#include "libcef/browser/extensions/event_router_forwarder.h"
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "extensions/browser/extensions_browser_client.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
class ExtensionsAPIClient;
|
||||
|
||||
// An ExtensionsBrowserClient that supports a single content::BrowserContent
|
||||
// with no related incognito context.
|
||||
class CefExtensionsBrowserClient : public ExtensionsBrowserClient {
|
||||
public:
|
||||
CefExtensionsBrowserClient();
|
||||
~CefExtensionsBrowserClient() override;
|
||||
|
||||
// ExtensionsBrowserClient overrides:
|
||||
bool IsShuttingDown() override;
|
||||
bool AreExtensionsDisabled(const base::CommandLine& command_line,
|
||||
content::BrowserContext* context) override;
|
||||
bool IsValidContext(content::BrowserContext* context) override;
|
||||
bool IsSameContext(content::BrowserContext* first,
|
||||
content::BrowserContext* second) override;
|
||||
bool HasOffTheRecordContext(content::BrowserContext* context) override;
|
||||
content::BrowserContext* GetOffTheRecordContext(
|
||||
content::BrowserContext* context) override;
|
||||
content::BrowserContext* GetOriginalContext(
|
||||
content::BrowserContext* context) override;
|
||||
bool IsGuestSession(content::BrowserContext* context) const override;
|
||||
bool IsExtensionIncognitoEnabled(
|
||||
const std::string& extension_id,
|
||||
content::BrowserContext* context) const override;
|
||||
bool CanExtensionCrossIncognito(
|
||||
const Extension* extension,
|
||||
content::BrowserContext* context) const override;
|
||||
net::URLRequestJob* MaybeCreateResourceBundleRequestJob(
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate,
|
||||
const base::FilePath& directory_path,
|
||||
const std::string& content_security_policy,
|
||||
bool send_cors_header) override;
|
||||
bool AllowCrossRendererResourceLoad(net::URLRequest* request,
|
||||
bool is_incognito,
|
||||
const Extension* extension,
|
||||
InfoMap* extension_info_map) override;
|
||||
PrefService* GetPrefServiceForContext(
|
||||
content::BrowserContext* context) override;
|
||||
void GetEarlyExtensionPrefsObservers(
|
||||
content::BrowserContext* context,
|
||||
std::vector<ExtensionPrefsObserver*>* observers) const
|
||||
override;
|
||||
ProcessManagerDelegate* GetProcessManagerDelegate() const override;
|
||||
scoped_ptr<ExtensionHostDelegate>
|
||||
CreateExtensionHostDelegate() override;
|
||||
bool DidVersionUpdate(content::BrowserContext* context) override;
|
||||
void PermitExternalProtocolHandler() override;
|
||||
scoped_ptr<AppSorting> CreateAppSorting() override;
|
||||
bool IsRunningInForcedAppMode() override;
|
||||
ApiActivityMonitor* GetApiActivityMonitor(
|
||||
content::BrowserContext* context) override;
|
||||
ExtensionSystemProvider* GetExtensionSystemFactory() override;
|
||||
void RegisterExtensionFunctions(
|
||||
ExtensionFunctionRegistry* registry) const override;
|
||||
void RegisterMojoServices(content::RenderFrameHost* render_frame_host,
|
||||
const Extension* extension) const override;
|
||||
scoped_ptr<RuntimeAPIDelegate> CreateRuntimeAPIDelegate(
|
||||
content::BrowserContext* context) const override;
|
||||
const ComponentExtensionResourceManager*
|
||||
GetComponentExtensionResourceManager() override;
|
||||
void BroadcastEventToRenderers(const std::string& event_name,
|
||||
scoped_ptr<base::ListValue> args) override;
|
||||
net::NetLog* GetNetLog() override;
|
||||
ExtensionCache* GetExtensionCache() override;
|
||||
bool IsBackgroundUpdateAllowed() override;
|
||||
bool IsMinBrowserVersionSupported(const std::string& min_version) override;
|
||||
|
||||
// Sets the API client.
|
||||
void SetAPIClientForTest(ExtensionsAPIClient* api_client);
|
||||
|
||||
private:
|
||||
// Support for extension APIs.
|
||||
scoped_ptr<ExtensionsAPIClient> api_client_;
|
||||
|
||||
// Resource manager used to supply resources from pak files.
|
||||
scoped_ptr<ComponentExtensionResourceManager> resource_manager_;
|
||||
|
||||
scoped_refptr<EventRouterForwarder> event_router_forwarder_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefExtensionsBrowserClient);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_EXTENSIONS_EXTENSIONS_BROWSER_CLIENT_H_
|
|
@ -0,0 +1,135 @@
|
|||
// Copyright 2015 The Chromium Embedded Framework Authors.
|
||||
// Portions copyright 2014 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/mime_handler_view_guest_delegate.h"
|
||||
|
||||
#include "include/internal/cef_types_wrappers.h"
|
||||
#include "libcef/browser/browser_host_impl.h"
|
||||
#include "libcef/browser/browser_info.h"
|
||||
#include "libcef/browser/content_browser_client.h"
|
||||
#include "libcef/browser/extensions/extension_web_contents_observer.h"
|
||||
#include "libcef/browser/extensions/pdf_web_contents_helper_client.h"
|
||||
#include "libcef/browser/printing/print_view_manager.h"
|
||||
#include "libcef/browser/web_contents_view_osr.h"
|
||||
|
||||
#include "components/pdf/browser/pdf_web_contents_helper.h"
|
||||
#include "components/pdf/browser/pdf_web_contents_helper_client.h"
|
||||
#include "content/browser/browser_plugin/browser_plugin_guest.h"
|
||||
#include "content/browser/web_contents/web_contents_impl.h"
|
||||
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
namespace {
|
||||
|
||||
CefRefPtr<CefBrowserHostImpl> GetOwnerBrowser(
|
||||
extensions::MimeHandlerViewGuest* guest) {
|
||||
content::WebContents* owner_web_contents = guest->GetOwnerWebContents();
|
||||
CefRefPtr<CefBrowserHostImpl> owner_browser =
|
||||
CefBrowserHostImpl::GetBrowserForContents(owner_web_contents);
|
||||
DCHECK(owner_browser);
|
||||
return owner_browser;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CefMimeHandlerViewGuestDelegate::CefMimeHandlerViewGuestDelegate(
|
||||
MimeHandlerViewGuest* guest)
|
||||
: MimeHandlerViewGuestDelegate(guest), guest_(guest) {
|
||||
}
|
||||
|
||||
CefMimeHandlerViewGuestDelegate::~CefMimeHandlerViewGuestDelegate() {
|
||||
}
|
||||
|
||||
void CefMimeHandlerViewGuestDelegate::OverrideWebContentsCreateParams(
|
||||
content::WebContents::CreateParams* params) {
|
||||
DCHECK(params->guest_delegate);
|
||||
|
||||
CefRefPtr<CefBrowserHostImpl> owner_browser = GetOwnerBrowser(guest_);
|
||||
if (owner_browser->IsWindowless()) {
|
||||
CefWebContentsViewOSR* view_osr = new CefWebContentsViewOSR();
|
||||
params->view = view_osr;
|
||||
params->delegate_view = view_osr;
|
||||
}
|
||||
}
|
||||
|
||||
bool CefMimeHandlerViewGuestDelegate::OnGuestAttached(
|
||||
content::WebContentsView* guest_view,
|
||||
content::WebContentsView* parent_view) {
|
||||
// Do nothing when the browser is windowless.
|
||||
return GetOwnerBrowser(guest_)->IsWindowless();
|
||||
}
|
||||
|
||||
bool CefMimeHandlerViewGuestDelegate::OnGuestDetached(
|
||||
content::WebContentsView* guest_view,
|
||||
content::WebContentsView* parent_view) {
|
||||
// Do nothing when the browser is windowless.
|
||||
return GetOwnerBrowser(guest_)->IsWindowless();
|
||||
}
|
||||
|
||||
bool CefMimeHandlerViewGuestDelegate::CreateViewForWidget(
|
||||
content::WebContentsView* guest_view,
|
||||
content::RenderWidgetHost* render_widget_host) {
|
||||
CefRefPtr<CefBrowserHostImpl> owner_browser = GetOwnerBrowser(guest_);
|
||||
if (owner_browser->IsWindowless()) {
|
||||
static_cast<CefWebContentsViewOSR*>(guest_view)->CreateViewForWidget(
|
||||
render_widget_host, true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO(lazyboy): Investigate ways to move this out to /extensions.
|
||||
void CefMimeHandlerViewGuestDelegate::AttachHelpers() {
|
||||
content::WebContents* web_contents = guest_->web_contents();
|
||||
|
||||
// Associate state information with the new WebContents.
|
||||
content::RenderViewHost* view_host = web_contents->GetRenderViewHost();
|
||||
content::RenderFrameHost* main_frame_host = web_contents->GetMainFrame();
|
||||
scoped_refptr<CefBrowserInfo> info =
|
||||
CefContentBrowserClient::Get()->GetOrCreateBrowserInfo(
|
||||
view_host->GetProcess()->GetID(),
|
||||
view_host->GetRoutingID(),
|
||||
main_frame_host->GetProcess()->GetID(),
|
||||
main_frame_host->GetRoutingID());
|
||||
info->set_mime_handler_view(true);
|
||||
|
||||
CefRefPtr<CefBrowserHostImpl> owner_browser = GetOwnerBrowser(guest_);
|
||||
if (owner_browser->IsWindowless()) {
|
||||
// Use the OSR view instead of the default WebContentsViewGuest.
|
||||
content::WebContentsImpl* web_contents_impl =
|
||||
static_cast<content::WebContentsImpl*>(web_contents);
|
||||
CefWebContentsViewOSR* view_osr =
|
||||
static_cast<CefWebContentsViewOSR*>(
|
||||
web_contents_impl->GetView());
|
||||
view_osr->set_web_contents(web_contents);
|
||||
view_osr->set_guest(web_contents_impl->GetBrowserPluginGuest());
|
||||
}
|
||||
|
||||
printing::PrintViewManager::CreateForWebContents(web_contents);
|
||||
pdf::PDFWebContentsHelper::CreateForWebContentsWithClient(
|
||||
web_contents,
|
||||
scoped_ptr<pdf::PDFWebContentsHelperClient>(
|
||||
new CefPDFWebContentsHelperClient()));
|
||||
CefExtensionWebContentsObserver::CreateForWebContents(web_contents);
|
||||
}
|
||||
|
||||
bool CefMimeHandlerViewGuestDelegate::HandleContextMenu(
|
||||
content::WebContents* web_contents,
|
||||
const content::ContextMenuParams& params) {
|
||||
content::ContextMenuParams new_params = params;
|
||||
|
||||
gfx::Point guest_coordinates =
|
||||
static_cast<content::WebContentsImpl*>(web_contents)->
|
||||
GetBrowserPluginGuest()->GetScreenCoordinates(gfx::Point());
|
||||
|
||||
// Adjust (x,y) position for offset from guest to embedder.
|
||||
new_params.x += guest_coordinates.x();
|
||||
new_params.y += guest_coordinates.y();
|
||||
|
||||
return GetOwnerBrowser(guest_)->HandleContextMenu(web_contents, new_params);
|
||||
}
|
||||
|
||||
} // namespace extensions
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright 2015 The Chromium Embedded Framework Authors.
|
||||
// Portions copyright 2014 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_MIME_HANDLER_VIEW_GUEST_DELEGATE_H_
|
||||
#define CEF_LIBCEF_BROWSER_EXTENSIONS_MIME_HANDLER_VIEW_GUEST_DELEGATE_H_
|
||||
|
||||
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h"
|
||||
|
||||
namespace content {
|
||||
struct ContextMenuParams;
|
||||
}
|
||||
|
||||
namespace extensions {
|
||||
|
||||
class CefMimeHandlerViewGuestDelegate : public MimeHandlerViewGuestDelegate {
|
||||
public:
|
||||
explicit CefMimeHandlerViewGuestDelegate(MimeHandlerViewGuest* guest);
|
||||
~CefMimeHandlerViewGuestDelegate() override;
|
||||
|
||||
// MimeHandlerViewGuestDelegate methods.
|
||||
void OverrideWebContentsCreateParams(
|
||||
content::WebContents::CreateParams* params) override;
|
||||
bool OnGuestAttached(content::WebContentsView* guest_view,
|
||||
content::WebContentsView* parent_view) override;
|
||||
bool OnGuestDetached(content::WebContentsView* guest_view,
|
||||
content::WebContentsView* parent_view) override;
|
||||
bool CreateViewForWidget(
|
||||
content::WebContentsView* guest_view,
|
||||
content::RenderWidgetHost* render_widget_host) override;
|
||||
void AttachHelpers() override;
|
||||
bool HandleContextMenu(content::WebContents* web_contents,
|
||||
const content::ContextMenuParams& params) override;
|
||||
|
||||
private:
|
||||
MimeHandlerViewGuest* guest_; // Owns us.
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefMimeHandlerViewGuestDelegate);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_EXTENSIONS_MIME_HANDLER_VIEW_GUEST_DELEGATE_H_
|
|
@ -0,0 +1,54 @@
|
|||
// Copyright 2015 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/pdf_extension_util.h"
|
||||
|
||||
#include "base/strings/string_util.h"
|
||||
#include "chrome/common/chrome_switches.h"
|
||||
#include "grit/cef_resources.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
|
||||
namespace extensions {
|
||||
namespace pdf_extension_util {
|
||||
|
||||
namespace {
|
||||
|
||||
// Tags in the manifest to be replaced.
|
||||
const char kNameTag[] = "<NAME>";
|
||||
const char kIndexTag[] = "<INDEX>";
|
||||
|
||||
// The index html pages to load for the material and non-material version of
|
||||
// the viewer.
|
||||
const char kRegularIndex[] = "index.html";
|
||||
const char kMaterialIndex[] = "index-material.html";
|
||||
|
||||
} // namespace
|
||||
|
||||
// These should match the keys for the Chrome and Chromium PDF Viewer entries in
|
||||
// chrome/browser/resources/plugin_metadata/plugins_*.json.
|
||||
#if defined(GOOGLE_CHROME_BUILD)
|
||||
const char kPdfResourceIdentifier[] = "google-chrome-pdf";
|
||||
#else
|
||||
const char kPdfResourceIdentifier[] = "chromium-pdf";
|
||||
#endif
|
||||
|
||||
const char kPdfPluginName[] = "Chromium PDF Viewer";
|
||||
|
||||
std::string GetManifest() {
|
||||
std::string manifest_contents =
|
||||
ResourceBundle::GetSharedInstance().GetRawDataResource(
|
||||
IDR_PDF_MANIFEST).as_string();
|
||||
DCHECK(manifest_contents.find(kNameTag) != std::string::npos);
|
||||
ReplaceFirstSubstringAfterOffset(
|
||||
&manifest_contents, 0, kNameTag, kPdfPluginName);
|
||||
|
||||
DCHECK(manifest_contents.find(kIndexTag) != std::string::npos);
|
||||
std::string index = switches::PdfMaterialUIEnabled() ?
|
||||
kMaterialIndex : kRegularIndex;
|
||||
ReplaceSubstringsAfterOffset(&manifest_contents, 0, kIndexTag, index);
|
||||
return manifest_contents;
|
||||
}
|
||||
|
||||
} // namespace pdf_extension_util
|
||||
} // namespace extensions
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright 2015 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_PDF_EXTENSION_UTIL_H_
|
||||
#define CEF_LIBCEF_BROWSER_EXTENSIONS_PDF_EXTENSION_UTIL_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace extensions {
|
||||
namespace pdf_extension_util {
|
||||
|
||||
// The ResourceIdentifier for the PDF Viewer plugin.
|
||||
extern const char kPdfResourceIdentifier[];
|
||||
|
||||
// The name of the PDF Viewer plugin.
|
||||
extern const char kPdfPluginName[];
|
||||
|
||||
// Return the extensions manifest for PDF. The manifest is loaded from
|
||||
// browser_resources.grd and certain fields are replaced based on what chrome
|
||||
// flags are enabled.
|
||||
std::string GetManifest();
|
||||
|
||||
} // namespace pdf_extension_util
|
||||
} // namespace extensions
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_EXTENSIONS_PDF_EXTENSION_UTIL_H_
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright 2014 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/pdf_web_contents_helper_client.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
CefPDFWebContentsHelperClient::CefPDFWebContentsHelperClient() {
|
||||
}
|
||||
|
||||
CefPDFWebContentsHelperClient::~CefPDFWebContentsHelperClient() {
|
||||
}
|
||||
|
||||
void CefPDFWebContentsHelperClient::UpdateLocationBar(
|
||||
content::WebContents* contents) {
|
||||
}
|
||||
|
||||
void CefPDFWebContentsHelperClient::UpdateContentRestrictions(
|
||||
content::WebContents* contents,
|
||||
int content_restrictions) {
|
||||
}
|
||||
|
||||
void CefPDFWebContentsHelperClient::OnPDFHasUnsupportedFeature(
|
||||
content::WebContents* contents) {
|
||||
}
|
||||
|
||||
void CefPDFWebContentsHelperClient::OnSaveURL(
|
||||
content::WebContents* contents) {
|
||||
}
|
||||
|
||||
} // namespace extensions
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright 2014 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_PDF_WEB_CONTENTS_HELPER_CLIENT_H_
|
||||
#define CEF_LIBCEF_BROWSER_EXTENSIONS_PDF_WEB_CONTENTS_HELPER_CLIENT_H_
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "components/pdf/browser/pdf_web_contents_helper_client.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
class CefPDFWebContentsHelperClient
|
||||
: public pdf::PDFWebContentsHelperClient {
|
||||
public:
|
||||
CefPDFWebContentsHelperClient();
|
||||
~CefPDFWebContentsHelperClient() override;
|
||||
|
||||
private:
|
||||
// pdf::PDFWebContentsHelperClient:
|
||||
void UpdateLocationBar(content::WebContents* contents) override;
|
||||
|
||||
void UpdateContentRestrictions(content::WebContents* contents,
|
||||
int content_restrictions) override;
|
||||
|
||||
void OnPDFHasUnsupportedFeature(content::WebContents* contents) override;
|
||||
|
||||
void OnSaveURL(content::WebContents* contents) override;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefPDFWebContentsHelperClient);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_EXTENSIONS_PDF_WEB_CONTENTS_HELPER_CLIENT_H_
|
|
@ -0,0 +1,217 @@
|
|||
// 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_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;
|
||||
}
|
||||
|
||||
} // namespace extensions
|
|
@ -0,0 +1,96 @@
|
|||
// 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);
|
||||
|
||||
// |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_
|
|
@ -0,0 +1,165 @@
|
|||
// Copyright 2015 The Chromium Embedded Framework Authors.
|
||||
// Portions copyright 2014 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/url_request_util.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/task_runner_util.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/resource_request_info.h"
|
||||
#include "extensions/browser/component_extension_resource_manager.h"
|
||||
#include "extensions/browser/extension_protocols.h"
|
||||
#include "extensions/browser/extensions_browser_client.h"
|
||||
#include "extensions/browser/info_map.h"
|
||||
#include "extensions/browser/url_request_util.h"
|
||||
#include "extensions/common/file_util.h"
|
||||
#include "net/base/mime_util.h"
|
||||
#include "net/base/net_errors.h"
|
||||
#include "net/http/http_request_headers.h"
|
||||
#include "net/http/http_response_headers.h"
|
||||
#include "net/http/http_response_info.h"
|
||||
#include "net/url_request/url_request.h"
|
||||
#include "net/url_request/url_request_simple_job.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
using content::ResourceType;
|
||||
using extensions::ExtensionsBrowserClient;
|
||||
|
||||
namespace {
|
||||
|
||||
// A request for an extension resource in a Chrome .pak file. These are used
|
||||
// by component extensions.
|
||||
class URLRequestResourceBundleJob : public net::URLRequestSimpleJob {
|
||||
public:
|
||||
URLRequestResourceBundleJob(net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate,
|
||||
const base::FilePath& filename,
|
||||
int resource_id,
|
||||
const std::string& content_security_policy,
|
||||
bool send_cors_header)
|
||||
: net::URLRequestSimpleJob(request, network_delegate),
|
||||
filename_(filename),
|
||||
resource_id_(resource_id),
|
||||
weak_factory_(this) {
|
||||
// Leave cache headers out of resource bundle requests.
|
||||
response_info_.headers = extensions::BuildHttpHeaders(
|
||||
content_security_policy, send_cors_header, base::Time());
|
||||
}
|
||||
|
||||
// Overridden from URLRequestSimpleJob:
|
||||
int GetRefCountedData(
|
||||
std::string* mime_type,
|
||||
std::string* charset,
|
||||
scoped_refptr<base::RefCountedMemory>* data,
|
||||
const net::CompletionCallback& callback) const override {
|
||||
const ResourceBundle& rb = ResourceBundle::GetSharedInstance();
|
||||
*data = rb.LoadDataResourceBytes(resource_id_);
|
||||
|
||||
// Add the Content-Length header now that we know the resource length.
|
||||
response_info_.headers->AddHeader(
|
||||
base::StringPrintf("%s: %s", net::HttpRequestHeaders::kContentLength,
|
||||
base::UintToString((*data)->size()).c_str()));
|
||||
|
||||
std::string* read_mime_type = new std::string;
|
||||
bool posted = base::PostTaskAndReplyWithResult(
|
||||
BrowserThread::GetBlockingPool(), FROM_HERE,
|
||||
base::Bind(&net::GetMimeTypeFromFile, filename_,
|
||||
base::Unretained(read_mime_type)),
|
||||
base::Bind(&URLRequestResourceBundleJob::OnMimeTypeRead,
|
||||
weak_factory_.GetWeakPtr(), mime_type, charset, *data,
|
||||
base::Owned(read_mime_type), callback));
|
||||
DCHECK(posted);
|
||||
|
||||
return net::ERR_IO_PENDING;
|
||||
}
|
||||
|
||||
void GetResponseInfo(net::HttpResponseInfo* info) override {
|
||||
*info = response_info_;
|
||||
}
|
||||
|
||||
private:
|
||||
~URLRequestResourceBundleJob() override {}
|
||||
|
||||
void OnMimeTypeRead(std::string* out_mime_type,
|
||||
std::string* charset,
|
||||
scoped_refptr<base::RefCountedMemory> data,
|
||||
std::string* read_mime_type,
|
||||
const net::CompletionCallback& callback,
|
||||
bool read_result) {
|
||||
*out_mime_type = *read_mime_type;
|
||||
if (StartsWithASCII(*read_mime_type, "text/", false)) {
|
||||
// All of our HTML files should be UTF-8 and for other resource types
|
||||
// (like images), charset doesn't matter.
|
||||
DCHECK(base::IsStringUTF8(base::StringPiece(
|
||||
reinterpret_cast<const char*>(data->front()), data->size())));
|
||||
*charset = "utf-8";
|
||||
}
|
||||
int result = read_result ? net::OK : net::ERR_INVALID_URL;
|
||||
callback.Run(result);
|
||||
}
|
||||
|
||||
// We need the filename of the resource to determine the mime type.
|
||||
base::FilePath filename_;
|
||||
|
||||
// The resource bundle id to load.
|
||||
int resource_id_;
|
||||
|
||||
net::HttpResponseInfo response_info_;
|
||||
|
||||
mutable base::WeakPtrFactory<URLRequestResourceBundleJob> weak_factory_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace extensions {
|
||||
namespace url_request_util {
|
||||
|
||||
net::URLRequestJob* MaybeCreateURLRequestResourceBundleJob(
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate,
|
||||
const base::FilePath& directory_path,
|
||||
const std::string& content_security_policy,
|
||||
bool send_cors_header) {
|
||||
base::FilePath resources_path;
|
||||
base::FilePath relative_path;
|
||||
// Try to load extension resources from chrome resource file if
|
||||
// directory_path is a descendant of resources_path. This path structure is
|
||||
// set up by CefExtensionSystem::ComponentExtensionInfo.
|
||||
if (PathService::Get(chrome::DIR_RESOURCES, &resources_path) &&
|
||||
// Since component extension resources are included in
|
||||
// component_extension_resources.pak file in resources_path, calculate
|
||||
// extension relative path against resources_path.
|
||||
resources_path.AppendRelativePath(directory_path, &relative_path)) {
|
||||
base::FilePath request_path =
|
||||
extensions::file_util::ExtensionURLToRelativeFilePath(request->url());
|
||||
int resource_id = 0;
|
||||
if (ExtensionsBrowserClient::Get()
|
||||
->GetComponentExtensionResourceManager()
|
||||
->IsComponentExtensionResource(
|
||||
directory_path, request_path, &resource_id)) {
|
||||
relative_path = relative_path.Append(request_path);
|
||||
relative_path = relative_path.NormalizePathSeparators();
|
||||
return new URLRequestResourceBundleJob(request,
|
||||
network_delegate,
|
||||
relative_path,
|
||||
resource_id,
|
||||
content_security_policy,
|
||||
send_cors_header);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} // namespace url_request_util
|
||||
} // namespace extensions
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright 2015 The Chromium Embedded Framework Authors.
|
||||
// Portions copyright 2014 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_URL_REQUEST_UTIL_H_
|
||||
#define CEF_LIBCEF_BROWSER_EXTENSIONS_URL_REQUEST_UTIL_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace base {
|
||||
class FilePath;
|
||||
}
|
||||
|
||||
namespace net {
|
||||
class NetworkDelegate;
|
||||
class URLRequest;
|
||||
class URLRequestJob;
|
||||
}
|
||||
|
||||
namespace extensions {
|
||||
class Extension;
|
||||
class InfoMap;
|
||||
|
||||
// Utilities related to URLRequest jobs for extension resources. Based on
|
||||
// chrome/browser/extensions/chrome_url_request_util.cc.
|
||||
namespace url_request_util {
|
||||
|
||||
// Creates a URLRequestJob for loading component extension resources out of
|
||||
// a CEF resource bundle. Returns NULL if the requested resource is not a
|
||||
// component extension resource.
|
||||
net::URLRequestJob* MaybeCreateURLRequestResourceBundleJob(
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate,
|
||||
const base::FilePath& directory_path,
|
||||
const std::string& content_security_policy,
|
||||
bool send_cors_header);
|
||||
|
||||
} // namespace url_request_util
|
||||
} // namespace extensions
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_EXTENSIONS_URL_REQUEST_UTIL_H_
|
|
@ -4,29 +4,33 @@
|
|||
// found in the LICENSE file.
|
||||
|
||||
#include "libcef/browser/internal_scheme_handler.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "libcef/common/content_client.h"
|
||||
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "net/base/mime_util.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
|
||||
namespace scheme {
|
||||
|
||||
namespace {
|
||||
|
||||
base::FilePath FilePathFromASCII(const std::string& str) {
|
||||
#if defined(OS_WIN)
|
||||
return base::FilePath(base::ASCIIToUTF16(str));
|
||||
#else
|
||||
return base::FilePath(str);
|
||||
#endif
|
||||
}
|
||||
|
||||
static std::string GetMimeType(const std::string& filename) {
|
||||
if (EndsWith(filename, ".html", false)) {
|
||||
return "text/html";
|
||||
} else if (EndsWith(filename, ".css", false)) {
|
||||
return "text/css";
|
||||
} else if (EndsWith(filename, ".jpg", false)) {
|
||||
return "image/jpeg";
|
||||
} else if (EndsWith(filename, ".js", false)) {
|
||||
return "application/javascript";
|
||||
} else if (EndsWith(filename, ".png", false)) {
|
||||
return "image/png";
|
||||
} else if (EndsWith(filename, ".gif", false)) {
|
||||
return "image/gif";
|
||||
}
|
||||
std::string mime_type;
|
||||
if (net::GetMimeTypeFromFile(FilePathFromASCII(filename), &mime_type))
|
||||
return mime_type;
|
||||
|
||||
NOTREACHED() << "No known mime type for file: " << filename.c_str();
|
||||
return "text/plain";
|
||||
}
|
||||
|
|
|
@ -33,8 +33,12 @@ CefString GetLabel(int message_id) {
|
|||
|
||||
} // namespace
|
||||
|
||||
CefMenuCreator::CefMenuCreator(CefBrowserHostImpl* browser)
|
||||
: browser_(browser) {
|
||||
CefMenuCreator::CefMenuCreator(content::WebContents* web_contents,
|
||||
CefBrowserHostImpl* browser)
|
||||
: content::WebContentsObserver(web_contents),
|
||||
browser_(browser) {
|
||||
DCHECK(web_contents);
|
||||
DCHECK(browser_);
|
||||
model_ = new CefMenuModelImpl(this);
|
||||
}
|
||||
|
||||
|
@ -45,10 +49,10 @@ CefMenuCreator::~CefMenuCreator() {
|
|||
}
|
||||
|
||||
bool CefMenuCreator::IsShowingContextMenu() {
|
||||
content::WebContents* web_contents = browser_->GetWebContents();
|
||||
if (!web_contents)
|
||||
if (!web_contents())
|
||||
return false;
|
||||
content::RenderWidgetHostView* view = web_contents->GetRenderWidgetHostView();
|
||||
content::RenderWidgetHostView* view =
|
||||
web_contents()->GetRenderWidgetHostView();
|
||||
return (view && view->IsShowingContextMenu());
|
||||
}
|
||||
|
||||
|
@ -162,12 +166,12 @@ void CefMenuCreator::MenuWillShow(CefRefPtr<CefMenuModelImpl> source) {
|
|||
if (source.get() != model_.get())
|
||||
return;
|
||||
|
||||
content::WebContents* web_contents = browser_->GetWebContents();
|
||||
if (!web_contents)
|
||||
if (!web_contents())
|
||||
return;
|
||||
|
||||
// Notify the host before showing the context menu.
|
||||
content::RenderWidgetHostView* view = web_contents->GetRenderWidgetHostView();
|
||||
content::RenderWidgetHostView* view =
|
||||
web_contents()->GetRenderWidgetHostView();
|
||||
if (view)
|
||||
view->SetShowingContextMenu(true);
|
||||
}
|
||||
|
@ -187,14 +191,13 @@ void CefMenuCreator::MenuClosed(CefRefPtr<CefMenuModelImpl> source) {
|
|||
}
|
||||
}
|
||||
|
||||
if (IsShowingContextMenu()) {
|
||||
if (IsShowingContextMenu() && web_contents()) {
|
||||
// Notify the host after closing the context menu.
|
||||
content::WebContents* web_contents = browser_->GetWebContents();
|
||||
content::RenderWidgetHostView* view =
|
||||
web_contents->GetRenderWidgetHostView();
|
||||
web_contents()->GetRenderWidgetHostView();
|
||||
if (view)
|
||||
view->SetShowingContextMenu(false);
|
||||
web_contents->NotifyContextMenuClosed(params_.custom_context);
|
||||
web_contents()->NotifyContextMenuClosed(params_.custom_context);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,15 +9,18 @@
|
|||
#include "libcef/browser/menu_model_impl.h"
|
||||
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "content/public/common/context_menu_params.h"
|
||||
|
||||
namespace content {
|
||||
class RenderFrameHost;
|
||||
class WebContents;
|
||||
};
|
||||
|
||||
class CefBrowserHostImpl;
|
||||
|
||||
class CefMenuCreator : public CefMenuModelImpl::Delegate {
|
||||
class CefMenuCreator : public CefMenuModelImpl::Delegate,
|
||||
public content::WebContentsObserver {
|
||||
public:
|
||||
// Used for OS-specific menu implementations.
|
||||
class Runner {
|
||||
|
@ -28,7 +31,8 @@ class CefMenuCreator : public CefMenuModelImpl::Delegate {
|
|||
virtual bool FormatLabel(base::string16& label) { return false; }
|
||||
};
|
||||
|
||||
explicit CefMenuCreator(CefBrowserHostImpl* browser);
|
||||
CefMenuCreator(content::WebContents* web_contents,
|
||||
CefBrowserHostImpl* browser);
|
||||
~CefMenuCreator() override;
|
||||
|
||||
// Returns true if the context menu is currently showing.
|
||||
|
|
|
@ -56,5 +56,6 @@ scoped_ptr<ResourceHost> CefBrowserPepperHostFactory::CreateResourceHost(
|
|||
}
|
||||
}
|
||||
|
||||
NOTREACHED() << "Unhandled message type: " << message.type();
|
||||
return scoped_ptr<ResourceHost>();
|
||||
}
|
||||
|
|
|
@ -18,12 +18,6 @@ namespace {
|
|||
|
||||
base::StaticAtomicSequenceNumber g_next_id;
|
||||
|
||||
CefRefPtr<CefBrowserContextImpl> GetImpl(CefRefPtr<CefBrowserContext> context) {
|
||||
if (context->IsProxy())
|
||||
return static_cast<CefBrowserContextProxy*>(context.get())->parent();
|
||||
return static_cast<CefBrowserContextImpl*>(context.get());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
|
@ -106,7 +100,8 @@ scoped_refptr<CefBrowserContext> CefRequestContextImpl::GetBrowserContext() {
|
|||
|
||||
if (other_.get()) {
|
||||
// Share storage with |other_|.
|
||||
parent = GetImpl(other_->GetBrowserContext());
|
||||
parent = CefBrowserContextImpl::GetForContext(
|
||||
other_->GetBrowserContext().get());
|
||||
}
|
||||
|
||||
if (!parent.get()) {
|
||||
|
@ -136,6 +131,7 @@ scoped_refptr<CefBrowserContext> CefRequestContextImpl::GetBrowserContext() {
|
|||
// Use a proxy that will execute handler callbacks where appropriate and
|
||||
// otherwise forward all requests to the parent implementation.
|
||||
browser_context_ = new CefBrowserContextProxy(handler_, parent);
|
||||
browser_context_->Initialize();
|
||||
} else {
|
||||
// Use the parent implementation directly.
|
||||
browser_context_ = parent;
|
||||
|
@ -152,7 +148,9 @@ scoped_refptr<CefBrowserContext> CefRequestContextImpl::GetBrowserContext() {
|
|||
}
|
||||
|
||||
if (!request_context_impl_) {
|
||||
request_context_impl_ = GetImpl(browser_context_)->request_context().get();
|
||||
request_context_impl_ =
|
||||
CefBrowserContextImpl::GetForContext(browser_context_.get())->
|
||||
request_context().get();
|
||||
DCHECK(request_context_impl_);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,11 @@
|
|||
#include "net/ssl/client_cert_store_mac.h"
|
||||
#endif
|
||||
|
||||
CefResourceContext::CefResourceContext() {
|
||||
CefResourceContext::CefResourceContext(
|
||||
bool is_off_the_record,
|
||||
extensions::InfoMap* extension_info_map)
|
||||
: is_off_the_record_(is_off_the_record),
|
||||
extension_info_map_(extension_info_map) {
|
||||
}
|
||||
|
||||
CefResourceContext::~CefResourceContext() {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "content/public/browser/resource_context.h"
|
||||
#include "extensions/browser/info_map.h"
|
||||
|
||||
class CefURLRequestContextGetter;
|
||||
|
||||
|
@ -20,7 +21,8 @@ class CefURLRequestContextGetter;
|
|||
// See browser_context.h for an object relationship diagram.
|
||||
class CefResourceContext : public content::ResourceContext {
|
||||
public:
|
||||
CefResourceContext();
|
||||
CefResourceContext(bool is_off_the_record,
|
||||
extensions::InfoMap* extension_info_map);
|
||||
~CefResourceContext() override;
|
||||
|
||||
// ResourceContext implementation.
|
||||
|
@ -31,9 +33,18 @@ class CefResourceContext : public content::ResourceContext {
|
|||
void set_url_request_context_getter(
|
||||
scoped_refptr<CefURLRequestContextGetter> getter);
|
||||
|
||||
// State transferred from the BrowserContext for use on the IO thread.
|
||||
bool IsOffTheRecord() const { return is_off_the_record_; }
|
||||
const extensions::InfoMap* GetExtensionInfoMap() const {
|
||||
return extension_info_map_.get();
|
||||
}
|
||||
|
||||
private:
|
||||
scoped_refptr<CefURLRequestContextGetter> getter_;
|
||||
|
||||
bool is_off_the_record_;
|
||||
scoped_refptr<extensions::InfoMap> extension_info_map_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefResourceContext);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,18 +1,30 @@
|
|||
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that can
|
||||
// be found in the LICENSE file.
|
||||
// Copyright 2015 The Chromium Embedded Framework Authors.
|
||||
// Portions copyright 2014 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/resource_dispatcher_host_delegate.h"
|
||||
#include "libcef/browser/browser_host_impl.h"
|
||||
#include "libcef/browser/extensions/api/streams_private/streams_private_api.h"
|
||||
#include "libcef/browser/origin_whitelist_impl.h"
|
||||
#include "libcef/browser/resource_context.h"
|
||||
#include "libcef/browser/thread_util.h"
|
||||
#include "libcef/common/request_impl.h"
|
||||
#include "libcef/common/extensions/extensions_util.h"
|
||||
|
||||
#include "base/guid.h"
|
||||
#include "base/memory/scoped_vector.h"
|
||||
#include "components/navigation_interception/intercept_navigation_resource_throttle.h"
|
||||
#include "components/navigation_interception/navigation_params.h"
|
||||
#include "content/public/browser/plugin_service.h"
|
||||
#include "content/public/browser/plugin_service_filter.h"
|
||||
#include "content/public/browser/resource_request_info.h"
|
||||
#include "content/public/browser/stream_info.h"
|
||||
#include "content/public/common/resource_response.h"
|
||||
#include "content/public/common/webplugininfo.h"
|
||||
#include "extensions/common/constants.h"
|
||||
#include "extensions/common/extension.h"
|
||||
#include "extensions/common/manifest_handlers/mime_types_handler.h"
|
||||
#include "net/http/http_response_headers.h"
|
||||
#include "net/url_request/url_request.h"
|
||||
|
||||
|
@ -29,7 +41,6 @@ bool NavigationOnUIThread(
|
|||
|
||||
CefRefPtr<CefBrowserHostImpl> browser =
|
||||
CefBrowserHostImpl::GetBrowserForContents(source);
|
||||
DCHECK(browser.get());
|
||||
if (browser.get()) {
|
||||
CefRefPtr<CefClient> client = browser->GetClient();
|
||||
if (client.get()) {
|
||||
|
@ -50,6 +61,72 @@ bool NavigationOnUIThread(
|
|||
return ignore_navigation;
|
||||
}
|
||||
|
||||
// TODO(raymes): This won't return the right result if plugins haven't been
|
||||
// loaded yet. Fixing this properly really requires fixing crbug.com/443466.
|
||||
bool IsPluginEnabledForExtension(const extensions::Extension* extension,
|
||||
const content::ResourceRequestInfo* info,
|
||||
const std::string& mime_type,
|
||||
const GURL& url) {
|
||||
content::PluginService* service = content::PluginService::GetInstance();
|
||||
std::vector<content::WebPluginInfo> plugins;
|
||||
service->GetPluginInfoArray(url, mime_type, true, &plugins, nullptr);
|
||||
content::PluginServiceFilter* filter = service->GetFilter();
|
||||
|
||||
for (auto& plugin : plugins) {
|
||||
// Check that the plugin is running the extension.
|
||||
if (plugin.path !=
|
||||
base::FilePath::FromUTF8Unsafe(extension->url().spec())) {
|
||||
continue;
|
||||
}
|
||||
// Check that the plugin is actually enabled.
|
||||
if (!filter || filter->IsPluginAvailable(info->GetChildID(),
|
||||
info->GetRenderFrameID(),
|
||||
info->GetContext(),
|
||||
url,
|
||||
GURL(),
|
||||
&plugin)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SendExecuteMimeTypeHandlerEvent(scoped_ptr<content::StreamInfo> stream,
|
||||
int64 expected_content_size,
|
||||
int render_process_id,
|
||||
int render_frame_id,
|
||||
const std::string& extension_id,
|
||||
const std::string& view_id,
|
||||
bool embedded) {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
CefRefPtr<CefBrowserHostImpl> browser =
|
||||
CefBrowserHostImpl::GetBrowserForFrame(render_process_id,
|
||||
render_frame_id);
|
||||
if (!browser.get())
|
||||
return;
|
||||
|
||||
content::WebContents* web_contents = browser->web_contents();
|
||||
if (!web_contents)
|
||||
return;
|
||||
|
||||
content::BrowserContext* browser_context = web_contents->GetBrowserContext();
|
||||
|
||||
extensions::StreamsPrivateAPI* streams_private =
|
||||
extensions::StreamsPrivateAPI::Get(browser_context);
|
||||
if (!streams_private)
|
||||
return;
|
||||
|
||||
// A |tab_id| value of -1 disables zoom management in the PDF extension.
|
||||
// Otherwise we need to implement chrome.tabs zoom handling. See
|
||||
// chrome/browser/resources/pdf/browser_api.js.
|
||||
int tab_id = -1;
|
||||
|
||||
streams_private->ExecuteMimeTypeHandler(
|
||||
extension_id, tab_id, stream.Pass(), view_id, expected_content_size,
|
||||
embedded, render_process_id, render_frame_id);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CefResourceDispatcherHostDelegate::CefResourceDispatcherHostDelegate() {
|
||||
|
@ -103,6 +180,82 @@ bool CefResourceDispatcherHostDelegate::HandleExternalProtocol(
|
|||
return false;
|
||||
}
|
||||
|
||||
// Implementation based on
|
||||
// ChromeResourceDispatcherHostDelegate::ShouldInterceptResourceAsStream.
|
||||
bool CefResourceDispatcherHostDelegate::ShouldInterceptResourceAsStream(
|
||||
net::URLRequest* request,
|
||||
const std::string& mime_type,
|
||||
GURL* origin,
|
||||
std::string* payload) {
|
||||
if (!extensions::ExtensionsEnabled())
|
||||
return false;
|
||||
|
||||
const content::ResourceRequestInfo* info =
|
||||
content::ResourceRequestInfo::ForRequest(request);
|
||||
CefResourceContext* context =
|
||||
static_cast<CefResourceContext*>(info->GetContext());
|
||||
bool profile_is_off_the_record = context->IsOffTheRecord();
|
||||
const scoped_refptr<const extensions::InfoMap> extension_info_map(
|
||||
context->GetExtensionInfoMap());
|
||||
|
||||
std::vector<std::string> whitelist = MimeTypesHandler::GetMIMETypeWhitelist();
|
||||
// Go through the white-listed extensions and try to use them to intercept
|
||||
// the URL request.
|
||||
for (const std::string& extension_id : whitelist) {
|
||||
const extensions::Extension* extension =
|
||||
extension_info_map->extensions().GetByID(extension_id);
|
||||
// The white-listed extension may not be installed, so we have to NULL check
|
||||
// |extension|.
|
||||
if (!extension ||
|
||||
(profile_is_off_the_record &&
|
||||
!extension_info_map->IsIncognitoEnabled(extension_id))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
MimeTypesHandler* handler = MimeTypesHandler::GetHandler(extension);
|
||||
if (handler && handler->CanHandleMIMEType(mime_type)) {
|
||||
StreamTargetInfo target_info;
|
||||
*origin = extensions::Extension::GetBaseURLFromExtensionId(extension_id);
|
||||
target_info.extension_id = extension_id;
|
||||
if (!handler->handler_url().empty()) {
|
||||
// This is reached in the case of MimeHandlerViews. If the
|
||||
// MimeHandlerView plugin is disabled, then we shouldn't intercept the
|
||||
// stream.
|
||||
if (!IsPluginEnabledForExtension(extension, info, mime_type,
|
||||
request->url())) {
|
||||
continue;
|
||||
}
|
||||
target_info.view_id = base::GenerateGUID();
|
||||
*payload = target_info.view_id;
|
||||
}
|
||||
stream_target_info_[request] = target_info;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Implementation based on
|
||||
// ChromeResourceDispatcherHostDelegate::OnStreamCreated.
|
||||
void CefResourceDispatcherHostDelegate::OnStreamCreated(
|
||||
net::URLRequest* request,
|
||||
scoped_ptr<content::StreamInfo> stream) {
|
||||
DCHECK(extensions::ExtensionsEnabled());
|
||||
const content::ResourceRequestInfo* info =
|
||||
content::ResourceRequestInfo::ForRequest(request);
|
||||
std::map<net::URLRequest*, StreamTargetInfo>::iterator ix =
|
||||
stream_target_info_.find(request);
|
||||
CHECK(ix != stream_target_info_.end());
|
||||
bool embedded = info->GetResourceType() != content::RESOURCE_TYPE_MAIN_FRAME;
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::Bind(&SendExecuteMimeTypeHandlerEvent, base::Passed(&stream),
|
||||
request->GetExpectedContentSize(), info->GetChildID(),
|
||||
info->GetRenderFrameID(), ix->second.extension_id,
|
||||
ix->second.view_id, embedded));
|
||||
stream_target_info_.erase(request);
|
||||
}
|
||||
|
||||
void CefResourceDispatcherHostDelegate::OnRequestRedirected(
|
||||
const GURL& redirect_url,
|
||||
net::URLRequest* request,
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that can
|
||||
// be found in the LICENSE file.
|
||||
// Copyright 2015 The Chromium Embedded Framework Authors.
|
||||
// Portions copyright 2014 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_RESOURCE_DISPATCHER_HOST_DELEGATE_H_
|
||||
#define CEF_LIBCEF_BROWSER_RESOURCE_DISPATCHER_HOST_DELEGATE_H_
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "content/public/browser/resource_dispatcher_host_delegate.h"
|
||||
|
||||
|
@ -29,6 +32,12 @@ class CefResourceDispatcherHostDelegate
|
|||
bool is_main_frame,
|
||||
ui::PageTransition page_transition,
|
||||
bool has_user_gesture) override;
|
||||
bool ShouldInterceptResourceAsStream(net::URLRequest* request,
|
||||
const std::string& mime_type,
|
||||
GURL* origin,
|
||||
std::string* payload) override;
|
||||
void OnStreamCreated(net::URLRequest* request,
|
||||
scoped_ptr<content::StreamInfo> stream) override;
|
||||
void OnRequestRedirected(
|
||||
const GURL& redirect_url,
|
||||
net::URLRequest* request,
|
||||
|
@ -36,6 +45,12 @@ class CefResourceDispatcherHostDelegate
|
|||
content::ResourceResponse* response) override;
|
||||
|
||||
private:
|
||||
struct StreamTargetInfo {
|
||||
std::string extension_id;
|
||||
std::string view_id;
|
||||
};
|
||||
std::map<net::URLRequest*, StreamTargetInfo> stream_target_info_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefResourceDispatcherHostDelegate);
|
||||
};
|
||||
|
||||
|
|
|
@ -8,11 +8,17 @@
|
|||
#include "libcef/browser/render_widget_host_view_osr.h"
|
||||
#include "libcef/common/drag_data_impl.h"
|
||||
|
||||
#include "content/browser/browser_plugin/browser_plugin_embedder.h"
|
||||
#include "content/browser/browser_plugin/browser_plugin_guest.h"
|
||||
#include "content/browser/frame_host/render_widget_host_view_guest.h"
|
||||
#include "content/browser/web_contents/web_contents_impl.h"
|
||||
#include "content/public/browser/render_widget_host.h"
|
||||
#include "content/public/browser/user_metrics.h"
|
||||
|
||||
CefWebContentsViewOSR::CefWebContentsViewOSR()
|
||||
: web_contents_(NULL),
|
||||
view_(NULL) {
|
||||
view_(NULL),
|
||||
guest_(NULL) {
|
||||
}
|
||||
|
||||
CefWebContentsViewOSR::~CefWebContentsViewOSR() {
|
||||
|
@ -24,6 +30,11 @@ void CefWebContentsViewOSR::set_web_contents(
|
|||
web_contents_ = web_contents;
|
||||
}
|
||||
|
||||
void CefWebContentsViewOSR::set_guest(content::BrowserPluginGuest* guest) {
|
||||
DCHECK(!guest_);
|
||||
guest_ = guest;
|
||||
}
|
||||
|
||||
gfx::NativeView CefWebContentsViewOSR::GetNativeView() const {
|
||||
return gfx::NativeView();
|
||||
}
|
||||
|
@ -37,10 +48,32 @@ gfx::NativeWindow CefWebContentsViewOSR::GetTopLevelNativeWindow() const {
|
|||
}
|
||||
|
||||
void CefWebContentsViewOSR::GetContainerBounds(gfx::Rect* out) const {
|
||||
if (guest_) {
|
||||
// Based on WebContentsViewGuest::GetContainerBounds.
|
||||
if (guest_->embedder_web_contents()) {
|
||||
// We need embedder container's bounds to calculate our bounds.
|
||||
guest_->embedder_web_contents()->GetView()->GetContainerBounds(out);
|
||||
gfx::Point guest_coordinates = guest_->GetScreenCoordinates(gfx::Point());
|
||||
out->Offset(guest_coordinates.x(), guest_coordinates.y());
|
||||
} else {
|
||||
out->set_origin(gfx::Point());
|
||||
}
|
||||
out->set_size(size_);
|
||||
return;
|
||||
}
|
||||
|
||||
*out = GetViewBounds();
|
||||
}
|
||||
|
||||
void CefWebContentsViewOSR::SizeContents(const gfx::Size& size) {
|
||||
if (guest_) {
|
||||
// Based on WebContentsViewGuest::SizeContents.
|
||||
size_ = size;
|
||||
content::RenderWidgetHostView* rwhv =
|
||||
web_contents_->GetRenderWidgetHostView();
|
||||
if (rwhv)
|
||||
rwhv->SetSize(size);
|
||||
}
|
||||
}
|
||||
|
||||
void CefWebContentsViewOSR::Focus() {
|
||||
|
@ -60,11 +93,20 @@ content::DropData* CefWebContentsViewOSR::GetDropData() const {
|
|||
}
|
||||
|
||||
gfx::Rect CefWebContentsViewOSR::GetViewBounds() const {
|
||||
if (guest_) {
|
||||
// Based on WebContentsViewGuest::GetViewBounds.
|
||||
return gfx::Rect(size_);
|
||||
}
|
||||
|
||||
return view_ ? view_->GetViewBounds() : gfx::Rect();
|
||||
}
|
||||
|
||||
void CefWebContentsViewOSR::CreateView(const gfx::Size& initial_size,
|
||||
gfx::NativeView context) {
|
||||
if (guest_) {
|
||||
// Based on WebContentsViewGuest::CreateView.
|
||||
size_ = initial_size;
|
||||
}
|
||||
}
|
||||
|
||||
content::RenderWidgetHostViewBase* CefWebContentsViewOSR::CreateViewForWidget(
|
||||
|
@ -75,6 +117,16 @@ content::RenderWidgetHostViewBase* CefWebContentsViewOSR::CreateViewForWidget(
|
|||
render_widget_host->GetView());
|
||||
}
|
||||
|
||||
if (guest_) {
|
||||
// Based on WebContentsViewGuest::CreateViewForWidget.
|
||||
CefRenderWidgetHostViewOSR* platform_widget =
|
||||
new CefRenderWidgetHostViewOSR(render_widget_host, NULL);
|
||||
return new content::RenderWidgetHostViewGuest(
|
||||
render_widget_host,
|
||||
guest_,
|
||||
platform_widget->GetWeakPtr());
|
||||
}
|
||||
|
||||
view_ = new CefRenderWidgetHostViewOSR(render_widget_host, NULL);
|
||||
return view_;
|
||||
}
|
||||
|
@ -123,6 +175,28 @@ void CefWebContentsViewOSR::StartDragging(
|
|||
const gfx::ImageSkia& image,
|
||||
const gfx::Vector2d& image_offset,
|
||||
const content::DragEventSourceInfo& event_info) {
|
||||
if (guest_) {
|
||||
// Based on WebContentsViewGuest::StartDragging.
|
||||
content::WebContentsImpl* embedder_web_contents =
|
||||
guest_->embedder_web_contents();
|
||||
embedder_web_contents->GetBrowserPluginEmbedder()->StartDrag(guest_);
|
||||
content::RenderViewHostImpl* embedder_render_view_host =
|
||||
static_cast<content::RenderViewHostImpl*>(
|
||||
embedder_web_contents->GetRenderViewHost());
|
||||
CHECK(embedder_render_view_host);
|
||||
content::RenderViewHostDelegateView* view =
|
||||
embedder_render_view_host->GetDelegate()->GetDelegateView();
|
||||
if (view) {
|
||||
content::RecordAction(
|
||||
base::UserMetricsAction("BrowserPlugin.Guest.StartDrag"));
|
||||
view->StartDragging(drop_data, allowed_ops, image, image_offset,
|
||||
event_info);
|
||||
} else {
|
||||
embedder_web_contents->SystemDragEnded();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
CefRefPtr<CefBrowserHostImpl> browser;
|
||||
CefRefPtr<CefRenderHandler> handler;
|
||||
bool handled = false;
|
||||
|
@ -150,6 +224,19 @@ void CefWebContentsViewOSR::StartDragging(
|
|||
|
||||
void CefWebContentsViewOSR::UpdateDragCursor(
|
||||
blink::WebDragOperation operation) {
|
||||
if (guest_) {
|
||||
// Based on WebContentsViewGuest::UpdateDragCursor.
|
||||
content::RenderViewHostImpl* embedder_render_view_host =
|
||||
static_cast<content::RenderViewHostImpl*>(
|
||||
guest_->embedder_web_contents()->GetRenderViewHost());
|
||||
CHECK(embedder_render_view_host);
|
||||
content::RenderViewHostDelegateView* view =
|
||||
embedder_render_view_host->GetDelegate()->GetDelegateView();
|
||||
if (view)
|
||||
view->UpdateDragCursor(operation);
|
||||
return;
|
||||
}
|
||||
|
||||
CefRefPtr<CefBrowserHostImpl> browser;
|
||||
CefRefPtr<CefRenderHandler> handler;
|
||||
CefRenderWidgetHostViewOSR* view =
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "content/browser/web_contents/web_contents_view.h"
|
||||
|
||||
namespace content {
|
||||
class BrowserPluginGuest;
|
||||
class WebContents;
|
||||
class WebContentsViewDelegate;
|
||||
}
|
||||
|
@ -24,6 +25,7 @@ class CefWebContentsViewOSR : public content::WebContentsView,
|
|||
~CefWebContentsViewOSR() override;
|
||||
|
||||
void set_web_contents(content::WebContents* web_contents);
|
||||
void set_guest(content::BrowserPluginGuest* guest);
|
||||
|
||||
// WebContentsView methods.
|
||||
gfx::NativeView GetNativeView() const override;
|
||||
|
@ -69,6 +71,9 @@ class CefWebContentsViewOSR : public content::WebContentsView,
|
|||
content::WebContents* web_contents_;
|
||||
CefRenderWidgetHostViewOSR* view_;
|
||||
|
||||
content::BrowserPluginGuest* guest_;
|
||||
gfx::Size size_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefWebContentsViewOSR);
|
||||
};
|
||||
|
||||
|
|
|
@ -15,13 +15,46 @@
|
|||
#include "ui/gfx/ipc/gfx_param_traits.h"
|
||||
#include "ipc/ipc_message_macros.h"
|
||||
|
||||
// Singly-included section for enums and custom IPC traits.
|
||||
#ifndef CEF_LIBCEF_COMMON_CEF_MESSAGES_H_
|
||||
#define CEF_LIBCEF_COMMON_CEF_MESSAGES_H_
|
||||
|
||||
// Based on ChromeViewHostMsg_GetPluginInfo_Status.
|
||||
enum class CefViewHostMsg_GetPluginInfo_Status {
|
||||
kAllowed,
|
||||
kBlocked,
|
||||
kBlockedByPolicy,
|
||||
kDisabled,
|
||||
kNotFound,
|
||||
kNPAPINotSupported,
|
||||
kOutdatedBlocked,
|
||||
kOutdatedDisallowed,
|
||||
kPlayImportantContent,
|
||||
kUnauthorized,
|
||||
};
|
||||
|
||||
namespace IPC {
|
||||
|
||||
// Extracted from chrome/common/automation_messages.h.
|
||||
template <>
|
||||
struct ParamTraits<scoped_refptr<net::UploadData> > {
|
||||
typedef scoped_refptr<net::UploadData> param_type;
|
||||
static void Write(Message* m, const param_type& p);
|
||||
static bool Read(const Message* m, base::PickleIterator* iter, param_type* r);
|
||||
static void Log(const param_type& p, std::string* l);
|
||||
};
|
||||
|
||||
} // namespace IPC
|
||||
|
||||
#endif // CEF_LIBCEF_COMMON_CEF_MESSAGES_H_
|
||||
|
||||
|
||||
// TODO(cef): Re-using the message start for extensions may be problematic in
|
||||
// the future. It would be better if ipc_message_utils.h contained a value
|
||||
// reserved for consumers of the content API.
|
||||
// See: http://crbug.com/110911
|
||||
#define IPC_MESSAGE_START ExtensionMsgStart
|
||||
|
||||
|
||||
// Common types.
|
||||
|
||||
// Parameters structure for a request.
|
||||
|
@ -130,6 +163,11 @@ IPC_MESSAGE_ROUTED1(CefMsg_Response,
|
|||
IPC_MESSAGE_ROUTED1(CefMsg_ResponseAck,
|
||||
int /* request_id */)
|
||||
|
||||
// Sent on process startup to indicate whether this process is running in
|
||||
// incognito mode. Based on ChromeViewMsg_SetIsIncognitoProcess.
|
||||
IPC_MESSAGE_CONTROL1(CefProcessMsg_SetIsIncognitoProcess,
|
||||
bool /* is_incognito_processs */)
|
||||
|
||||
// Sent to child processes to add or remove a cross-origin whitelist entry.
|
||||
IPC_MESSAGE_CONTROL2(CefProcessMsg_ModifyCrossOriginWhitelistEntry,
|
||||
bool /* add */,
|
||||
|
@ -159,6 +197,7 @@ IPC_STRUCT_BEGIN(CefProcessHostMsg_GetNewBrowserInfo_Params)
|
|||
IPC_STRUCT_MEMBER(int, browser_id)
|
||||
IPC_STRUCT_MEMBER(bool, is_popup)
|
||||
IPC_STRUCT_MEMBER(bool, is_windowless)
|
||||
IPC_STRUCT_MEMBER(bool, is_mime_handler_view)
|
||||
IPC_STRUCT_END()
|
||||
|
||||
// Retrieve information about a newly created browser.
|
||||
|
@ -168,6 +207,29 @@ IPC_SYNC_MESSAGE_CONTROL2_1(
|
|||
int /* render_frame_routing_id */,
|
||||
CefProcessHostMsg_GetNewBrowserInfo_Params /* params*/)
|
||||
|
||||
IPC_ENUM_TRAITS_MAX_VALUE(CefViewHostMsg_GetPluginInfo_Status,
|
||||
CefViewHostMsg_GetPluginInfo_Status::kUnauthorized)
|
||||
|
||||
// Output parameters for CefViewHostMsg_GetPluginInfo message.
|
||||
IPC_STRUCT_BEGIN(CefViewHostMsg_GetPluginInfo_Output)
|
||||
IPC_STRUCT_MEMBER(CefViewHostMsg_GetPluginInfo_Status, status)
|
||||
IPC_STRUCT_MEMBER(content::WebPluginInfo, plugin)
|
||||
IPC_STRUCT_MEMBER(std::string, actual_mime_type)
|
||||
IPC_STRUCT_MEMBER(std::string, group_identifier)
|
||||
IPC_STRUCT_MEMBER(base::string16, group_name)
|
||||
IPC_STRUCT_END()
|
||||
|
||||
// Return information about a plugin for the given URL and MIME type.
|
||||
// In contrast to ViewHostMsg_GetPluginInfo in content/, this IPC call knows
|
||||
// about specific reasons why a plugin can't be used, for example because it's
|
||||
// disabled. Based on ChromeViewHostMsg_GetPluginInfo.
|
||||
IPC_SYNC_MESSAGE_CONTROL4_1(CefViewHostMsg_GetPluginInfo,
|
||||
int /* render_frame_id */,
|
||||
GURL /* url */,
|
||||
GURL /* top origin url */,
|
||||
std::string /* mime_type */,
|
||||
CefViewHostMsg_GetPluginInfo_Output /* output */)
|
||||
|
||||
// Sent when a frame is identified for the first time.
|
||||
IPC_MESSAGE_ROUTED3(CefHostMsg_FrameIdentified,
|
||||
int64 /* frame_id */,
|
||||
|
@ -198,23 +260,3 @@ IPC_MESSAGE_ROUTED1(CefHostMsg_ResponseAck,
|
|||
// Sent by the renderer when the draggable regions are updated.
|
||||
IPC_MESSAGE_ROUTED1(CefHostMsg_UpdateDraggableRegions,
|
||||
std::vector<Cef_DraggableRegion_Params> /* regions */)
|
||||
|
||||
|
||||
// Singly-included section for struct and custom IPC traits.
|
||||
#ifndef CEF_LIBCEF_COMMON_CEF_MESSAGES_H_
|
||||
#define CEF_LIBCEF_COMMON_CEF_MESSAGES_H_
|
||||
|
||||
namespace IPC {
|
||||
|
||||
// Extracted from chrome/common/automation_messages.h.
|
||||
template <>
|
||||
struct ParamTraits<scoped_refptr<net::UploadData> > {
|
||||
typedef scoped_refptr<net::UploadData> param_type;
|
||||
static void Write(Message* m, const param_type& p);
|
||||
static bool Read(const Message* m, base::PickleIterator* iter, param_type* r);
|
||||
static void Log(const param_type& p, std::string* l);
|
||||
};
|
||||
|
||||
} // namespace IPC
|
||||
|
||||
#endif // CEF_LIBCEF_COMMON_CEF_MESSAGES_H_
|
||||
|
|
|
@ -100,4 +100,7 @@ const char kEnableSystemFlash[] = "enable-system-flash";
|
|||
// Disable scroll bounce (rubber-banding) on OS X Lion and newer.
|
||||
const char kDisableScrollBounce[] = "disable-scroll-bounce";
|
||||
|
||||
// Disable the PDF extension.
|
||||
const char kDisablePdfExtension[] = "disable-pdf-extension";
|
||||
|
||||
} // namespace switches
|
||||
|
|
|
@ -43,6 +43,7 @@ extern const char kEnableSpellingService[];
|
|||
extern const char kOverrideSpellCheckLang[];
|
||||
extern const char kEnableSystemFlash[];
|
||||
extern const char kDisableScrollBounce[];
|
||||
extern const char kDisablePdfExtension[];
|
||||
|
||||
} // namespace switches
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Copyright 2015 The Chromium Embedded Framework Authors.
|
||||
// Portions copyright 2014 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.
|
||||
|
||||
|
@ -6,7 +7,9 @@
|
|||
#include "include/cef_stream.h"
|
||||
#include "include/cef_version.h"
|
||||
#include "libcef/browser/content_browser_client.h"
|
||||
#include "libcef/browser/extensions/pdf_extension_util.h"
|
||||
#include "libcef/common/cef_switches.h"
|
||||
#include "libcef/common/extensions/extensions_util.h"
|
||||
#include "libcef/common/scheme_registrar_impl.h"
|
||||
#include "libcef/common/scheme_registration.h"
|
||||
|
||||
|
@ -28,16 +31,54 @@
|
|||
#include "content/public/common/content_switches.h"
|
||||
#include "content/public/common/pepper_plugin_info.h"
|
||||
#include "content/public/common/user_agent.h"
|
||||
#include "ppapi/shared_impl/ppapi_permissions.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
CefContentClient* g_content_client = NULL;
|
||||
|
||||
// The following Flash-related methods are from
|
||||
// The following plugin-related methods are from
|
||||
// chrome/common/chrome_content_client.cc
|
||||
|
||||
const char kPDFPluginExtension[] = "pdf";
|
||||
const char kPDFPluginDescription[] = "Portable Document Format";
|
||||
const char kPDFPluginOutOfProcessMimeType[] =
|
||||
"application/x-google-chrome-pdf";
|
||||
const uint32 kPDFPluginPermissions = ppapi::PERMISSION_PRIVATE |
|
||||
ppapi::PERMISSION_DEV;
|
||||
|
||||
content::PepperPluginInfo::GetInterfaceFunc g_pdf_get_interface;
|
||||
content::PepperPluginInfo::PPP_InitializeModuleFunc g_pdf_initialize_module;
|
||||
content::PepperPluginInfo::PPP_ShutdownModuleFunc g_pdf_shutdown_module;
|
||||
|
||||
// Appends the known built-in plugins to the given vector. Some built-in
|
||||
// plugins are "internal" which means they are compiled into the Chrome binary,
|
||||
// and some are extra shared libraries distributed with the browser (these are
|
||||
// not marked internal, aside from being automatically registered, they're just
|
||||
// regular plugins).
|
||||
void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
|
||||
if (extensions::PdfExtensionEnabled()) {
|
||||
content::PepperPluginInfo pdf_info;
|
||||
pdf_info.is_internal = true;
|
||||
pdf_info.is_out_of_process = true;
|
||||
pdf_info.name = extensions::pdf_extension_util::kPdfPluginName;
|
||||
pdf_info.description = kPDFPluginDescription;
|
||||
pdf_info.path =
|
||||
base::FilePath::FromUTF8Unsafe(CefContentClient::kPDFPluginPath);
|
||||
content::WebPluginMimeType pdf_mime_type(
|
||||
kPDFPluginOutOfProcessMimeType,
|
||||
kPDFPluginExtension,
|
||||
kPDFPluginDescription);
|
||||
pdf_info.mime_types.push_back(pdf_mime_type);
|
||||
pdf_info.internal_entry_points.get_interface = g_pdf_get_interface;
|
||||
pdf_info.internal_entry_points.initialize_module = g_pdf_initialize_module;
|
||||
pdf_info.internal_entry_points.shutdown_module = g_pdf_shutdown_module;
|
||||
pdf_info.permissions = kPDFPluginPermissions;
|
||||
plugins->push_back(pdf_info);
|
||||
}
|
||||
}
|
||||
|
||||
content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
|
||||
const std::string& version) {
|
||||
content::PepperPluginInfo plugin;
|
||||
|
@ -162,6 +203,8 @@ bool GetSystemPepperFlash(content::PepperPluginInfo* plugin) {
|
|||
|
||||
} // namespace
|
||||
|
||||
const char CefContentClient::kPDFPluginPath[] = "internal-pdf-viewer";
|
||||
|
||||
CefContentClient::CefContentClient(CefRefPtr<CefApp> application)
|
||||
: application_(application),
|
||||
pack_loading_disabled_(false),
|
||||
|
@ -182,6 +225,7 @@ CefContentClient* CefContentClient::Get() {
|
|||
|
||||
void CefContentClient::AddPepperPlugins(
|
||||
std::vector<content::PepperPluginInfo>* plugins) {
|
||||
ComputeBuiltInPlugins(plugins);
|
||||
AddPepperFlashFromCommandLine(plugins);
|
||||
|
||||
content::PepperPluginInfo plugin;
|
||||
|
@ -205,7 +249,7 @@ void CefContentClient::AddAdditionalSchemes(
|
|||
DCHECK(schemeRegistrar->VerifyRefCount());
|
||||
}
|
||||
|
||||
scheme::AddInternalSchemes(standard_schemes);
|
||||
scheme::AddInternalSchemes(standard_schemes, savable_schemes);
|
||||
|
||||
scheme_info_list_locked_ = true;
|
||||
}
|
||||
|
@ -289,6 +333,16 @@ bool CefContentClient::HasCustomScheme(const std::string& scheme_name) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
void CefContentClient::SetPDFEntryFunctions(
|
||||
content::PepperPluginInfo::GetInterfaceFunc get_interface,
|
||||
content::PepperPluginInfo::PPP_InitializeModuleFunc initialize_module,
|
||||
content::PepperPluginInfo::PPP_ShutdownModuleFunc shutdown_module) {
|
||||
g_pdf_get_interface = get_interface;
|
||||
g_pdf_initialize_module = initialize_module;
|
||||
g_pdf_shutdown_module = shutdown_module;
|
||||
}
|
||||
|
||||
base::FilePath CefContentClient::GetPathForResourcePack(
|
||||
const base::FilePath& pack_path,
|
||||
ui::ScaleFactor scale_factor) {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Copyright 2015 The Chromium Embedded Framework Authors.
|
||||
// Portions copyright 2014 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.
|
||||
|
||||
|
@ -14,11 +15,14 @@
|
|||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "content/public/common/content_client.h"
|
||||
#include "content/public/common/pepper_plugin_info.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
|
||||
class CefContentClient : public content::ContentClient,
|
||||
public ui::ResourceBundle::Delegate {
|
||||
public:
|
||||
static const char kPDFPluginPath[];
|
||||
|
||||
explicit CefContentClient(CefRefPtr<CefApp> application);
|
||||
~CefContentClient() override;
|
||||
|
||||
|
@ -41,6 +45,7 @@ class CefContentClient : public content::ContentClient,
|
|||
struct SchemeInfo {
|
||||
std::string scheme_name;
|
||||
bool is_standard;
|
||||
bool is_savable;
|
||||
bool is_local;
|
||||
bool is_display_isolated;
|
||||
};
|
||||
|
@ -57,6 +62,11 @@ class CefContentClient : public content::ContentClient,
|
|||
bool pack_loading_disabled() const { return pack_loading_disabled_; }
|
||||
void set_allow_pack_file_load(bool val) { allow_pack_file_load_ = val; }
|
||||
|
||||
static void SetPDFEntryFunctions(
|
||||
content::PepperPluginInfo::GetInterfaceFunc get_interface,
|
||||
content::PepperPluginInfo::PPP_InitializeModuleFunc initialize_module,
|
||||
content::PepperPluginInfo::PPP_ShutdownModuleFunc shutdown_module);
|
||||
|
||||
private:
|
||||
// ui::ResourceBundle::Delegate methods.
|
||||
base::FilePath GetPathForResourcePack(
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
This directory provides Mojo API definitions for CEF.
|
||||
|
||||
To add a new Mojo API:
|
||||
|
||||
<api> is the name of the API definition (e.g. 'streams_private').
|
||||
<class> is the name of the class implementation (e.g. 'StreamsPrivateAPI').
|
||||
|
||||
1. Add libcef/common/extensions/api/<api>.idl file which defines the API.
|
||||
2. Add <api>.idl to the 'schema_files' list in
|
||||
libcef/common/extensions/api/schemas.gypi. Serialization code will be
|
||||
generated based on this list in step 5.
|
||||
3. Add an entry to libcef/common/extensions/api/_api_features.json if
|
||||
necessary [1].
|
||||
4. Add libcef/browser/extensions/api/<api>/<api>_api.[h|cc] class implementation
|
||||
files and associated entries to the 'libcef_static' target in cef.gyp.
|
||||
5. Run the cef_create_projects script and build to generate the
|
||||
cef/libcef/common/extensions/api/<api>.h file and other serialization code
|
||||
required by the extensions system.
|
||||
6. Call `<class>::GetInstance();` or `<class>Factory::GetFactoryInstance();` [2]
|
||||
from EnsureBrowserContextKeyedServiceFactoriesBuilt in
|
||||
libcef/browser/extensions/browser_context_keyed_service_factories.cc.
|
||||
7. Call `DependsOn(<class>Factory::GetInstance());` from
|
||||
CefExtensionSystemFactory::CefExtensionSystemFactory in
|
||||
libcef/browser/extensions/extension_system_factory.cc if necessary [2].
|
||||
|
||||
See https://www.chromium.org/developers/design-documents/mojo for more
|
||||
information.
|
||||
|
||||
[1] A feature can optionally express requirements for where it can be accessed.
|
||||
See the _api_features.json file for additional details.
|
||||
|
||||
[2] Some Mojo APIs use singleton Factory objects that create a one-to-one
|
||||
relationship between a service and a BrowserContext. This is used primarily
|
||||
to control shutdown/destruction order and implementors must explicitly state
|
||||
which services are depended on. See comments in
|
||||
components/keyed_service/content/browser_context_keyed_service_factory.h
|
||||
for additional details.
|
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// This file defines extension APIs implemented in CEF.
|
||||
// See extensions/common/features/* to understand this file, in particular
|
||||
// feature.h, simple_feature.h, and base_feature_provider.h.
|
||||
|
||||
{
|
||||
// From chrome/common/extensions/api/_api_features.json.
|
||||
// Required by the PDF extension which is hosted in a guest view.
|
||||
"mimeHandlerViewGuestInternal": {
|
||||
"internal": true,
|
||||
"contexts": "all",
|
||||
"channel": "stable",
|
||||
"matches": ["<all_urls>"]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
# Copyright 2014 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.
|
||||
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'cef_api',
|
||||
'type': 'static_library',
|
||||
# TODO(jschuh): http://crbug.com/167187 size_t -> int
|
||||
'msvs_disabled_warnings': [ 4267 ],
|
||||
'includes': [
|
||||
'../../../../../build/json_schema_bundle_compile.gypi',
|
||||
'../../../../../build/json_schema_compile.gypi',
|
||||
'schemas.gypi',
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
# Copyright 2014 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.
|
||||
|
||||
{
|
||||
'sources': [
|
||||
'<@(schema_files)',
|
||||
],
|
||||
'variables': {
|
||||
'schema_files': [
|
||||
'streams_private.idl',
|
||||
],
|
||||
'non_compiled_schema_files': [
|
||||
],
|
||||
|
||||
'chromium_code': 1,
|
||||
'cc_dir': 'cef/libcef/common/extensions/api',
|
||||
# Match the Chrome namespace to minimize code changes.
|
||||
'root_namespace': 'extensions::api::%(namespace)s',
|
||||
'impl_dir_': 'cef/libcef/browser/extensions/api',
|
||||
},
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// Streams Private API.
|
||||
namespace streamsPrivate {
|
||||
dictionary StreamInfo {
|
||||
// The MIME type of the intercepted URL request.
|
||||
DOMString mimeType;
|
||||
|
||||
// The original URL that was intercepted.
|
||||
DOMString originalUrl;
|
||||
|
||||
// The URL that the stream can be read from.
|
||||
DOMString streamUrl;
|
||||
|
||||
// The ID of the tab that opened the stream. If the stream is not opened in
|
||||
// a tab, it will be -1.
|
||||
long tabId;
|
||||
|
||||
// The ID of the view that will render the stream, if the viewer was opened
|
||||
// in a plugin.
|
||||
DOMString? viewId;
|
||||
|
||||
// The amount of data the Stream should contain, if known. If there is no
|
||||
// information on the size it will be -1.
|
||||
long expectedContentSize;
|
||||
|
||||
// The HTTP response headers of the intercepted request stored as a
|
||||
// dictionary mapping header name to header value. If a header name appears
|
||||
// multiple times, the header values are merged in the dictionary and
|
||||
// separated by a ", ".
|
||||
object responseHeaders;
|
||||
|
||||
// Whether the stream is embedded within another document.
|
||||
boolean embedded;
|
||||
};
|
||||
|
||||
callback AbortCallback = void ();
|
||||
|
||||
interface Functions {
|
||||
// Abort the URL request on the given stream.
|
||||
// |streamUrl| : The URL of the stream to abort.
|
||||
// |callback| : Called when the stream URL is guaranteed to be invalid. The
|
||||
// underlying URL request may not yet have been aborted when this is run.
|
||||
static void abort(DOMString streamUrl,
|
||||
optional AbortCallback callback);
|
||||
};
|
||||
|
||||
interface Events {
|
||||
// Fired when a resource is fetched which matches a mime type handled by
|
||||
// this extension. The resource request is cancelled, and the extension is
|
||||
// expected to handle the request. The event is restricted to a small number
|
||||
// of white-listed extensions.
|
||||
static void onExecuteMimeTypeHandler(StreamInfo streamInfo);
|
||||
};
|
||||
};
|
|
@ -0,0 +1,243 @@
|
|||
// Copyright 2015 The Chromium Embedded Framework Authors.
|
||||
// Portions copyright 2014 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/common/extensions/extensions_client.h"
|
||||
|
||||
#include "libcef/common/cef_switches.h"
|
||||
|
||||
#include "base/lazy_instance.h"
|
||||
#include "base/logging.h"
|
||||
#include "cef/libcef/common/extensions/api/generated_schemas.h"
|
||||
#include "extensions/common/api/generated_schemas.h"
|
||||
#include "extensions/common/common_manifest_handlers.h"
|
||||
#include "extensions/common/extension_urls.h"
|
||||
#include "extensions/common/features/api_feature.h"
|
||||
#include "extensions/common/features/base_feature_provider.h"
|
||||
#include "extensions/common/features/behavior_feature.h"
|
||||
#include "extensions/common/features/json_feature_provider_source.h"
|
||||
#include "extensions/common/features/manifest_feature.h"
|
||||
#include "extensions/common/features/permission_feature.h"
|
||||
#include "extensions/common/features/simple_feature.h"
|
||||
#include "extensions/common/manifest_handler.h"
|
||||
#include "extensions/common/permissions/permission_message_provider.h"
|
||||
#include "extensions/common/permissions/permissions_info.h"
|
||||
#include "extensions/common/permissions/permissions_provider.h"
|
||||
#include "extensions/common/url_pattern_set.h"
|
||||
#include "grit/cef_resources.h"
|
||||
#include "grit/extensions_resources.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
namespace {
|
||||
|
||||
template <class FeatureClass>
|
||||
SimpleFeature* CreateFeature() {
|
||||
return new FeatureClass;
|
||||
}
|
||||
|
||||
// TODO(jamescook): Refactor ChromePermissionsMessageProvider so we can share
|
||||
// code. For now, this implementation does nothing.
|
||||
class CefPermissionMessageProvider : public PermissionMessageProvider {
|
||||
public:
|
||||
CefPermissionMessageProvider() {}
|
||||
~CefPermissionMessageProvider() override {}
|
||||
|
||||
// PermissionMessageProvider implementation.
|
||||
PermissionMessageIDs GetLegacyPermissionMessageIDs(
|
||||
const PermissionSet* permissions,
|
||||
Manifest::Type extension_type) const override {
|
||||
return PermissionMessageIDs();
|
||||
}
|
||||
|
||||
CoalescedPermissionMessages GetCoalescedPermissionMessages(
|
||||
const PermissionIDSet& permissions) const override {
|
||||
return CoalescedPermissionMessages();
|
||||
}
|
||||
|
||||
std::vector<base::string16> GetLegacyWarningMessages(
|
||||
const PermissionSet* permissions,
|
||||
Manifest::Type extension_type) const override {
|
||||
return std::vector<base::string16>();
|
||||
}
|
||||
|
||||
std::vector<base::string16> GetLegacyWarningMessagesDetails(
|
||||
const PermissionSet* permissions,
|
||||
Manifest::Type extension_type) const override {
|
||||
return std::vector<base::string16>();
|
||||
}
|
||||
|
||||
bool IsPrivilegeIncrease(const PermissionSet* old_permissions,
|
||||
const PermissionSet* new_permissions,
|
||||
Manifest::Type extension_type) const override {
|
||||
// Ensure we implement this before shipping.
|
||||
CHECK(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
PermissionIDSet GetAllPermissionIDs(
|
||||
const PermissionSet* permissions,
|
||||
Manifest::Type extension_type) const override {
|
||||
return PermissionIDSet();
|
||||
}
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(CefPermissionMessageProvider);
|
||||
};
|
||||
|
||||
base::LazyInstance<CefPermissionMessageProvider>
|
||||
g_permission_message_provider = LAZY_INSTANCE_INITIALIZER;
|
||||
|
||||
} // namespace
|
||||
|
||||
CefExtensionsClient::CefExtensionsClient()
|
||||
: extensions_api_permissions_(ExtensionsAPIPermissions()) {
|
||||
}
|
||||
|
||||
CefExtensionsClient::~CefExtensionsClient() {
|
||||
}
|
||||
|
||||
void CefExtensionsClient::Initialize() {
|
||||
RegisterCommonManifestHandlers();
|
||||
ManifestHandler::FinalizeRegistration();
|
||||
// TODO(jamescook): Do we need to whitelist any extensions?
|
||||
|
||||
PermissionsInfo::GetInstance()->AddProvider(extensions_api_permissions_);
|
||||
}
|
||||
|
||||
const PermissionMessageProvider&
|
||||
CefExtensionsClient::GetPermissionMessageProvider() const {
|
||||
NOTIMPLEMENTED();
|
||||
return g_permission_message_provider.Get();
|
||||
}
|
||||
|
||||
const std::string CefExtensionsClient::GetProductName() {
|
||||
return "cef";
|
||||
}
|
||||
|
||||
scoped_ptr<FeatureProvider> CefExtensionsClient::CreateFeatureProvider(
|
||||
const std::string& name) const {
|
||||
scoped_ptr<FeatureProvider> provider;
|
||||
scoped_ptr<JSONFeatureProviderSource> source(
|
||||
CreateFeatureProviderSource(name));
|
||||
if (name == "api") {
|
||||
provider.reset(new BaseFeatureProvider(source->dictionary(),
|
||||
CreateFeature<APIFeature>));
|
||||
} else if (name == "manifest") {
|
||||
provider.reset(new BaseFeatureProvider(source->dictionary(),
|
||||
CreateFeature<ManifestFeature>));
|
||||
} else if (name == "permission") {
|
||||
provider.reset(new BaseFeatureProvider(source->dictionary(),
|
||||
CreateFeature<PermissionFeature>));
|
||||
} else if (name == "behavior") {
|
||||
provider.reset(new BaseFeatureProvider(source->dictionary(),
|
||||
CreateFeature<BehaviorFeature>));
|
||||
} else {
|
||||
NOTREACHED();
|
||||
}
|
||||
return provider.Pass();
|
||||
}
|
||||
|
||||
scoped_ptr<JSONFeatureProviderSource>
|
||||
CefExtensionsClient::CreateFeatureProviderSource(
|
||||
const std::string& name) const {
|
||||
scoped_ptr<JSONFeatureProviderSource> source(
|
||||
new JSONFeatureProviderSource(name));
|
||||
if (name == "api") {
|
||||
source->LoadJSON(IDR_EXTENSION_API_FEATURES);
|
||||
|
||||
// Extension API features specific to CEF. See
|
||||
// libcef/common/extensions/api/README.txt for additional details.
|
||||
source->LoadJSON(IDR_CEF_EXTENSION_API_FEATURES);
|
||||
} else if (name == "manifest") {
|
||||
source->LoadJSON(IDR_EXTENSION_MANIFEST_FEATURES);
|
||||
} else if (name == "permission") {
|
||||
source->LoadJSON(IDR_EXTENSION_PERMISSION_FEATURES);
|
||||
} else if (name == "behavior") {
|
||||
source->LoadJSON(IDR_EXTENSION_BEHAVIOR_FEATURES);
|
||||
} else {
|
||||
NOTREACHED();
|
||||
source.reset();
|
||||
}
|
||||
return source.Pass();
|
||||
}
|
||||
|
||||
void CefExtensionsClient::FilterHostPermissions(
|
||||
const URLPatternSet& hosts,
|
||||
URLPatternSet* new_hosts,
|
||||
std::set<PermissionMessage>* messages) const {
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
|
||||
void CefExtensionsClient::FilterHostPermissions(
|
||||
const URLPatternSet& hosts,
|
||||
URLPatternSet* new_hosts,
|
||||
PermissionIDSet* permissions) const {
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
|
||||
void CefExtensionsClient::SetScriptingWhitelist(
|
||||
const ScriptingWhitelist& whitelist) {
|
||||
scripting_whitelist_ = whitelist;
|
||||
}
|
||||
|
||||
const ExtensionsClient::ScriptingWhitelist&
|
||||
CefExtensionsClient::GetScriptingWhitelist() const {
|
||||
// TODO(jamescook): Real whitelist.
|
||||
return scripting_whitelist_;
|
||||
}
|
||||
|
||||
URLPatternSet CefExtensionsClient::GetPermittedChromeSchemeHosts(
|
||||
const Extension* extension,
|
||||
const APIPermissionSet& api_permissions) const {
|
||||
return URLPatternSet();
|
||||
}
|
||||
|
||||
bool CefExtensionsClient::IsScriptableURL(const GURL& url,
|
||||
std::string* error) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CefExtensionsClient::IsAPISchemaGenerated(
|
||||
const std::string& name) const {
|
||||
return core_api::GeneratedSchemas::IsGenerated(name) ||
|
||||
api::GeneratedSchemas::IsGenerated(name);
|
||||
}
|
||||
|
||||
base::StringPiece CefExtensionsClient::GetAPISchema(
|
||||
const std::string& name) const {
|
||||
// Schema for CEF-only APIs.
|
||||
if (api::GeneratedSchemas::IsGenerated(name))
|
||||
return api::GeneratedSchemas::Get(name);
|
||||
|
||||
// Core extensions APIs.
|
||||
return core_api::GeneratedSchemas::Get(name);
|
||||
}
|
||||
|
||||
void CefExtensionsClient::RegisterAPISchemaResources(
|
||||
ExtensionAPI* api) const {
|
||||
}
|
||||
|
||||
bool CefExtensionsClient::ShouldSuppressFatalErrors() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void CefExtensionsClient::RecordDidSuppressFatalError() {
|
||||
}
|
||||
|
||||
std::string CefExtensionsClient::GetWebstoreBaseURL() const {
|
||||
return extension_urls::kChromeWebstoreBaseURL;
|
||||
}
|
||||
|
||||
std::string CefExtensionsClient::GetWebstoreUpdateURL() const {
|
||||
return extension_urls::kChromeWebstoreUpdateURL;
|
||||
}
|
||||
|
||||
bool CefExtensionsClient::IsBlacklistUpdateURL(const GURL& url) const {
|
||||
// TODO(rockot): Maybe we want to do something else here. For now we accept
|
||||
// any URL as a blacklist URL because we don't really care.
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace extensions
|
|
@ -0,0 +1,63 @@
|
|||
// Copyright 2015 The Chromium Embedded Framework Authors.
|
||||
// Portions copyright 2014 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_COMMON_EXTENSIONS_EXTENSIONS_CLIENT_H_
|
||||
#define CEF_LIBCEF_COMMON_EXTENSIONS_EXTENSIONS_CLIENT_H_
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/compiler_specific.h"
|
||||
#include "extensions/common/extensions_client.h"
|
||||
#include "extensions/common/permissions/extensions_api_permissions.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
// The CEF implementation of ExtensionsClient.
|
||||
class CefExtensionsClient : public ExtensionsClient {
|
||||
public:
|
||||
CefExtensionsClient();
|
||||
~CefExtensionsClient() override;
|
||||
|
||||
// ExtensionsClient overrides:
|
||||
void Initialize() override;
|
||||
const PermissionMessageProvider& GetPermissionMessageProvider()
|
||||
const override;
|
||||
const std::string GetProductName() override;
|
||||
scoped_ptr<FeatureProvider> CreateFeatureProvider(
|
||||
const std::string& name) const override;
|
||||
scoped_ptr<JSONFeatureProviderSource> CreateFeatureProviderSource(
|
||||
const std::string& name) const override;
|
||||
void FilterHostPermissions(
|
||||
const URLPatternSet& hosts,
|
||||
URLPatternSet* new_hosts,
|
||||
std::set<PermissionMessage>* messages) const override;
|
||||
void FilterHostPermissions(const URLPatternSet& hosts,
|
||||
URLPatternSet* new_hosts,
|
||||
PermissionIDSet* permissions) const override;
|
||||
void SetScriptingWhitelist(const ScriptingWhitelist& whitelist) override;
|
||||
const ScriptingWhitelist& GetScriptingWhitelist() const override;
|
||||
URLPatternSet GetPermittedChromeSchemeHosts(
|
||||
const Extension* extension,
|
||||
const APIPermissionSet& api_permissions) const override;
|
||||
bool IsScriptableURL(const GURL& url, std::string* error) const override;
|
||||
bool IsAPISchemaGenerated(const std::string& name) const override;
|
||||
base::StringPiece GetAPISchema(const std::string& name) const override;
|
||||
void RegisterAPISchemaResources(ExtensionAPI* api) const override;
|
||||
bool ShouldSuppressFatalErrors() const override;
|
||||
void RecordDidSuppressFatalError() override;
|
||||
std::string GetWebstoreBaseURL() const override;
|
||||
std::string GetWebstoreUpdateURL() const override;
|
||||
bool IsBlacklistUpdateURL(const GURL& url) const override;
|
||||
|
||||
private:
|
||||
const ExtensionsAPIPermissions extensions_api_permissions_;
|
||||
|
||||
ScriptingWhitelist scripting_whitelist_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefExtensionsClient);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // CEF_LIBCEF_COMMON_EXTENSIONS_EXTENSIONS_CLIENT_H_
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2015 The Chromium Embedded Framework 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/common/extensions/extensions_util.h"
|
||||
|
||||
#include "libcef/common/cef_switches.h"
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "chrome/common/chrome_switches.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
bool ExtensionsEnabled() {
|
||||
static bool enabled = !base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||
switches::kDisableExtensions);
|
||||
return enabled;
|
||||
}
|
||||
|
||||
bool PdfExtensionEnabled() {
|
||||
static bool enabled =
|
||||
ExtensionsEnabled() &&
|
||||
!base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||
switches::kDisablePdfExtension);
|
||||
return enabled;
|
||||
}
|
||||
|
||||
} // namespace extensions
|
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2015 The Chromium Embedded Framework 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_COMMON_EXTENSIONS_EXTENSIONS_UTIL_H_
|
||||
#define CEF_LIBCEF_COMMON_EXTENSIONS_EXTENSIONS_UTIL_H_
|
||||
|
||||
namespace extensions {
|
||||
|
||||
// Returns true if extensions have not been disabled via the command-line.
|
||||
bool ExtensionsEnabled();
|
||||
|
||||
// Returns true if the PDF extension has not been disabled via the command-line.
|
||||
bool PdfExtensionEnabled();
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // CEF_LIBCEF_COMMON_EXTENSIONS_EXTENSIONS_UTIL_H_
|
|
@ -8,6 +8,7 @@
|
|||
#include "libcef/common/cef_switches.h"
|
||||
#include "libcef/common/command_line_impl.h"
|
||||
#include "libcef/common/crash_reporter_client.h"
|
||||
#include "libcef/common/extensions/extensions_util.h"
|
||||
#include "libcef/renderer/content_renderer_client.h"
|
||||
#include "libcef/utility/content_utility_client.h"
|
||||
|
||||
|
@ -21,12 +22,14 @@
|
|||
#include "base/strings/string_util.h"
|
||||
#include "base/synchronization/waitable_event.h"
|
||||
#include "base/threading/thread.h"
|
||||
#include "chrome/child/pdf_child_init.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "chrome/common/chrome_switches.h"
|
||||
#include "content/public/browser/browser_main_runner.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "content/public/common/main_function_params.h"
|
||||
#include "pdf/pdf.h"
|
||||
#include "ui/base/layout.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
#include "ui/base/ui_base_paths.h"
|
||||
|
@ -524,6 +527,14 @@ void CefMainDelegate::PreSandboxStartup() {
|
|||
content_client_.set_pack_loading_disabled(true);
|
||||
|
||||
InitializeResourceBundle();
|
||||
chrome::InitializePDF();
|
||||
}
|
||||
|
||||
void CefMainDelegate::SandboxInitialized(const std::string& process_type) {
|
||||
CefContentClient::SetPDFEntryFunctions(
|
||||
chrome_pdf::PPP_GetInterface,
|
||||
chrome_pdf::PPP_InitializeModule,
|
||||
chrome_pdf::PPP_ShutdownModule);
|
||||
}
|
||||
|
||||
int CefMainDelegate::RunProcess(
|
||||
|
@ -608,23 +619,28 @@ void CefMainDelegate::InitializeResourceBundle() {
|
|||
const base::CommandLine* command_line =
|
||||
base::CommandLine::ForCurrentProcess();
|
||||
base::FilePath cef_pak_file, cef_100_percent_pak_file,
|
||||
cef_200_percent_pak_file, devtools_pak_file, locales_dir;
|
||||
cef_200_percent_pak_file, cef_extensions_pak_file,
|
||||
devtools_pak_file, locales_dir;
|
||||
|
||||
base::FilePath resources_dir;
|
||||
if (command_line->HasSwitch(switches::kResourcesDirPath)) {
|
||||
resources_dir =
|
||||
command_line->GetSwitchValuePath(switches::kResourcesDirPath);
|
||||
}
|
||||
if (resources_dir.empty())
|
||||
resources_dir = GetResourcesFilePath();
|
||||
if (!resources_dir.empty())
|
||||
PathService::Override(chrome::DIR_RESOURCES, resources_dir);
|
||||
|
||||
if (!content_client_.pack_loading_disabled()) {
|
||||
base::FilePath resources_dir;
|
||||
if (command_line->HasSwitch(switches::kResourcesDirPath)) {
|
||||
resources_dir =
|
||||
command_line->GetSwitchValuePath(switches::kResourcesDirPath);
|
||||
}
|
||||
if (resources_dir.empty())
|
||||
resources_dir = GetResourcesFilePath();
|
||||
|
||||
if (!resources_dir.empty()) {
|
||||
cef_pak_file = resources_dir.Append(FILE_PATH_LITERAL("cef.pak"));
|
||||
cef_100_percent_pak_file =
|
||||
resources_dir.Append(FILE_PATH_LITERAL("cef_100_percent.pak"));
|
||||
cef_200_percent_pak_file =
|
||||
resources_dir.Append(FILE_PATH_LITERAL("cef_200_percent.pak"));
|
||||
cef_extensions_pak_file =
|
||||
resources_dir.Append(FILE_PATH_LITERAL("cef_extensions.pak"));
|
||||
devtools_pak_file =
|
||||
resources_dir.Append(FILE_PATH_LITERAL("devtools_resources.pak"));
|
||||
}
|
||||
|
@ -685,6 +701,15 @@ void CefMainDelegate::InitializeResourceBundle() {
|
|||
}
|
||||
}
|
||||
|
||||
if (extensions::ExtensionsEnabled()) {
|
||||
if (base::PathExists(cef_extensions_pak_file)) {
|
||||
resource_bundle.AddDataPackFromPath(
|
||||
cef_extensions_pak_file, ui::SCALE_FACTOR_NONE);
|
||||
} else {
|
||||
LOG(ERROR) << "Could not load cef_extensions.pak";
|
||||
}
|
||||
}
|
||||
|
||||
if (base::PathExists(devtools_pak_file)) {
|
||||
resource_bundle.AddDataPackFromPath(
|
||||
devtools_pak_file, ui::SCALE_FACTOR_NONE);
|
||||
|
|
|
@ -34,6 +34,7 @@ class CefMainDelegate : public content::ContentMainDelegate {
|
|||
|
||||
bool BasicStartupComplete(int* exit_code) override;
|
||||
void PreSandboxStartup() override;
|
||||
void SandboxInitialized(const std::string& process_type) override;
|
||||
int RunProcess(
|
||||
const std::string& process_type,
|
||||
const content::MainFunctionParams& main_function_params) override;
|
||||
|
|
|
@ -6,20 +6,26 @@
|
|||
#include "libcef/common/content_client.h"
|
||||
|
||||
#include "content/public/common/url_constants.h"
|
||||
#include "extensions/common/constants.h"
|
||||
#include "url/url_constants.h"
|
||||
|
||||
namespace scheme {
|
||||
|
||||
void AddInternalSchemes(std::vector<std::string>* standard_schemes) {
|
||||
void AddInternalSchemes(std::vector<std::string>* standard_schemes,
|
||||
std::vector<std::string>* savable_schemes) {
|
||||
static CefContentClient::SchemeInfo schemes[] = {
|
||||
{ content::kChromeUIScheme, true, true, true },
|
||||
{ content::kChromeDevToolsScheme, true, false, true }
|
||||
{ content::kChromeUIScheme, true, false, true, true },
|
||||
{ content::kChromeDevToolsScheme, true, false, false, true },
|
||||
{ extensions::kExtensionScheme, true, true, true, true },
|
||||
{ extensions::kExtensionResourceScheme, true, true, false, true },
|
||||
};
|
||||
|
||||
CefContentClient* client = CefContentClient::Get();
|
||||
for (size_t i = 0; i < sizeof(schemes) / sizeof(schemes[0]); ++i) {
|
||||
if (schemes[0].is_standard)
|
||||
if (schemes[i].is_standard)
|
||||
standard_schemes->push_back(schemes[i].scheme_name);
|
||||
if (schemes[i].is_savable)
|
||||
savable_schemes->push_back(schemes[i].scheme_name);
|
||||
client->AddCustomScheme(schemes[i]);
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +35,8 @@ bool IsInternalHandledScheme(const std::string& scheme) {
|
|||
url::kBlobScheme,
|
||||
content::kChromeDevToolsScheme,
|
||||
content::kChromeUIScheme,
|
||||
extensions::kExtensionScheme,
|
||||
extensions::kExtensionResourceScheme,
|
||||
url::kDataScheme,
|
||||
url::kFileScheme,
|
||||
url::kFileSystemScheme,
|
||||
|
@ -49,6 +57,8 @@ bool IsInternalProtectedScheme(const std::string& scheme) {
|
|||
static const char* schemes[] = {
|
||||
url::kBlobScheme,
|
||||
content::kChromeUIScheme,
|
||||
extensions::kExtensionScheme,
|
||||
extensions::kExtensionResourceScheme,
|
||||
url::kDataScheme,
|
||||
url::kFileScheme,
|
||||
url::kFileSystemScheme,
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
namespace scheme {
|
||||
|
||||
// Add internal schemes.
|
||||
void AddInternalSchemes(std::vector<std::string>* standard_schemes);
|
||||
void AddInternalSchemes(std::vector<std::string>* standard_schemes,
|
||||
std::vector<std::string>* savable_schemes);
|
||||
|
||||
// Returns true if the specified |scheme| is handled internally.
|
||||
bool IsInternalHandledScheme(const std::string& scheme);
|
||||
|
|
|
@ -9,9 +9,13 @@
|
|||
#include "libcef/common/cef_messages.h"
|
||||
#include "libcef/common/cef_switches.h"
|
||||
#include "libcef/common/content_client.h"
|
||||
#include "libcef/common/extensions/extensions_client.h"
|
||||
#include "libcef/common/extensions/extensions_util.h"
|
||||
#include "libcef/common/request_impl.h"
|
||||
#include "libcef/common/values_impl.h"
|
||||
#include "libcef/renderer/browser_impl.h"
|
||||
#include "libcef/renderer/extensions/extensions_renderer_client.h"
|
||||
#include "libcef/renderer/extensions/print_web_view_helper_delegate.h"
|
||||
#include "libcef/renderer/pepper/pepper_helper.h"
|
||||
#include "libcef/renderer/render_frame_observer.h"
|
||||
#include "libcef/renderer/render_message_filter.h"
|
||||
|
@ -24,9 +28,12 @@
|
|||
#include "base/path_service.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "chrome/common/pepper_permission_util.h"
|
||||
#include "chrome/renderer/loadtimes_extension_bindings.h"
|
||||
#include "chrome/renderer/pepper/chrome_pdf_print_client.h"
|
||||
#include "chrome/renderer/spellchecker/spellcheck.h"
|
||||
#include "chrome/renderer/spellchecker/spellcheck_provider.h"
|
||||
#include "components/content_settings/core/common/content_settings_types.h"
|
||||
#include "components/printing/renderer/print_web_view_helper.h"
|
||||
#include "components/web_cache/renderer/web_cache_render_process_observer.h"
|
||||
#include "content/child/worker_task_runner.h"
|
||||
|
@ -41,6 +48,13 @@
|
|||
#include "content/public/renderer/render_view.h"
|
||||
#include "content/public/renderer/render_view_visitor.h"
|
||||
#include "content/renderer/render_frame_impl.h"
|
||||
#include "extensions/renderer/dispatcher.h"
|
||||
#include "extensions/renderer/dispatcher_delegate.h"
|
||||
#include "extensions/renderer/extension_frame_helper.h"
|
||||
#include "extensions/renderer/extension_helper.h"
|
||||
#include "extensions/renderer/guest_view/extensions_guest_view_container.h"
|
||||
#include "extensions/renderer/guest_view/extensions_guest_view_container_dispatcher.h"
|
||||
#include "extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.h"
|
||||
#include "ipc/ipc_sync_channel.h"
|
||||
#include "media/base/media.h"
|
||||
#include "third_party/WebKit/public/platform/WebPrerenderingSupport.h"
|
||||
|
@ -135,31 +149,40 @@ class CefWebWorkerTaskRunner : public base::SequencedTaskRunner,
|
|||
int worker_id_;
|
||||
};
|
||||
|
||||
class CefPrintWebViewHelperDelegate :
|
||||
public printing::PrintWebViewHelper::Delegate {
|
||||
public:
|
||||
CefPrintWebViewHelperDelegate() {}
|
||||
void IsGuestViewApiAvailableToScriptContext(
|
||||
bool* api_is_available,
|
||||
extensions::ScriptContext* context) {
|
||||
if (context->GetAvailability("guestViewInternal").is_available()) {
|
||||
*api_is_available = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool CancelPrerender(content::RenderView* render_view,
|
||||
int routing_id) override {
|
||||
return false;
|
||||
void AppendParams(const std::vector<base::string16>& additional_names,
|
||||
const std::vector<base::string16>& additional_values,
|
||||
blink::WebVector<blink::WebString>* existing_names,
|
||||
blink::WebVector<blink::WebString>* existing_values) {
|
||||
DCHECK(additional_names.size() == additional_values.size());
|
||||
DCHECK(existing_names->size() == existing_values->size());
|
||||
|
||||
size_t existing_size = existing_names->size();
|
||||
size_t total_size = existing_size + additional_names.size();
|
||||
|
||||
blink::WebVector<blink::WebString> names(total_size);
|
||||
blink::WebVector<blink::WebString> values(total_size);
|
||||
|
||||
for (size_t i = 0; i < existing_size; ++i) {
|
||||
names[i] = (*existing_names)[i];
|
||||
values[i] = (*existing_values)[i];
|
||||
}
|
||||
|
||||
blink::WebElement GetPdfElement(blink::WebLocalFrame* frame) override {
|
||||
return blink::WebElement();
|
||||
for (size_t i = 0; i < additional_names.size(); ++i) {
|
||||
names[existing_size + i] = additional_names[i];
|
||||
values[existing_size + i] = additional_values[i];
|
||||
}
|
||||
|
||||
bool IsPrintPreviewEnabled() override {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OverridePrint(blink::WebLocalFrame* frame) override {
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(CefPrintWebViewHelperDelegate);
|
||||
};
|
||||
existing_names->swap(names);
|
||||
existing_values->swap(values);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
@ -456,6 +479,32 @@ void CefContentRendererClient::RenderThreadStarted() {
|
|||
}
|
||||
#endif // defined(OS_MACOSX)
|
||||
|
||||
if (extensions::PdfExtensionEnabled()) {
|
||||
pdf_print_client_.reset(new ChromePDFPrintClient());
|
||||
pdf::PepperPDFHost::SetPrintClient(pdf_print_client_.get());
|
||||
}
|
||||
|
||||
if (extensions::ExtensionsEnabled()) {
|
||||
extensions_client_.reset(new extensions::CefExtensionsClient);
|
||||
extensions::ExtensionsClient::Set(extensions_client_.get());
|
||||
|
||||
extensions_renderer_client_.reset(
|
||||
new extensions::CefExtensionsRendererClient);
|
||||
extensions::ExtensionsRendererClient::Set(
|
||||
extensions_renderer_client_.get());
|
||||
|
||||
extension_dispatcher_delegate_.reset(new extensions::DispatcherDelegate());
|
||||
|
||||
// Must be initialized after ExtensionsRendererClient.
|
||||
extension_dispatcher_.reset(
|
||||
new extensions::Dispatcher(extension_dispatcher_delegate_.get()));
|
||||
thread->AddObserver(extension_dispatcher_.get());
|
||||
|
||||
guest_view_container_dispatcher_.reset(
|
||||
new extensions::ExtensionsGuestViewContainerDispatcher());
|
||||
thread->AddObserver(guest_view_container_dispatcher_.get());
|
||||
}
|
||||
|
||||
// Notify the render process handler.
|
||||
CefRefPtr<CefApp> application = CefContentClient::Get()->application();
|
||||
if (application.get()) {
|
||||
|
@ -474,11 +523,33 @@ void CefContentRendererClient::RenderFrameCreated(
|
|||
content::RenderFrame* render_frame) {
|
||||
new CefRenderFrameObserver(render_frame);
|
||||
new CefPepperHelper(render_frame);
|
||||
|
||||
if (extensions::ExtensionsEnabled()) {
|
||||
new extensions::ExtensionFrameHelper(render_frame,
|
||||
extension_dispatcher_.get());
|
||||
extension_dispatcher_->OnRenderFrameCreated(render_frame);
|
||||
}
|
||||
|
||||
BrowserCreated(render_frame->GetRenderView(), render_frame);
|
||||
}
|
||||
|
||||
void CefContentRendererClient::RenderViewCreated(
|
||||
content::RenderView* render_view) {
|
||||
new CefPrerendererClient(render_view);
|
||||
new printing::PrintWebViewHelper(
|
||||
render_view,
|
||||
make_scoped_ptr<printing::PrintWebViewHelper::Delegate>(
|
||||
new extensions::CefPrintWebViewHelperDelegate()));
|
||||
|
||||
if (extensions::ExtensionsEnabled()) {
|
||||
new extensions::ExtensionHelper(render_view, extension_dispatcher_.get());
|
||||
}
|
||||
|
||||
const base::CommandLine* command_line =
|
||||
base::CommandLine::ForCurrentProcess();
|
||||
if (!command_line->HasSwitch(switches::kDisableSpellChecking))
|
||||
new SpellCheckProvider(render_view, spellcheck_.get());
|
||||
|
||||
BrowserCreated(render_view, render_view->GetMainRenderFrame());
|
||||
}
|
||||
|
||||
|
@ -487,62 +558,29 @@ bool CefContentRendererClient::OverrideCreatePlugin(
|
|||
blink::WebLocalFrame* frame,
|
||||
const blink::WebPluginParams& params,
|
||||
blink::WebPlugin** plugin) {
|
||||
CefRefPtr<CefBrowserImpl> browser =
|
||||
CefBrowserImpl::GetBrowserForMainFrame(frame->top());
|
||||
if (!browser.get() || !browser->is_windowless())
|
||||
if (!extensions::ExtensionsEnabled())
|
||||
return false;
|
||||
|
||||
#if defined(ENABLE_PLUGINS)
|
||||
if (base::UTF16ToASCII(params.mimeType) == content::kBrowserPluginMimeType)
|
||||
return false;
|
||||
|
||||
content::RenderFrameImpl* render_frame_impl =
|
||||
static_cast<content::RenderFrameImpl*>(render_frame);
|
||||
|
||||
content::WebPluginInfo info;
|
||||
std::string mime_type;
|
||||
bool found = false;
|
||||
render_frame_impl->Send(
|
||||
new FrameHostMsg_GetPluginInfo(
|
||||
render_frame_impl->GetRoutingID(),
|
||||
params.url,
|
||||
frame->top()->document().url(),
|
||||
params.mimeType.utf8(),
|
||||
&found,
|
||||
&info,
|
||||
&mime_type));
|
||||
if (!found)
|
||||
return false;
|
||||
|
||||
bool silverlight = StartsWithASCII(mime_type,
|
||||
"application/x-silverlight", false);
|
||||
if (silverlight) {
|
||||
// Force Flash and Silverlight plugins to use windowless mode.
|
||||
blink::WebPluginParams params_to_use = params;
|
||||
params_to_use.mimeType = blink::WebString::fromUTF8(mime_type);
|
||||
|
||||
size_t size = params.attributeNames.size();
|
||||
blink::WebVector<blink::WebString> new_names(size+1),
|
||||
new_values(size+1);
|
||||
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
new_names[i] = params.attributeNames[i];
|
||||
new_values[i] = params.attributeValues[i];
|
||||
}
|
||||
|
||||
new_names[size] = "windowless";
|
||||
new_values[size] = "true";
|
||||
|
||||
params_to_use.attributeNames.swap(new_names);
|
||||
params_to_use.attributeValues.swap(new_values);
|
||||
|
||||
*plugin = render_frame_impl->CreatePlugin(
|
||||
frame, info, params_to_use, nullptr);
|
||||
return true;
|
||||
// Based on ChromeContentRendererClient::OverrideCreatePlugin.
|
||||
std::string orig_mime_type = params.mimeType.utf8();
|
||||
if (orig_mime_type == content::kBrowserPluginMimeType) {
|
||||
bool guest_view_api_available = false;
|
||||
extension_dispatcher_->script_context_set().ForEach(
|
||||
render_frame->GetRenderView(),
|
||||
base::Bind(&IsGuestViewApiAvailableToScriptContext,
|
||||
&guest_view_api_available));
|
||||
if (guest_view_api_available)
|
||||
return false;
|
||||
}
|
||||
#endif // defined(ENABLE_PLUGINS)
|
||||
|
||||
return false;
|
||||
GURL url(params.url);
|
||||
CefViewHostMsg_GetPluginInfo_Output output;
|
||||
render_frame->Send(new CefViewHostMsg_GetPluginInfo(
|
||||
render_frame->GetRoutingID(), url, frame->top()->document().url(),
|
||||
orig_mime_type, &output));
|
||||
|
||||
*plugin = CreatePlugin(render_frame, frame, params, output);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CefContentRendererClient::HandleNavigation(
|
||||
|
@ -561,7 +599,6 @@ bool CefContentRendererClient::HandleNavigation(
|
|||
if (handler.get()) {
|
||||
CefRefPtr<CefBrowserImpl> browserPtr =
|
||||
CefBrowserImpl::GetBrowserForMainFrame(frame->top());
|
||||
DCHECK(browserPtr.get());
|
||||
if (browserPtr.get()) {
|
||||
CefRefPtr<CefFrameImpl> framePtr = browserPtr->GetWebFrameImpl(frame);
|
||||
CefRefPtr<CefRequest> requestPtr(CefRequest::Create());
|
||||
|
@ -604,17 +641,37 @@ bool CefContentRendererClient::HandleNavigation(
|
|||
return false;
|
||||
}
|
||||
|
||||
content::BrowserPluginDelegate*
|
||||
CefContentRendererClient::CreateBrowserPluginDelegate(
|
||||
content::RenderFrame* render_frame,
|
||||
const std::string& mime_type,
|
||||
const GURL& original_url) {
|
||||
DCHECK(extensions::ExtensionsEnabled());
|
||||
if (mime_type == content::kBrowserPluginMimeType) {
|
||||
return new extensions::ExtensionsGuestViewContainer(render_frame);
|
||||
} else {
|
||||
return new extensions::MimeHandlerViewContainer(
|
||||
render_frame, mime_type, original_url);
|
||||
}
|
||||
}
|
||||
|
||||
void CefContentRendererClient::WillDestroyCurrentMessageLoop() {
|
||||
base::AutoLock lock_scope(single_process_cleanup_lock_);
|
||||
single_process_cleanup_complete_ = true;
|
||||
}
|
||||
|
||||
bool CefContentRendererClient::IsExtensionOrSharedModuleWhitelisted(
|
||||
const GURL& url, const std::set<std::string>& whitelist) {
|
||||
DCHECK(extensions::ExtensionsEnabled());
|
||||
const extensions::ExtensionSet* extension_set =
|
||||
CefContentRendererClient::Get()->extension_dispatcher_->extensions();
|
||||
return chrome::IsExtensionOrSharedModuleWhitelisted(url, extension_set,
|
||||
whitelist);
|
||||
}
|
||||
|
||||
void CefContentRendererClient::BrowserCreated(
|
||||
content::RenderView* render_view,
|
||||
content::RenderFrame* render_frame) {
|
||||
const base::CommandLine* command_line =
|
||||
base::CommandLine::ForCurrentProcess();
|
||||
|
||||
// Retrieve the browser information synchronously. This will also register
|
||||
// the routing ids with the browser info object in the browser process.
|
||||
CefProcessHostMsg_GetNewBrowserInfo_Params params;
|
||||
|
@ -625,6 +682,11 @@ void CefContentRendererClient::BrowserCreated(
|
|||
¶ms));
|
||||
DCHECK_GT(params.browser_id, 0);
|
||||
|
||||
if (params.is_mime_handler_view) {
|
||||
// Don't create a CefBrowser for mime handler views.
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't create another browser object if one already exists for the view.
|
||||
if (GetBrowserForView(render_view).get())
|
||||
return;
|
||||
|
@ -643,15 +705,6 @@ void CefContentRendererClient::BrowserCreated(
|
|||
params.is_windowless);
|
||||
browsers_.insert(std::make_pair(render_view, browser));
|
||||
|
||||
new CefPrerendererClient(render_view);
|
||||
new printing::PrintWebViewHelper(
|
||||
render_view,
|
||||
make_scoped_ptr<printing::PrintWebViewHelper::Delegate>(
|
||||
new CefPrintWebViewHelperDelegate()));
|
||||
|
||||
if (!command_line->HasSwitch(switches::kDisableSpellChecking))
|
||||
new SpellCheckProvider(render_view, spellcheck_.get());
|
||||
|
||||
// Notify the render process handler.
|
||||
CefRefPtr<CefApp> application = CefContentClient::Get()->application();
|
||||
if (application.get()) {
|
||||
|
@ -690,3 +743,57 @@ void CefContentRendererClient::RunSingleProcessCleanupOnUIThread() {
|
|||
if (!CefContext::Get()->settings().multi_threaded_message_loop)
|
||||
delete host;
|
||||
}
|
||||
|
||||
blink::WebPlugin* CefContentRendererClient::CreatePlugin(
|
||||
content::RenderFrame* render_frame,
|
||||
blink::WebLocalFrame* frame,
|
||||
const blink::WebPluginParams& original_params,
|
||||
const CefViewHostMsg_GetPluginInfo_Output& output) {
|
||||
const content::WebPluginInfo& info = output.plugin;
|
||||
const std::string& actual_mime_type = output.actual_mime_type;
|
||||
CefViewHostMsg_GetPluginInfo_Status status = output.status;
|
||||
GURL url(original_params.url);
|
||||
std::string orig_mime_type = original_params.mimeType.utf8();
|
||||
|
||||
// If the browser plugin is to be enabled, this should be handled by the
|
||||
// renderer, so the code won't reach here due to the early exit in
|
||||
// OverrideCreatePlugin.
|
||||
if (status == CefViewHostMsg_GetPluginInfo_Status::kNotFound ||
|
||||
orig_mime_type == content::kBrowserPluginMimeType) {
|
||||
return NULL;
|
||||
} else {
|
||||
// TODO(bauerb): This should be in content/.
|
||||
blink::WebPluginParams params(original_params);
|
||||
for (size_t i = 0; i < info.mime_types.size(); ++i) {
|
||||
if (info.mime_types[i].mime_type == actual_mime_type) {
|
||||
AppendParams(info.mime_types[i].additional_param_names,
|
||||
info.mime_types[i].additional_param_values,
|
||||
¶ms.attributeNames, ¶ms.attributeValues);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (params.mimeType.isNull() && (actual_mime_type.size() > 0)) {
|
||||
// Webkit might say that mime type is null while we already know the
|
||||
// actual mime type via CefViewHostMsg_GetPluginInfo. In that case
|
||||
// we should use what we know since WebpluginDelegateProxy does some
|
||||
// specific initializations based on this information.
|
||||
params.mimeType = blink::WebString::fromUTF8(actual_mime_type.c_str());
|
||||
}
|
||||
|
||||
switch (status) {
|
||||
case CefViewHostMsg_GetPluginInfo_Status::kNotFound: {
|
||||
NOTREACHED();
|
||||
break;
|
||||
}
|
||||
case CefViewHostMsg_GetPluginInfo_Status::kAllowed:
|
||||
case CefViewHostMsg_GetPluginInfo_Status::kPlayImportantContent: {
|
||||
// TODO(cef): Maybe supply a throttler based on power settings.
|
||||
return render_frame->CreatePlugin(frame, info, params, nullptr);
|
||||
}
|
||||
default:
|
||||
// TODO(cef): Provide a placeholder for the various failure conditions.
|
||||
break;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -20,12 +20,22 @@
|
|||
#include "base/sequenced_task_runner.h"
|
||||
#include "content/public/renderer/content_renderer_client.h"
|
||||
|
||||
namespace extensions {
|
||||
class Dispatcher;
|
||||
class DispatcherDelegate;
|
||||
class ExtensionsClient;
|
||||
class ExtensionsGuestViewContainerDispatcher;
|
||||
class ExtensionsRendererClient;
|
||||
}
|
||||
|
||||
namespace web_cache {
|
||||
class WebCacheRenderProcessObserver;
|
||||
}
|
||||
|
||||
class CefRenderProcessObserver;
|
||||
struct Cef_CrossOriginWhiteListEntry_Params;
|
||||
struct CefViewHostMsg_GetPluginInfo_Output;
|
||||
class ChromePDFPrintClient;
|
||||
class SpellCheck;
|
||||
|
||||
class CefContentRendererClient : public content::ContentRendererClient,
|
||||
|
@ -94,10 +104,17 @@ class CefContentRendererClient : public content::ContentRendererClient,
|
|||
blink::WebNavigationType type,
|
||||
blink::WebNavigationPolicy default_policy,
|
||||
bool is_redirect) override;
|
||||
content::BrowserPluginDelegate* CreateBrowserPluginDelegate(
|
||||
content::RenderFrame* render_frame,
|
||||
const std::string& mime_type,
|
||||
const GURL& original_url) override;
|
||||
|
||||
// MessageLoop::DestructionObserver implementation.
|
||||
void WillDestroyCurrentMessageLoop() override;
|
||||
|
||||
static bool IsExtensionOrSharedModuleWhitelisted(
|
||||
const GURL& url, const std::set<std::string>& whitelist);
|
||||
|
||||
private:
|
||||
void BrowserCreated(content::RenderView* render_view,
|
||||
content::RenderFrame* render_frame);
|
||||
|
@ -105,6 +122,12 @@ class CefContentRendererClient : public content::ContentRendererClient,
|
|||
// Perform cleanup work for single-process mode.
|
||||
void RunSingleProcessCleanupOnUIThread();
|
||||
|
||||
static blink::WebPlugin* CreatePlugin(
|
||||
content::RenderFrame* render_frame,
|
||||
blink::WebLocalFrame* frame,
|
||||
const blink::WebPluginParams& params,
|
||||
const CefViewHostMsg_GetPluginInfo_Output& output);
|
||||
|
||||
scoped_refptr<base::SequencedTaskRunner> render_task_runner_;
|
||||
scoped_ptr<CefRenderProcessObserver> observer_;
|
||||
scoped_ptr<web_cache::WebCacheRenderProcessObserver> web_cache_observer_;
|
||||
|
@ -118,6 +141,15 @@ class CefContentRendererClient : public content::ContentRendererClient,
|
|||
typedef std::vector<Cef_CrossOriginWhiteListEntry_Params> CrossOriginList;
|
||||
CrossOriginList cross_origin_whitelist_entries_;
|
||||
|
||||
scoped_ptr<ChromePDFPrintClient> pdf_print_client_;
|
||||
|
||||
scoped_ptr<extensions::ExtensionsClient> extensions_client_;
|
||||
scoped_ptr<extensions::ExtensionsRendererClient> extensions_renderer_client_;
|
||||
scoped_ptr<extensions::DispatcherDelegate> extension_dispatcher_delegate_;
|
||||
scoped_ptr<extensions::Dispatcher> extension_dispatcher_;
|
||||
scoped_ptr<extensions::ExtensionsGuestViewContainerDispatcher>
|
||||
guest_view_container_dispatcher_;
|
||||
|
||||
int devtools_agent_count_;
|
||||
int uncaught_exception_stack_size_;
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright 2014 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/renderer/extensions/extensions_renderer_client.h"
|
||||
|
||||
#include "libcef/renderer/render_process_observer.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
CefExtensionsRendererClient::CefExtensionsRendererClient() {
|
||||
}
|
||||
|
||||
CefExtensionsRendererClient::~CefExtensionsRendererClient() {
|
||||
}
|
||||
|
||||
bool CefExtensionsRendererClient::IsIncognitoProcess() const {
|
||||
return CefRenderProcessObserver::is_incognito_process();
|
||||
}
|
||||
|
||||
int CefExtensionsRendererClient::GetLowestIsolatedWorldId() const {
|
||||
// CEF doesn't need to reserve world IDs for anything other than extensions,
|
||||
// so we always return 1. Note that 0 is reserved for the global world.
|
||||
return 1;
|
||||
}
|
||||
|
||||
} // namespace extensions
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2014 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_RENDERER_EXTENSIONS_EXTENSIONS_RENDERER_CLIENT_H_
|
||||
#define CEF_LIBCEF_RENDERER_EXTENSIONS_EXTENSIONS_RENDERER_CLIENT_H_
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "extensions/renderer/extensions_renderer_client.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
class CefExtensionsRendererClient : public ExtensionsRendererClient {
|
||||
public:
|
||||
CefExtensionsRendererClient();
|
||||
~CefExtensionsRendererClient() override;
|
||||
|
||||
// ExtensionsRendererClient implementation.
|
||||
bool IsIncognitoProcess() const override;
|
||||
int GetLowestIsolatedWorldId() const override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(CefExtensionsRendererClient);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // CEF_LIBCEF_RENDERER_EXTENSIONS_EXTENSIONS_RENDERER_CLIENT_H_
|
|
@ -0,0 +1,71 @@
|
|||
// Copyright 2015 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/renderer/extensions/print_web_view_helper_delegate.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "chrome/common/chrome_switches.h"
|
||||
#include "chrome/common/extensions/extension_constants.h"
|
||||
#include "content/public/renderer/render_frame.h"
|
||||
#include "content/public/renderer/render_view.h"
|
||||
#include "extensions/common/constants.h"
|
||||
#include "extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.h"
|
||||
#include "third_party/WebKit/public/web/WebDocument.h"
|
||||
#include "third_party/WebKit/public/web/WebElement.h"
|
||||
#include "third_party/WebKit/public/web/WebLocalFrame.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
CefPrintWebViewHelperDelegate::~CefPrintWebViewHelperDelegate(){
|
||||
}
|
||||
|
||||
bool CefPrintWebViewHelperDelegate::CancelPrerender(
|
||||
content::RenderView* render_view, int routing_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return the PDF object element if |frame| is the out of process PDF extension.
|
||||
blink::WebElement CefPrintWebViewHelperDelegate::GetPdfElement(
|
||||
blink::WebLocalFrame* frame) {
|
||||
GURL url = frame->document().url();
|
||||
if (url.SchemeIs(extensions::kExtensionScheme) &&
|
||||
url.host() == extension_misc::kPdfExtensionId) {
|
||||
// <object> with id="plugin" is created in
|
||||
// chrome/browser/resources/pdf/pdf.js.
|
||||
auto plugin_element = frame->document().getElementById("plugin");
|
||||
if (!plugin_element.isNull()) {
|
||||
return plugin_element;
|
||||
}
|
||||
NOTREACHED();
|
||||
}
|
||||
return blink::WebElement();
|
||||
}
|
||||
|
||||
bool CefPrintWebViewHelperDelegate::IsPrintPreviewEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CefPrintWebViewHelperDelegate::OverridePrint(
|
||||
blink::WebLocalFrame* frame) {
|
||||
if (!frame->document().isPluginDocument())
|
||||
return false;
|
||||
|
||||
std::vector<extensions::MimeHandlerViewContainer*> mime_handlers =
|
||||
extensions::MimeHandlerViewContainer::FromRenderFrame(
|
||||
content::RenderFrame::FromWebFrame(frame));
|
||||
if (!mime_handlers.empty()) {
|
||||
// This message is handled in chrome/browser/resources/pdf/pdf.js and
|
||||
// instructs the PDF plugin to print. This is to make window.print() on a
|
||||
// PDF plugin document correctly print the PDF. See
|
||||
// https://crbug.com/448720.
|
||||
base::DictionaryValue message;
|
||||
message.SetString("type", "print");
|
||||
mime_handlers.front()->PostMessageFromValue(message);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace extensions
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2015 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_RENDERER_EXTENSIONS_PRINT_WEB_VIEW_HELPER_DELEGATE_H_
|
||||
#define CEF_LIBCEF_RENDERER_EXTENSIONS_PRINT_WEB_VIEW_HELPER_DELEGATE_H_
|
||||
|
||||
#include "components/printing/renderer/print_web_view_helper.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
class CefPrintWebViewHelperDelegate
|
||||
: public printing::PrintWebViewHelper::Delegate {
|
||||
public:
|
||||
~CefPrintWebViewHelperDelegate() override;
|
||||
|
||||
bool CancelPrerender(content::RenderView* render_view,
|
||||
int routing_id) override;
|
||||
blink::WebElement GetPdfElement(blink::WebLocalFrame* frame) override;
|
||||
bool IsPrintPreviewEnabled() override;
|
||||
bool OverridePrint(blink::WebLocalFrame* frame) override;
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // CEF_LIBCEF_RENDERER_EXTENSIONS_PRINT_WEB_VIEW_HELPER_DELEGATE_H_
|
|
@ -0,0 +1,214 @@
|
|||
// Copyright 2014 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 "chrome/renderer/pepper/pepper_uma_host.h"
|
||||
|
||||
#include "libcef/common/cef_messages.h"
|
||||
#include "libcef/common/content_client.h"
|
||||
#include "libcef/renderer/content_renderer_client.h"
|
||||
|
||||
#include "base/metrics/histogram.h"
|
||||
#include "base/sha1.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "chrome/common/chrome_switches.h"
|
||||
#include "content/public/renderer/pepper_plugin_instance.h"
|
||||
#include "content/public/renderer/render_thread.h"
|
||||
#include "content/public/renderer/renderer_ppapi_host.h"
|
||||
#include "ppapi/c/pp_errors.h"
|
||||
#include "ppapi/host/dispatch_host_message.h"
|
||||
#include "ppapi/host/host_message_context.h"
|
||||
#include "ppapi/host/ppapi_host.h"
|
||||
#include "ppapi/proxy/ppapi_messages.h"
|
||||
|
||||
#include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR.
|
||||
|
||||
#if defined(ENABLE_EXTENSIONS)
|
||||
#include "extensions/common/constants.h"
|
||||
#include "extensions/common/extension.h"
|
||||
#endif // defined(ENABLE_EXTENSIONS)
|
||||
|
||||
namespace {
|
||||
|
||||
const char* const kPredefinedAllowedUMAOrigins[] = {
|
||||
"6EAED1924DB611B6EEF2A664BD077BE7EAD33B8F", // see http://crbug.com/317833
|
||||
"4EB74897CB187C7633357C2FE832E0AD6A44883A", // see http://crbug.com/317833
|
||||
};
|
||||
|
||||
const char* const kWhitelistedHistogramPrefixes[] = {
|
||||
"22F67DA2061FFC4DC9A4974036348D9C38C22919", // see http://crbug.com/390221
|
||||
};
|
||||
|
||||
const char* const kWhitelistedPluginBaseNames[] = {
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
|
||||
kWidevineCdmAdapterFileName, // see http://crbug.com/368743
|
||||
// and http://crbug.com/410630
|
||||
#endif
|
||||
CefContentClient::kPDFPluginPath,
|
||||
};
|
||||
|
||||
std::string HashPrefix(const std::string& histogram) {
|
||||
const std::string id_hash =
|
||||
base::SHA1HashString(histogram.substr(0, histogram.find('.')));
|
||||
DCHECK_EQ(id_hash.length(), base::kSHA1Length);
|
||||
return base::HexEncode(id_hash.c_str(), id_hash.length());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
PepperUMAHost::PepperUMAHost(content::RendererPpapiHost* host,
|
||||
PP_Instance instance,
|
||||
PP_Resource resource)
|
||||
: ResourceHost(host->GetPpapiHost(), instance, resource),
|
||||
document_url_(host->GetDocumentURL(instance)),
|
||||
is_plugin_in_process_(host->IsRunningInProcess()) {
|
||||
if (host->GetPluginInstance(instance)) {
|
||||
plugin_base_name_ =
|
||||
host->GetPluginInstance(instance)->GetModulePath().BaseName();
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < arraysize(kPredefinedAllowedUMAOrigins); ++i)
|
||||
allowed_origins_.insert(kPredefinedAllowedUMAOrigins[i]);
|
||||
for (size_t i = 0; i < arraysize(kWhitelistedHistogramPrefixes); ++i)
|
||||
allowed_histogram_prefixes_.insert(kWhitelistedHistogramPrefixes[i]);
|
||||
for (size_t i = 0; i < arraysize(kWhitelistedPluginBaseNames); ++i)
|
||||
allowed_plugin_base_names_.insert(kWhitelistedPluginBaseNames[i]);
|
||||
}
|
||||
|
||||
PepperUMAHost::~PepperUMAHost() {}
|
||||
|
||||
int32_t PepperUMAHost::OnResourceMessageReceived(
|
||||
const IPC::Message& msg,
|
||||
ppapi::host::HostMessageContext* context) {
|
||||
PPAPI_BEGIN_MESSAGE_MAP(PepperUMAHost, msg)
|
||||
PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UMA_HistogramCustomTimes,
|
||||
OnHistogramCustomTimes)
|
||||
PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UMA_HistogramCustomCounts,
|
||||
OnHistogramCustomCounts)
|
||||
PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UMA_HistogramEnumeration,
|
||||
OnHistogramEnumeration)
|
||||
PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
|
||||
PpapiHostMsg_UMA_IsCrashReportingEnabled, OnIsCrashReportingEnabled)
|
||||
PPAPI_END_MESSAGE_MAP()
|
||||
return PP_ERROR_FAILED;
|
||||
}
|
||||
|
||||
bool PepperUMAHost::IsPluginWhitelisted() {
|
||||
#if defined(ENABLE_EXTENSIONS)
|
||||
return CefContentRendererClient::IsExtensionOrSharedModuleWhitelisted(
|
||||
document_url_, allowed_origins_);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool PepperUMAHost::IsHistogramAllowed(const std::string& histogram) {
|
||||
if (is_plugin_in_process_ && histogram.find("NaCl.") == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (IsPluginWhitelisted() &&
|
||||
ContainsKey(allowed_histogram_prefixes_, HashPrefix(histogram))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ContainsKey(allowed_plugin_base_names_,
|
||||
plugin_base_name_.MaybeAsASCII())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG(ERROR) << "Host or histogram name is not allowed to use the UMA API.";
|
||||
return false;
|
||||
}
|
||||
|
||||
#define RETURN_IF_BAD_ARGS(_min, _max, _buckets) \
|
||||
do { \
|
||||
if (_min >= _max || _buckets <= 1) \
|
||||
return PP_ERROR_BADARGUMENT; \
|
||||
} while (0)
|
||||
|
||||
int32_t PepperUMAHost::OnHistogramCustomTimes(
|
||||
ppapi::host::HostMessageContext* context,
|
||||
const std::string& name,
|
||||
int64_t sample,
|
||||
int64_t min,
|
||||
int64_t max,
|
||||
uint32_t bucket_count) {
|
||||
if (!IsHistogramAllowed(name)) {
|
||||
return PP_ERROR_NOACCESS;
|
||||
}
|
||||
RETURN_IF_BAD_ARGS(min, max, bucket_count);
|
||||
|
||||
base::HistogramBase* counter = base::Histogram::FactoryTimeGet(
|
||||
name,
|
||||
base::TimeDelta::FromMilliseconds(min),
|
||||
base::TimeDelta::FromMilliseconds(max),
|
||||
bucket_count,
|
||||
base::HistogramBase::kUmaTargetedHistogramFlag);
|
||||
// The histogram can be NULL if it is constructed with bad arguments. Ignore
|
||||
// that data for this API. An error message will be logged.
|
||||
if (counter)
|
||||
counter->AddTime(base::TimeDelta::FromMilliseconds(sample));
|
||||
return PP_OK;
|
||||
}
|
||||
|
||||
int32_t PepperUMAHost::OnHistogramCustomCounts(
|
||||
ppapi::host::HostMessageContext* context,
|
||||
const std::string& name,
|
||||
int32_t sample,
|
||||
int32_t min,
|
||||
int32_t max,
|
||||
uint32_t bucket_count) {
|
||||
if (!IsHistogramAllowed(name)) {
|
||||
return PP_ERROR_NOACCESS;
|
||||
}
|
||||
RETURN_IF_BAD_ARGS(min, max, bucket_count);
|
||||
|
||||
base::HistogramBase* counter = base::Histogram::FactoryGet(
|
||||
name,
|
||||
min,
|
||||
max,
|
||||
bucket_count,
|
||||
base::HistogramBase::kUmaTargetedHistogramFlag);
|
||||
// The histogram can be NULL if it is constructed with bad arguments. Ignore
|
||||
// that data for this API. An error message will be logged.
|
||||
if (counter)
|
||||
counter->Add(sample);
|
||||
return PP_OK;
|
||||
}
|
||||
|
||||
int32_t PepperUMAHost::OnHistogramEnumeration(
|
||||
ppapi::host::HostMessageContext* context,
|
||||
const std::string& name,
|
||||
int32_t sample,
|
||||
int32_t boundary_value) {
|
||||
if (!IsHistogramAllowed(name)) {
|
||||
return PP_ERROR_NOACCESS;
|
||||
}
|
||||
RETURN_IF_BAD_ARGS(0, boundary_value, boundary_value + 1);
|
||||
|
||||
base::HistogramBase* counter = base::LinearHistogram::FactoryGet(
|
||||
name,
|
||||
1,
|
||||
boundary_value,
|
||||
boundary_value + 1,
|
||||
base::HistogramBase::kUmaTargetedHistogramFlag);
|
||||
// The histogram can be NULL if it is constructed with bad arguments. Ignore
|
||||
// that data for this API. An error message will be logged.
|
||||
if (counter)
|
||||
counter->Add(sample);
|
||||
return PP_OK;
|
||||
}
|
||||
|
||||
int32_t PepperUMAHost::OnIsCrashReportingEnabled(
|
||||
ppapi::host::HostMessageContext* context) {
|
||||
if (!IsPluginWhitelisted())
|
||||
return PP_ERROR_NOACCESS;
|
||||
// TODO(extensions): Chrome uses ChromeViewHostMsg_IsCrashReportingEnabled to
|
||||
// retrieve this value. Explore whether it's useful for CEF clients when crash
|
||||
// reporting is enabled.
|
||||
bool enabled = false;
|
||||
if (enabled)
|
||||
return PP_OK;
|
||||
return PP_ERROR_FAILED;
|
||||
}
|
|
@ -10,6 +10,8 @@
|
|||
#include "chrome/renderer/pepper/pepper_flash_fullscreen_host.h"
|
||||
#include "chrome/renderer/pepper/pepper_flash_menu_host.h"
|
||||
#include "chrome/renderer/pepper/pepper_flash_renderer_host.h"
|
||||
#include "chrome/renderer/pepper/pepper_uma_host.h"
|
||||
#include "components/pdf/renderer/pepper_pdf_host.h"
|
||||
#include "content/public/renderer/renderer_ppapi_host.h"
|
||||
#include "ppapi/host/ppapi_host.h"
|
||||
#include "ppapi/host/resource_host.h"
|
||||
|
@ -83,5 +85,27 @@ scoped_ptr<ResourceHost> CefRendererPepperHostFactory::CreateResourceHost(
|
|||
}
|
||||
}
|
||||
|
||||
if (host_->GetPpapiHost()->permissions().HasPermission(
|
||||
ppapi::PERMISSION_PRIVATE)) {
|
||||
switch (message.type()) {
|
||||
case PpapiHostMsg_PDF_Create::ID: {
|
||||
return scoped_ptr<ResourceHost>(
|
||||
new pdf::PepperPDFHost(host_, instance, resource));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Permissions for the following interfaces will be checked at the
|
||||
// time of the corresponding instance's method calls. Currently these
|
||||
// interfaces are available only for whitelisted apps which may not have
|
||||
// access to the other private interfaces.
|
||||
switch (message.type()) {
|
||||
case PpapiHostMsg_UMA_Create::ID: {
|
||||
return scoped_ptr<ResourceHost>(
|
||||
new PepperUMAHost(host_, instance, resource));
|
||||
}
|
||||
}
|
||||
|
||||
NOTREACHED() << "Unhandled message type: " << message.type();
|
||||
return scoped_ptr<ResourceHost>();
|
||||
}
|
||||
|
|
|
@ -38,10 +38,16 @@ void CefRenderFrameObserver::DidCreateScriptContext(
|
|||
|
||||
CefRefPtr<CefBrowserImpl> browserPtr =
|
||||
CefBrowserImpl::GetBrowserForMainFrame(frame->top());
|
||||
DCHECK(browserPtr.get());
|
||||
if (!browserPtr.get())
|
||||
return;
|
||||
|
||||
CefRefPtr<CefRenderProcessHandler> handler;
|
||||
CefRefPtr<CefApp> application = CefContentClient::Get()->application();
|
||||
if (application.get())
|
||||
handler = application->GetRenderProcessHandler();
|
||||
if (!handler.get())
|
||||
return;
|
||||
|
||||
CefRefPtr<CefFrameImpl> framePtr = browserPtr->GetWebFrameImpl(frame);
|
||||
|
||||
v8::Isolate* isolate = blink::mainThreadIsolate();
|
||||
|
@ -51,14 +57,7 @@ void CefRenderFrameObserver::DidCreateScriptContext(
|
|||
|
||||
CefRefPtr<CefV8Context> contextPtr(new CefV8ContextImpl(isolate, context));
|
||||
|
||||
// Notify the render process handler.
|
||||
CefRefPtr<CefApp> application = CefContentClient::Get()->application();
|
||||
if (application.get()) {
|
||||
CefRefPtr<CefRenderProcessHandler> handler =
|
||||
application->GetRenderProcessHandler();
|
||||
if (handler.get())
|
||||
handler->OnContextCreated(browserPtr.get(), framePtr.get(), contextPtr);
|
||||
}
|
||||
handler->OnContextCreated(browserPtr.get(), framePtr.get(), contextPtr);
|
||||
}
|
||||
|
||||
void CefRenderFrameObserver::WillReleaseScriptContext(
|
||||
|
@ -66,16 +65,14 @@ void CefRenderFrameObserver::WillReleaseScriptContext(
|
|||
int world_id) {
|
||||
blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
|
||||
|
||||
// Notify the render process handler.
|
||||
CefRefPtr<CefApp> application = CefContentClient::Get()->application();
|
||||
if (application.get()) {
|
||||
CefRefPtr<CefRenderProcessHandler> handler =
|
||||
application->GetRenderProcessHandler();
|
||||
if (handler.get()) {
|
||||
CefRefPtr<CefBrowserImpl> browserPtr =
|
||||
CefBrowserImpl::GetBrowserForMainFrame(frame->top());
|
||||
DCHECK(browserPtr.get());
|
||||
if (browserPtr.get()) {
|
||||
CefRefPtr<CefBrowserImpl> browserPtr =
|
||||
CefBrowserImpl::GetBrowserForMainFrame(frame->top());
|
||||
if (browserPtr.get()) {
|
||||
CefRefPtr<CefApp> application = CefContentClient::Get()->application();
|
||||
if (application.get()) {
|
||||
CefRefPtr<CefRenderProcessHandler> handler =
|
||||
application->GetRenderProcessHandler();
|
||||
if (handler.get()) {
|
||||
CefRefPtr<CefFrameImpl> framePtr = browserPtr->GetWebFrameImpl(frame);
|
||||
|
||||
v8::Isolate* isolate = blink::mainThreadIsolate();
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include "third_party/WebKit/public/platform/WebURL.h"
|
||||
#include "third_party/WebKit/public/web/WebSecurityPolicy.h"
|
||||
|
||||
bool CefRenderProcessObserver::is_incognito_process_ = false;
|
||||
|
||||
CefRenderProcessObserver::CefRenderProcessObserver() {
|
||||
net::NetModule::SetResourceProvider(NetResourceProvider);
|
||||
}
|
||||
|
@ -24,6 +26,8 @@ bool CefRenderProcessObserver::OnControlMessageReceived(
|
|||
const IPC::Message& message) {
|
||||
bool handled = true;
|
||||
IPC_BEGIN_MESSAGE_MAP(CefRenderProcessObserver, message)
|
||||
IPC_MESSAGE_HANDLER(CefProcessMsg_SetIsIncognitoProcess,
|
||||
OnSetIsIncognitoProcess)
|
||||
IPC_MESSAGE_HANDLER(CefProcessMsg_ModifyCrossOriginWhitelistEntry,
|
||||
OnModifyCrossOriginWhitelistEntry)
|
||||
IPC_MESSAGE_HANDLER(CefProcessMsg_ClearCrossOriginWhitelist,
|
||||
|
@ -41,6 +45,11 @@ void CefRenderProcessObserver::OnRenderProcessShutdown() {
|
|||
CefContentRendererClient::Get()->OnRenderProcessShutdown();
|
||||
}
|
||||
|
||||
void CefRenderProcessObserver::OnSetIsIncognitoProcess(
|
||||
bool is_incognito_process) {
|
||||
is_incognito_process_ = is_incognito_process;
|
||||
}
|
||||
|
||||
void CefRenderProcessObserver::OnModifyCrossOriginWhitelistEntry(
|
||||
bool add,
|
||||
const Cef_CrossOriginWhiteListEntry_Params& params) {
|
||||
|
|
|
@ -17,6 +17,8 @@ class CefRenderProcessObserver : public content::RenderProcessObserver {
|
|||
CefRenderProcessObserver();
|
||||
~CefRenderProcessObserver() override;
|
||||
|
||||
static bool is_incognito_process() { return is_incognito_process_; }
|
||||
|
||||
// RenderProcessObserver implementation.
|
||||
bool OnControlMessageReceived(const IPC::Message& message) override;
|
||||
void WebKitInitialized() override;
|
||||
|
@ -24,11 +26,14 @@ class CefRenderProcessObserver : public content::RenderProcessObserver {
|
|||
|
||||
private:
|
||||
// Message handlers called on the render thread.
|
||||
void OnSetIsIncognitoProcess(bool is_incognito_process);
|
||||
void OnModifyCrossOriginWhitelistEntry(
|
||||
bool add,
|
||||
const Cef_CrossOriginWhiteListEntry_Params& params);
|
||||
void OnClearCrossOriginWhitelist();
|
||||
|
||||
static bool is_incognito_process_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefRenderProcessObserver);
|
||||
};
|
||||
|
||||
|
|
|
@ -14,6 +14,12 @@
|
|||
<include name="IDR_CEF_CREDITS_JS" file="..\..\..\chrome\browser\resources\about_credits.js" type="BINDATA" />
|
||||
<include name="IDR_CEF_LICENSE_TXT" file="..\..\LICENSE.txt" type="BINDATA" />
|
||||
<include name="IDR_CEF_VERSION_HTML" file="about_version.html" type="BINDATA" />
|
||||
|
||||
<!-- Features specific to CEF. -->
|
||||
<include name="IDR_CEF_EXTENSION_API_FEATURES" file="..\common\extensions\api\_api_features.json" type="BINDATA" />
|
||||
|
||||
<!-- Manifest files for built-in extensions. -->
|
||||
<include name="IDR_PDF_MANIFEST" file="..\..\..\chrome\browser\resources\pdf\manifest.json" type="BINDATA" />
|
||||
</includes>
|
||||
</release>
|
||||
</grit>
|
||||
|
|
|
@ -90,6 +90,26 @@ patches = [
|
|||
'name': 'ui_webview_1257',
|
||||
'path': '../ui/views/controls/webview/',
|
||||
},
|
||||
{
|
||||
# Allow specification of a custom WebContentsView.
|
||||
# http://code.google.com/p/chromiumembedded/issues/detail?id=1257
|
||||
'name': 'extensions_1257',
|
||||
'path': '../extensions/',
|
||||
},
|
||||
{
|
||||
# Allow specification of a custom WebContentsViewGuest implementation for
|
||||
# MimeHandlerView.
|
||||
# https://bitbucket.org/chromiumembedded/cef/issues/1565
|
||||
'name': 'mime_handler_view_1565',
|
||||
'path': '../extensions/browser/guest_view/mime_handler_view/',
|
||||
},
|
||||
{
|
||||
# Allow specification of a custom WebContentsViewGuest implementation for
|
||||
# BrowserPluginGuest.
|
||||
# https://bitbucket.org/chromiumembedded/cef/issues/1565
|
||||
'name': 'browser_plugin_guest_1565',
|
||||
'path': '../content/',
|
||||
},
|
||||
{
|
||||
# Allow customization of the WebView background color.
|
||||
# http://code.google.com/p/chromiumembedded/issues/detail?id=1161
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
diff --git browser/browser_plugin/browser_plugin_guest.cc browser/browser_plugin/browser_plugin_guest.cc
|
||||
index f438805..d199c6b 100644
|
||||
--- browser/browser_plugin/browser_plugin_guest.cc
|
||||
+++ browser/browser_plugin/browser_plugin_guest.cc
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "content/browser/renderer_host/render_widget_host_impl.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_view_base.h"
|
||||
#include "content/browser/web_contents/web_contents_impl.h"
|
||||
-#include "content/browser/web_contents/web_contents_view_guest.h"
|
||||
+#include "content/browser/web_contents/web_contents_view.h"
|
||||
#include "content/common/browser_plugin/browser_plugin_constants.h"
|
||||
#include "content/common/browser_plugin/browser_plugin_messages.h"
|
||||
#include "content/common/content_constants_internal.h"
|
||||
@@ -262,15 +262,16 @@ void BrowserPluginGuest::InitInternal(
|
||||
guest_window_rect_ = params.view_rect;
|
||||
|
||||
if (owner_web_contents_ != owner_web_contents) {
|
||||
- WebContentsViewGuest* new_view =
|
||||
- static_cast<WebContentsViewGuest*>(GetWebContents()->GetView());
|
||||
- if (owner_web_contents_)
|
||||
- new_view->OnGuestDetached(owner_web_contents_->GetView());
|
||||
+ if (owner_web_contents_) {
|
||||
+ delegate_->OnGuestDetached(GetWebContents()->GetView(),
|
||||
+ owner_web_contents_->GetView());
|
||||
+ }
|
||||
|
||||
// Once a BrowserPluginGuest has an embedder WebContents, it's considered to
|
||||
// be attached.
|
||||
owner_web_contents_ = owner_web_contents;
|
||||
- new_view->OnGuestAttached(owner_web_contents_->GetView());
|
||||
+ delegate_->OnGuestAttached(GetWebContents()->GetView(),
|
||||
+ owner_web_contents_->GetView());
|
||||
}
|
||||
|
||||
RendererPreferences* renderer_prefs =
|
||||
@@ -656,12 +657,9 @@ void BrowserPluginGuest::OnWillAttachComplete(
|
||||
// This will trigger a callback to RenderViewReady after a round-trip IPC.
|
||||
static_cast<RenderViewHostImpl*>(
|
||||
GetWebContents()->GetRenderViewHost())->Init();
|
||||
- WebContentsViewGuest* web_contents_view =
|
||||
- static_cast<WebContentsViewGuest*>(GetWebContents()->GetView());
|
||||
- if (!web_contents()->GetRenderViewHost()->GetView()) {
|
||||
- web_contents_view->CreateViewForWidget(
|
||||
- web_contents()->GetRenderViewHost(), true);
|
||||
- }
|
||||
+ if (!web_contents()->GetRenderViewHost()->GetView())
|
||||
+ delegate_->CreateViewForWidget(GetWebContents()->GetView(),
|
||||
+ web_contents()->GetRenderViewHost());
|
||||
}
|
||||
|
||||
InitInternal(params, embedder_web_contents);
|
||||
diff --git public/browser/browser_plugin_guest_delegate.cc public/browser/browser_plugin_guest_delegate.cc
|
||||
index fd7dec4..49d4f99 100644
|
||||
--- public/browser/browser_plugin_guest_delegate.cc
|
||||
+++ public/browser/browser_plugin_guest_delegate.cc
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "content/public/browser/browser_plugin_guest_delegate.h"
|
||||
|
||||
+#include "content/browser/web_contents/web_contents_view_guest.h"
|
||||
+
|
||||
namespace content {
|
||||
|
||||
bool BrowserPluginGuestDelegate::CanRunInDetachedState() const {
|
||||
@@ -30,4 +32,23 @@ bool BrowserPluginGuestDelegate::StopFinding(StopFindAction action) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+void BrowserPluginGuestDelegate::OnGuestAttached(
|
||||
+ content::WebContentsView* guest_view,
|
||||
+ content::WebContentsView* parent_view) {
|
||||
+ static_cast<WebContentsViewGuest*>(guest_view)->OnGuestAttached(parent_view);
|
||||
+}
|
||||
+
|
||||
+void BrowserPluginGuestDelegate::OnGuestDetached(
|
||||
+ content::WebContentsView* guest_view,
|
||||
+ content::WebContentsView* parent_view) {
|
||||
+ static_cast<WebContentsViewGuest*>(guest_view)->OnGuestAttached(parent_view);
|
||||
+}
|
||||
+
|
||||
+void BrowserPluginGuestDelegate::CreateViewForWidget(
|
||||
+ content::WebContentsView* guest_view,
|
||||
+ content::RenderWidgetHost* render_widget_host) {
|
||||
+ static_cast<WebContentsViewGuest*>(guest_view)->CreateViewForWidget(
|
||||
+ render_widget_host, true);
|
||||
+}
|
||||
+
|
||||
} // namespace content
|
||||
diff --git public/browser/browser_plugin_guest_delegate.h public/browser/browser_plugin_guest_delegate.h
|
||||
index 000e3b6..ced8765 100644
|
||||
--- public/browser/browser_plugin_guest_delegate.h
|
||||
+++ public/browser/browser_plugin_guest_delegate.h
|
||||
@@ -21,6 +21,8 @@ class Size;
|
||||
namespace content {
|
||||
|
||||
class GuestHost;
|
||||
+class RenderWidgetHost;
|
||||
+class WebContentsView;
|
||||
|
||||
// Objects implement this interface to get notified about changes in the guest
|
||||
// WebContents and to provide necessary functionality.
|
||||
@@ -86,6 +88,17 @@ class CONTENT_EXPORT BrowserPluginGuestDelegate {
|
||||
// Provides the delegate with an interface with which to communicate with the
|
||||
// content module.
|
||||
virtual void SetGuestHost(GuestHost* guest_host) {}
|
||||
+
|
||||
+ // Called when a guest is attached or detached.
|
||||
+ virtual void OnGuestAttached(content::WebContentsView* guest_view,
|
||||
+ content::WebContentsView* parent_view);
|
||||
+ virtual void OnGuestDetached(content::WebContentsView* guest_view,
|
||||
+ content::WebContentsView* parent_view);
|
||||
+
|
||||
+ // Called to create the view for the widget.
|
||||
+ virtual void CreateViewForWidget(
|
||||
+ content::WebContentsView* guest_view,
|
||||
+ content::RenderWidgetHost* render_widget_host);
|
||||
};
|
||||
|
||||
} // namespace content
|
|
@ -0,0 +1,30 @@
|
|||
diff --git browser/guest_view/extension_options/extension_options_guest.cc browser/guest_view/extension_options/extension_options_guest.cc
|
||||
index c882315..ff6d25f 100644
|
||||
--- browser/guest_view/extension_options/extension_options_guest.cc
|
||||
+++ browser/guest_view/extension_options/extension_options_guest.cc
|
||||
@@ -208,7 +208,9 @@ bool ExtensionOptionsGuest::ShouldCreateWebContents(
|
||||
const base::string16& frame_name,
|
||||
const GURL& target_url,
|
||||
const std::string& partition_id,
|
||||
- content::SessionStorageNamespace* session_storage_namespace) {
|
||||
+ content::SessionStorageNamespace* session_storage_namespace,
|
||||
+ content::WebContentsView** view,
|
||||
+ content::RenderViewHostDelegateView** delegate_view) {
|
||||
// This method handles opening links from within the guest. Since this guest
|
||||
// view is used for displaying embedded extension options, we want any
|
||||
// external links to be opened in a new tab, not in a new guest view.
|
||||
diff --git browser/guest_view/extension_options/extension_options_guest.h browser/guest_view/extension_options/extension_options_guest.h
|
||||
index b62d81a..8176f84 100644
|
||||
--- browser/guest_view/extension_options/extension_options_guest.h
|
||||
+++ browser/guest_view/extension_options/extension_options_guest.h
|
||||
@@ -54,7 +54,9 @@ class ExtensionOptionsGuest
|
||||
const base::string16& frame_name,
|
||||
const GURL& target_url,
|
||||
const std::string& partition_id,
|
||||
- content::SessionStorageNamespace* session_storage_namespace) override;
|
||||
+ content::SessionStorageNamespace* session_storage_namespace,
|
||||
+ content::WebContentsView** view,
|
||||
+ content::RenderViewHostDelegateView** delegate_view) override;
|
||||
|
||||
// content::WebContentsObserver implementation.
|
||||
void DidNavigateMainFrame(
|
|
@ -0,0 +1,130 @@
|
|||
diff --git mime_handler_view_guest.cc mime_handler_view_guest.cc
|
||||
index 61fd142..ed9a58d 100644
|
||||
--- mime_handler_view_guest.cc
|
||||
+++ mime_handler_view_guest.cc
|
||||
@@ -142,6 +142,8 @@ void MimeHandlerViewGuest::CreateWebContents(
|
||||
WebContents::CreateParams params(browser_context(),
|
||||
guest_site_instance.get());
|
||||
params.guest_delegate = this;
|
||||
+ if (delegate_)
|
||||
+ delegate_->OverrideWebContentsCreateParams(¶ms);
|
||||
callback.Run(WebContents::Create(params));
|
||||
}
|
||||
|
||||
@@ -183,6 +185,30 @@ bool MimeHandlerViewGuest::StopFinding(content::StopFindAction action) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+void MimeHandlerViewGuest::OnGuestAttached(
|
||||
+ content::WebContentsView* guest_view,
|
||||
+ content::WebContentsView* parent_view) {
|
||||
+ if (!delegate_ || !delegate_->OnGuestAttached(guest_view, parent_view))
|
||||
+ BrowserPluginGuestDelegate::OnGuestAttached(guest_view, parent_view);
|
||||
+}
|
||||
+
|
||||
+void MimeHandlerViewGuest::OnGuestDetached(
|
||||
+ content::WebContentsView* guest_view,
|
||||
+ content::WebContentsView* parent_view) {
|
||||
+ if (!delegate_ || !delegate_->OnGuestDetached(guest_view, parent_view))
|
||||
+ BrowserPluginGuestDelegate::OnGuestDetached(guest_view, parent_view);
|
||||
+}
|
||||
+
|
||||
+void MimeHandlerViewGuest::CreateViewForWidget(
|
||||
+ content::WebContentsView* guest_view,
|
||||
+ content::RenderWidgetHost* render_widget_host) {
|
||||
+ if (!delegate_ ||
|
||||
+ !delegate_->CreateViewForWidget(guest_view, render_widget_host)) {
|
||||
+ BrowserPluginGuestDelegate::CreateViewForWidget(guest_view,
|
||||
+ render_widget_host);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
content::WebContents* MimeHandlerViewGuest::OpenURLFromTab(
|
||||
content::WebContents* source,
|
||||
const content::OpenURLParams& params) {
|
||||
diff --git mime_handler_view_guest.h mime_handler_view_guest.h
|
||||
index f95aab7..fe4944e 100644
|
||||
--- mime_handler_view_guest.h
|
||||
+++ mime_handler_view_guest.h
|
||||
@@ -76,6 +76,13 @@ class MimeHandlerViewGuest : public guest_view::GuestView<MimeHandlerViewGuest>,
|
||||
const base::string16& search_text,
|
||||
const blink::WebFindOptions& options) override;
|
||||
bool StopFinding(content::StopFindAction action) override;
|
||||
+ void OnGuestAttached(content::WebContentsView* guest_view,
|
||||
+ content::WebContentsView* parent_view) override;
|
||||
+ void OnGuestDetached(content::WebContentsView* guest_view,
|
||||
+ content::WebContentsView* parent_view) override;
|
||||
+ void CreateViewForWidget(
|
||||
+ content::WebContentsView* guest_view,
|
||||
+ content::RenderWidgetHost* render_widget_host) override;
|
||||
|
||||
// WebContentsDelegate implementation.
|
||||
content::WebContents* OpenURLFromTab(
|
||||
diff --git mime_handler_view_guest_delegate.cc mime_handler_view_guest_delegate.cc
|
||||
index 63b81b8..0f63f48 100644
|
||||
--- mime_handler_view_guest_delegate.cc
|
||||
+++ mime_handler_view_guest_delegate.cc
|
||||
@@ -6,6 +6,24 @@
|
||||
|
||||
namespace extensions {
|
||||
|
||||
+bool MimeHandlerViewGuestDelegate::OnGuestAttached(
|
||||
+ content::WebContentsView* guest_view,
|
||||
+ content::WebContentsView* parent_view) {
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+bool MimeHandlerViewGuestDelegate::OnGuestDetached(
|
||||
+ content::WebContentsView* guest_view,
|
||||
+ content::WebContentsView* parent_view) {
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+bool MimeHandlerViewGuestDelegate::CreateViewForWidget(
|
||||
+ content::WebContentsView* guest_view,
|
||||
+ content::RenderWidgetHost* render_widget_host) {
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
bool MimeHandlerViewGuestDelegate::HandleContextMenu(
|
||||
content::WebContents* web_contents,
|
||||
const content::ContextMenuParams& params) {
|
||||
diff --git mime_handler_view_guest_delegate.h mime_handler_view_guest_delegate.h
|
||||
index b9a6fe3..6a2c3b0 100644
|
||||
--- mime_handler_view_guest_delegate.h
|
||||
+++ mime_handler_view_guest_delegate.h
|
||||
@@ -6,10 +6,11 @@
|
||||
#define EXTENSIONS_BROWSER_GUEST_VIEW_MIME_HANDLER_VIEW_MIME_HANDLER_VIEW_GUEST_DELEGATE_H_
|
||||
|
||||
#include "base/macros.h"
|
||||
+#include "content/public/browser/web_contents.h"
|
||||
|
||||
namespace content {
|
||||
-class WebContents;
|
||||
struct ContextMenuParams;
|
||||
+class RenderWidgetHost;
|
||||
} // namespace content
|
||||
|
||||
namespace extensions {
|
||||
@@ -22,6 +23,21 @@ class MimeHandlerViewGuestDelegate {
|
||||
explicit MimeHandlerViewGuestDelegate(MimeHandlerViewGuest* guest) {}
|
||||
virtual ~MimeHandlerViewGuestDelegate() {}
|
||||
|
||||
+ // Provides an opportunity to supply a custom view implementation.
|
||||
+ virtual void OverrideWebContentsCreateParams(
|
||||
+ content::WebContents::CreateParams* params) {}
|
||||
+
|
||||
+ // Called when a guest is attached or detached.
|
||||
+ virtual bool OnGuestAttached(content::WebContentsView* guest_view,
|
||||
+ content::WebContentsView* parent_view);
|
||||
+ virtual bool OnGuestDetached(content::WebContentsView* guest_view,
|
||||
+ content::WebContentsView* parent_view);
|
||||
+
|
||||
+ // Called to create the view for the widget.
|
||||
+ virtual bool CreateViewForWidget(
|
||||
+ content::WebContentsView* guest_view,
|
||||
+ content::RenderWidgetHost* render_widget_host);
|
||||
+
|
||||
// Attaches helpers upon initializing the WebContents.
|
||||
virtual void AttachHelpers() {}
|
||||
|
|
@ -44,19 +44,20 @@
|
|||
#define ID_TESTS_PRINT_TO_PDF 32716
|
||||
#define ID_TESTS_LAST 32716
|
||||
#define IDC_STATIC -1
|
||||
#define IDS_BINDING 1000
|
||||
#define IDS_DIALOGS 1001
|
||||
#define IDS_LOCALSTORAGE 1002
|
||||
#define IDS_LOGO 1003
|
||||
#define IDS_LOGOBALL 1004
|
||||
#define IDS_OSRTEST 1005
|
||||
#define IDS_OTHER_TESTS 1006
|
||||
#define IDS_PERFORMANCE 1007
|
||||
#define IDS_PERFORMANCE2 1008
|
||||
#define IDS_TRANSPARENCY 1009
|
||||
#define IDS_URLREQUEST 1010
|
||||
#define IDS_WINDOW 1011
|
||||
#define IDS_XMLHTTPREQUEST 1012
|
||||
#define IDS_BINDING_HTML 1000
|
||||
#define IDS_DIALOGS_HTML 1001
|
||||
#define IDS_LOCALSTORAGE_HTML 1002
|
||||
#define IDS_LOGO_PNG 1003
|
||||
#define IDS_OSRTEST_HTML 1004
|
||||
#define IDS_OTHER_TESTS_HTML 1005
|
||||
#define IDS_PDF_HTML 1006
|
||||
#define IDS_PDF_PDF 1007
|
||||
#define IDS_PERFORMANCE_HTML 1008
|
||||
#define IDS_PERFORMANCE2_HTML 1009
|
||||
#define IDS_TRANSPARENCY_HTML 1010
|
||||
#define IDS_URLREQUEST_HTML 1011
|
||||
#define IDS_WINDOW_HTML 1012
|
||||
#define IDS_XMLHTTPREQUEST_HTML 1013
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
|
|
|
@ -37,18 +37,20 @@ int GetResourceId(const char* resource_name) {
|
|||
char* name;
|
||||
int id;
|
||||
} resource_map[] = {
|
||||
{"binding.html", IDS_BINDING},
|
||||
{"dialogs.html", IDS_DIALOGS},
|
||||
{"localstorage.html", IDS_LOCALSTORAGE},
|
||||
{"logo.png", IDS_LOGO},
|
||||
{"osr_test.html", IDS_OSRTEST},
|
||||
{"other_tests.html", IDS_OTHER_TESTS},
|
||||
{"performance.html", IDS_PERFORMANCE},
|
||||
{"performance2.html", IDS_PERFORMANCE2},
|
||||
{"transparency.html", IDS_TRANSPARENCY},
|
||||
{"urlrequest.html", IDS_URLREQUEST},
|
||||
{"window.html", IDS_WINDOW},
|
||||
{"xmlhttprequest.html", IDS_XMLHTTPREQUEST},
|
||||
{"binding.html", IDS_BINDING_HTML},
|
||||
{"dialogs.html", IDS_DIALOGS_HTML},
|
||||
{"localstorage.html", IDS_LOCALSTORAGE_HTML},
|
||||
{"logo.png", IDS_LOGO_PNG},
|
||||
{"osr_test.html", IDS_OSRTEST_HTML},
|
||||
{"other_tests.html", IDS_OTHER_TESTS_HTML},
|
||||
{"pdf.html", IDS_PDF_HTML},
|
||||
{"pdf.pdf", IDS_PDF_PDF},
|
||||
{"performance.html", IDS_PERFORMANCE_HTML},
|
||||
{"performance2.html", IDS_PERFORMANCE2_HTML},
|
||||
{"transparency.html", IDS_TRANSPARENCY_HTML},
|
||||
{"urlrequest.html", IDS_URLREQUEST_HTML},
|
||||
{"window.html", IDS_WINDOW_HTML},
|
||||
{"xmlhttprequest.html", IDS_XMLHTTPREQUEST_HTML},
|
||||
};
|
||||
|
||||
for (int i = 0; i < sizeof(resource_map)/sizeof(_resource_map); ++i) {
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
<li><a href="http://tests/performance2">JavaScript Performance (2) Tests</a></li>
|
||||
<li><a href="http://tests/window">JavaScript Window Manipulation</a></li>
|
||||
<li><a href="http://tests/localstorage">Local Storage</a></li>
|
||||
<li><a href="http://tests/pdf.pdf">PDF Viewer direct</a></li>
|
||||
<li><a href="http://tests/pdf">PDF Viewer iframe</a></li>
|
||||
<li><a href="http://mrdoob.com/lab/javascript/requestanimationframe/">requestAnimationFrame</a></li>
|
||||
<li><a href="client://tests/handler.html">Scheme Handler</a></li>
|
||||
<li><a href="https://www.google.com/intl/en/chrome/demos/speech.html">Speech Input</a> - requires "enable-speech-input" flag</li>
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>PDF Test</title>
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<iframe src="pdf.pdf" width="500" height="500"></iframe>
|
||||
<iframe src="pdf.pdf" width="500" height="500"></iframe>
|
||||
</body>
|
||||
</html>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue