From dc3aae19e890c4a7891926ac146dd30d8cdec4bf Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Wed, 9 Sep 2015 16:05:39 +0200 Subject: [PATCH] Add plugin placeholder and policy support (issue #1708) - Default plugin loading policy can be specified using the new `--plugin-policy=[allow|block|detect]` command-line flag. - Move CefRequestHandler::OnBeforePluginLoad to CefRequestContextHandler and add a new policy argument that supports different actions (allow, block, detect, disable) on a per-plugin-instance basis. - Add CefContextMenuHandler::RunContextMenu for providing a custom context menu implementation. - Add CefResourceBundleHandler::GetDataResourceForScale for returning scaled resources (issue #1272). - Add CefResourceBundle for retrieving resources from the resource bundle (*.pak) files loaded by CEF during startup or via the CefResourceBundleHandler. - Linux: Fix Debug build IO access warning with CefGetMimeType. - cef_unittests: Move the refcounting implementation from TestHandler to subclasses in order to support interface inheritance from subclasses. --- cef.gyp | 31 +- cef.gypi | 2 + cef_paths.gypi | 10 + include/capi/cef_context_menu_handler_capi.h | 49 ++ .../capi/cef_request_context_handler_capi.h | 23 +- include/capi/cef_request_handler_capi.h | 9 - include/capi/cef_resource_bundle_capi.h | 107 +++ .../capi/cef_resource_bundle_handler_capi.h | 35 +- include/capi/cef_web_plugin_capi.h | 2 +- include/cef_context_menu_handler.h | 54 ++ include/cef_request_context_handler.h | 27 +- include/cef_request_handler.h | 13 - include/cef_resource_bundle.h | 99 +++ include/cef_resource_bundle_handler.h | 36 +- include/cef_web_plugin.h | 3 +- include/internal/cef_types.h | 49 ++ libcef/browser/browser_context.cc | 2 +- libcef/browser/browser_context.h | 9 + libcef/browser/browser_context_impl.cc | 43 +- libcef/browser/browser_context_impl.h | 3 + libcef/browser/browser_context_proxy.cc | 8 + libcef/browser/browser_context_proxy.h | 2 + libcef/browser/browser_main.cc | 4 + libcef/browser/browser_pref_store.cc | 9 +- libcef/browser/content_browser_client.cc | 58 +- libcef/browser/content_browser_client.h | 2 - libcef/browser/context_menu_params_impl.cc | 10 + libcef/browser/context_menu_params_impl.h | 2 + .../extensions/extensions_browser_client.cc | 5 +- .../extensions/plugin_info_message_filter.cc | 245 ------- libcef/browser/menu_creator.cc | 252 +++++-- libcef/browser/menu_creator.h | 14 + libcef/browser/menu_model_impl.cc | 36 + libcef/browser/menu_model_impl.h | 7 + .../plugins/plugin_info_message_filter.cc | 615 ++++++++++++++++++ .../plugin_info_message_filter.h | 61 +- libcef/common/cef_messages.h | 5 + libcef/common/cef_switches.cc | 10 + libcef/common/cef_switches.h | 4 + libcef/common/content_client.cc | 9 +- libcef/common/main_delegate.cc | 5 + libcef/common/parser_impl.cc | 5 + libcef/common/resource_bundle_impl.cc | 47 ++ libcef/common/resource_bundle_impl.h | 31 + libcef/renderer/content_renderer_client.cc | 238 +++++-- libcef/renderer/content_renderer_client.h | 12 +- .../plugins/cef_plugin_placeholder.cc | 285 ++++++++ .../renderer/plugins/cef_plugin_placeholder.h | 102 +++ libcef/renderer/plugins/plugin_preroller.cc | 91 +++ libcef/renderer/plugins/plugin_preroller.h | 61 ++ libcef/resources/cef_resources.grd | 16 + libcef/resources/cef_strings.grd | 46 ++ .../cpptoc/context_menu_handler_cpptoc.cc | 45 ++ .../cpptoc/context_menu_params_cpptoc.cc | 32 + .../cpptoc/request_context_handler_cpptoc.cc | 43 ++ libcef_dll/cpptoc/request_handler_cpptoc.cc | 32 - libcef_dll/cpptoc/resource_bundle_cpptoc.cc | 153 +++++ libcef_dll/cpptoc/resource_bundle_cpptoc.h | 35 + .../cpptoc/resource_bundle_handler_cpptoc.cc | 47 +- .../run_context_menu_callback_cpptoc.cc | 72 ++ .../cpptoc/run_context_menu_callback_cpptoc.h | 35 + libcef_dll/cpptoc/web_plugin_info_cpptoc.h | 2 + .../cpptoc/web_plugin_info_visitor_cpptoc.h | 2 + .../web_plugin_unstable_callback_cpptoc.h | 2 + .../ctocpp/context_menu_handler_ctocpp.cc | 44 ++ .../ctocpp/context_menu_handler_ctocpp.h | 3 + .../ctocpp/context_menu_params_ctocpp.cc | 28 + .../ctocpp/context_menu_params_ctocpp.h | 2 + .../ctocpp/request_context_handler_ctocpp.cc | 41 ++ .../ctocpp/request_context_handler_ctocpp.h | 4 + libcef_dll/ctocpp/request_handler_ctocpp.cc | 31 - libcef_dll/ctocpp/request_handler_ctocpp.h | 2 - libcef_dll/ctocpp/resource_bundle_ctocpp.cc | 104 +++ libcef_dll/ctocpp/resource_bundle_ctocpp.h | 42 ++ .../ctocpp/resource_bundle_handler_ctocpp.cc | 23 +- .../ctocpp/resource_bundle_handler_ctocpp.h | 4 +- .../run_context_menu_callback_ctocpp.cc | 64 ++ .../ctocpp/run_context_menu_callback_ctocpp.h | 39 ++ libcef_dll/ctocpp/web_plugin_info_ctocpp.h | 2 + .../ctocpp/web_plugin_info_visitor_ctocpp.h | 2 + .../web_plugin_unstable_callback_ctocpp.h | 2 + libcef_dll/libcef_dll.cc | 3 + libcef_dll/wrapper/libcef_dll_wrapper.cc | 3 + libcef_dll/wrapper_types.h | 2 + tests/cefclient/browser/client_app_browser.cc | 7 +- tests/cefclient/browser/client_app_browser.h | 6 +- .../cefclient/browser/root_window_manager.cc | 36 +- tests/cefclient/browser/root_window_manager.h | 2 + .../cefclient/renderer/client_app_renderer.cc | 3 +- tests/unittests/client_app_delegates.cc | 5 + tests/unittests/cookie_unittest.cc | 4 + tests/unittests/dialog_unittest.cc | 2 + tests/unittests/display_unittest.cc | 2 + tests/unittests/dom_unittest.cc | 2 + tests/unittests/download_unittest.cc | 2 + tests/unittests/draggable_regions_unittest.cc | 2 + tests/unittests/frame_unittest.cc | 2 + tests/unittests/geolocation_unittest.cc | 2 + tests/unittests/jsdialog_unittest.cc | 2 + tests/unittests/life_span_unittest.cc | 2 + tests/unittests/message_router_unittest.cc | 2 + tests/unittests/navigation_unittest.cc | 12 + tests/unittests/plugin_unittest.cc | 593 +++++++++++++++++ tests/unittests/process_message_unittest.cc | 2 + tests/unittests/request_context_unittest.cc | 4 + tests/unittests/request_handler_unittest.cc | 6 + tests/unittests/request_unittest.cc | 4 + tests/unittests/resource_manager_unittest.cc | 2 + tests/unittests/scheme_handler_unittest.cc | 2 + .../stream_resource_handler_unittest.cc | 2 + tests/unittests/test_handler.h | 3 - tests/unittests/urlrequest_unittest.cc | 2 + tests/unittests/v8_unittest.cc | 2 + tools/cef_parser.py | 1 + 114 files changed, 4007 insertions(+), 559 deletions(-) create mode 100644 include/capi/cef_resource_bundle_capi.h create mode 100644 include/cef_resource_bundle.h delete mode 100644 libcef/browser/extensions/plugin_info_message_filter.cc create mode 100644 libcef/browser/plugins/plugin_info_message_filter.cc rename libcef/browser/{extensions => plugins}/plugin_info_message_filter.h (58%) create mode 100644 libcef/common/resource_bundle_impl.cc create mode 100644 libcef/common/resource_bundle_impl.h create mode 100644 libcef/renderer/plugins/cef_plugin_placeholder.cc create mode 100644 libcef/renderer/plugins/cef_plugin_placeholder.h create mode 100644 libcef/renderer/plugins/plugin_preroller.cc create mode 100644 libcef/renderer/plugins/plugin_preroller.h create mode 100644 libcef_dll/cpptoc/resource_bundle_cpptoc.cc create mode 100644 libcef_dll/cpptoc/resource_bundle_cpptoc.h create mode 100644 libcef_dll/cpptoc/run_context_menu_callback_cpptoc.cc create mode 100644 libcef_dll/cpptoc/run_context_menu_callback_cpptoc.h create mode 100644 libcef_dll/ctocpp/resource_bundle_ctocpp.cc create mode 100644 libcef_dll/ctocpp/resource_bundle_ctocpp.h create mode 100644 libcef_dll/ctocpp/run_context_menu_callback_ctocpp.cc create mode 100644 libcef_dll/ctocpp/run_context_menu_callback_ctocpp.h create mode 100644 tests/unittests/plugin_unittest.cc diff --git a/cef.gyp b/cef.gyp index c0d33c518..2b65d4e1b 100644 --- a/cef.gyp +++ b/cef.gyp @@ -409,6 +409,8 @@ 'tests/cefclient/renderer/client_app_renderer.cc', 'tests/cefclient/renderer/client_app_renderer.h', 'tests/cefclient/resources/osr_test.html', + 'tests/cefclient/resources/pdf.html', + 'tests/cefclient/resources/pdf.pdf', 'tests/unittests/browser_info_map_unittest.cc', 'tests/unittests/command_line_unittest.cc', 'tests/unittests/cookie_unittest.cc', @@ -425,6 +427,7 @@ 'tests/unittests/navigation_unittest.cc', 'tests/unittests/os_rendering_unittest.cc', 'tests/unittests/parser_unittest.cc', + 'tests/unittests/plugin_unittest.cc', 'tests/unittests/print_unittest.cc', 'tests/unittests/process_message_unittest.cc', 'tests/unittests/request_context_unittest.cc', @@ -457,6 +460,8 @@ ], 'mac_bundle_resources': [ 'tests/cefclient/resources/osr_test.html', + 'tests/cefclient/resources/pdf.html', + 'tests/cefclient/resources/pdf.pdf', 'tests/unittests/mac/unittests.icns', 'tests/unittests/mac/English.lproj/InfoPlist.strings', 'tests/unittests/mac/English.lproj/MainMenu.xib', @@ -595,6 +600,8 @@ 'destination': '<(PRODUCT_DIR)/files', 'files': [ 'tests/cefclient/resources/osr_test.html', + 'tests/cefclient/resources/pdf.html', + 'tests/cefclient/resources/pdf.pdf', ], }, ], @@ -921,6 +928,7 @@ '<(DEPTH)/third_party/WebKit/public/web', # CEF grit resource includes '<(DEPTH)/cef/libcef/resources/grit_stub', + '<(DEPTH)/cef/libcef/resources/grit_stub/chrome', '<(grit_out_dir)', '<(SHARED_INTERMEDIATE_DIR)/ui/resources', '<(SHARED_INTERMEDIATE_DIR)/ui/strings', @@ -938,6 +946,8 @@ '<(DEPTH)/chrome/chrome.gyp:safe_browsing_proto', '<(DEPTH)/components/components.gyp:cdm_renderer', '<(DEPTH)/components/components.gyp:component_updater', + '<(DEPTH)/components/components.gyp:content_settings_core_browser', + '<(DEPTH)/components/components.gyp:content_settings_core_common', '<(DEPTH)/components/components.gyp:crash_component_breakpad_mac_to_be_deleted', '<(DEPTH)/components/components.gyp:crx_file', '<(DEPTH)/components/components.gyp:devtools_discovery', @@ -1080,8 +1090,6 @@ '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', @@ -1114,6 +1122,8 @@ 'libcef/browser/pepper/device_id_fetcher.cc', 'libcef/browser/permission_manager.cc', 'libcef/browser/permission_manager.h', + 'libcef/browser/plugins/plugin_info_message_filter.cc', + 'libcef/browser/plugins/plugin_info_message_filter.h', 'libcef/browser/print_settings_impl.cc', 'libcef/browser/print_settings_impl.h', 'libcef/browser/printing/printing_message_filter.cc', @@ -1210,6 +1220,8 @@ 'libcef/common/process_message_impl.h', 'libcef/common/request_impl.cc', 'libcef/common/request_impl.h', + 'libcef/common/resource_bundle_impl.cc', + 'libcef/common/resource_bundle_impl.h', 'libcef/common/response_impl.cc', 'libcef/common/response_impl.h', 'libcef/common/response_manager.cc', @@ -1262,6 +1274,10 @@ '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/plugins/cef_plugin_placeholder.cc', + 'libcef/renderer/plugins/cef_plugin_placeholder.h', + 'libcef/renderer/plugins/plugin_preroller.cc', + 'libcef/renderer/plugins/plugin_preroller.h', 'libcef/renderer/render_frame_observer.cc', 'libcef/renderer/render_frame_observer.h', 'libcef/renderer/render_message_filter.cc', @@ -1403,6 +1419,13 @@ # Include sources for widevine support. '<(DEPTH)/chrome/common/widevine_cdm_constants.cc', '<(DEPTH)/chrome/common/widevine_cdm_constants.h', + # Include sources for plugin placeholder support. + '<(DEPTH)/chrome/browser/plugins/plugin_finder.cc', + '<(DEPTH)/chrome/browser/plugins/plugin_finder.h', + '<(DEPTH)/chrome/browser/plugins/plugin_metadata.cc', + '<(DEPTH)/chrome/browser/plugins/plugin_metadata.h', + '<(DEPTH)/components/nacl/common/nacl_constants.cc', + '<(DEPTH)/components/nacl/common/nacl_constants.h', ], 'conditions': [ ['OS=="win"', { @@ -1754,6 +1777,9 @@ 'sources': [ 'tests/cefclient/browser/client_app_browser.cc', 'tests/cefclient/browser/client_app_browser.h', + 'tests/cefclient/browser/resource_util.h', + 'tests/cefclient/browser/resource_util_mac.mm', + 'tests/cefclient/browser/resource_util_posix.cc', 'tests/cefclient/common/client_app.cc', 'tests/cefclient/common/client_app.h', 'tests/cefclient/common/client_app_other.cc', @@ -1769,6 +1795,7 @@ 'tests/unittests/frame_unittest.cc', 'tests/unittests/message_router_unittest.cc', 'tests/unittests/navigation_unittest.cc', + 'tests/unittests/plugin_unittest.cc', 'tests/unittests/process_message_unittest.cc', 'tests/unittests/request_handler_unittest.cc', 'tests/unittests/request_unittest.cc', diff --git a/cef.gypi b/cef.gypi index cde635189..24115cc1c 100644 --- a/cef.gypi +++ b/cef.gypi @@ -11,6 +11,8 @@ 'enable_print_preview': 0, # Enable support for Widevine CDM. 'enable_widevine': 1, + # Disable support for plugin installation. + 'enable_plugin_installation': 0, 'conditions': [ # Directory for CEF source files. [ 'OS=="win"', { diff --git a/cef_paths.gypi b/cef_paths.gypi index 948ebc1a5..161927330 100644 --- a/cef_paths.gypi +++ b/cef_paths.gypi @@ -52,6 +52,7 @@ 'include/cef_request_context.h', 'include/cef_request_context_handler.h', 'include/cef_request_handler.h', + 'include/cef_resource_bundle.h', 'include/cef_resource_bundle_handler.h', 'include/cef_resource_handler.h', 'include/cef_response.h', @@ -110,6 +111,7 @@ 'include/capi/cef_request_context_capi.h', 'include/capi/cef_request_context_handler_capi.h', 'include/capi/cef_request_handler_capi.h', + 'include/capi/cef_resource_bundle_capi.h', 'include/capi/cef_resource_bundle_handler_capi.h', 'include/capi/cef_resource_handler_capi.h', 'include/capi/cef_response_capi.h', @@ -248,12 +250,16 @@ 'libcef_dll/ctocpp/request_context_handler_ctocpp.h', 'libcef_dll/ctocpp/request_handler_ctocpp.cc', 'libcef_dll/ctocpp/request_handler_ctocpp.h', + 'libcef_dll/cpptoc/resource_bundle_cpptoc.cc', + 'libcef_dll/cpptoc/resource_bundle_cpptoc.h', 'libcef_dll/ctocpp/resource_bundle_handler_ctocpp.cc', 'libcef_dll/ctocpp/resource_bundle_handler_ctocpp.h', 'libcef_dll/ctocpp/resource_handler_ctocpp.cc', 'libcef_dll/ctocpp/resource_handler_ctocpp.h', 'libcef_dll/cpptoc/response_cpptoc.cc', 'libcef_dll/cpptoc/response_cpptoc.h', + 'libcef_dll/cpptoc/run_context_menu_callback_cpptoc.cc', + 'libcef_dll/cpptoc/run_context_menu_callback_cpptoc.h', 'libcef_dll/ctocpp/run_file_dialog_callback_ctocpp.cc', 'libcef_dll/ctocpp/run_file_dialog_callback_ctocpp.h', 'libcef_dll/cpptoc/sslcert_principal_cpptoc.cc', @@ -442,12 +448,16 @@ 'libcef_dll/cpptoc/request_context_handler_cpptoc.h', 'libcef_dll/cpptoc/request_handler_cpptoc.cc', 'libcef_dll/cpptoc/request_handler_cpptoc.h', + 'libcef_dll/ctocpp/resource_bundle_ctocpp.cc', + 'libcef_dll/ctocpp/resource_bundle_ctocpp.h', 'libcef_dll/cpptoc/resource_bundle_handler_cpptoc.cc', 'libcef_dll/cpptoc/resource_bundle_handler_cpptoc.h', 'libcef_dll/cpptoc/resource_handler_cpptoc.cc', 'libcef_dll/cpptoc/resource_handler_cpptoc.h', 'libcef_dll/ctocpp/response_ctocpp.cc', 'libcef_dll/ctocpp/response_ctocpp.h', + 'libcef_dll/ctocpp/run_context_menu_callback_ctocpp.cc', + 'libcef_dll/ctocpp/run_context_menu_callback_ctocpp.h', 'libcef_dll/cpptoc/run_file_dialog_callback_cpptoc.cc', 'libcef_dll/cpptoc/run_file_dialog_callback_cpptoc.h', 'libcef_dll/ctocpp/sslcert_principal_ctocpp.cc', diff --git a/include/capi/cef_context_menu_handler_capi.h b/include/capi/cef_context_menu_handler_capi.h index 531409b77..388e73052 100644 --- a/include/capi/cef_context_menu_handler_capi.h +++ b/include/capi/cef_context_menu_handler_capi.h @@ -49,6 +49,29 @@ extern "C" { struct _cef_context_menu_params_t; +/// +// Callback structure used for continuation of custom context menu display. +/// +typedef struct _cef_run_context_menu_callback_t { + /// + // Base structure. + /// + cef_base_t base; + + /// + // Complete context menu display by selecting the specified |command_id| and + // |event_flags|. + /// + void (CEF_CALLBACK *cont)(struct _cef_run_context_menu_callback_t* self, + int command_id, cef_event_flags_t event_flags); + + /// + // Cancel context menu display. + /// + void (CEF_CALLBACK *cancel)(struct _cef_run_context_menu_callback_t* self); +} cef_run_context_menu_callback_t; + + /// // Implement this structure to handle context menu events. The functions of this // structure will be called on the UI thread. @@ -71,6 +94,20 @@ typedef struct _cef_context_menu_handler_t { struct _cef_frame_t* frame, struct _cef_context_menu_params_t* params, struct _cef_menu_model_t* model); + /// + // Called to allow custom display of the context menu. |params| provides + // information about the context menu state. |model| contains the context menu + // model resulting from OnBeforeContextMenu. For custom display return true + // (1) and execute |callback| either synchronously or asynchronously with the + // selected command ID. For default display return false (0). Do not keep + // references to |params| or |model| outside of this callback. + /// + int (CEF_CALLBACK *run_context_menu)(struct _cef_context_menu_handler_t* self, + struct _cef_browser_t* browser, struct _cef_frame_t* frame, + struct _cef_context_menu_params_t* params, + struct _cef_menu_model_t* model, + struct _cef_run_context_menu_callback_t* callback); + /// // Called to execute a command selected from the context menu. Return true (1) // if the command was handled or false (0) for the default implementation. See @@ -232,6 +269,18 @@ typedef struct _cef_context_menu_params_t { /// cef_context_menu_edit_state_flags_t (CEF_CALLBACK *get_edit_state_flags)( struct _cef_context_menu_params_t* self); + + /// + // Returns true (1) if the context menu contains items specified by the + // renderer process (for example, plugin placeholder or pepper plugin menu + // items). + /// + int (CEF_CALLBACK *is_custom_menu)(struct _cef_context_menu_params_t* self); + + /// + // Returns true (1) if the context menu was invoked from a pepper plugin. + /// + int (CEF_CALLBACK *is_pepper_menu)(struct _cef_context_menu_params_t* self); } cef_context_menu_params_t; diff --git a/include/capi/cef_request_context_handler_capi.h b/include/capi/cef_request_context_handler_capi.h index 09716402c..1856ca5e1 100644 --- a/include/capi/cef_request_context_handler_capi.h +++ b/include/capi/cef_request_context_handler_capi.h @@ -40,6 +40,7 @@ #include "include/capi/cef_base_capi.h" #include "include/capi/cef_cookie_capi.h" +#include "include/capi/cef_web_plugin_capi.h" #ifdef __cplusplus extern "C" { @@ -58,12 +59,30 @@ typedef struct _cef_request_context_handler_t { cef_base_t base; /// - // Called on the IO thread to retrieve the cookie manager. If this function - // returns NULL the default cookie manager retrievable via + // Called on the browser process IO thread to retrieve the cookie manager. If + // this function returns NULL the default cookie manager retrievable via // cef_request_tContext::get_default_cookie_manager() will be used. /// struct _cef_cookie_manager_t* (CEF_CALLBACK *get_cookie_manager)( struct _cef_request_context_handler_t* self); + + /// + // Called on the browser process IO thread before a plugin instance is loaded. + // |mime_type| is the mime type of the plugin that will be loaded. + // |plugin_url| is the content URL that the plugin will load and may be NULL. + // |top_origin_url| is the URL for the top-level frame that contains the + // plugin. |plugin_info| includes additional information about the plugin that + // will be loaded. |plugin_policy| is the recommended policy. Modify + // |plugin_policy| and return true (1) to change the policy. Return false (0) + // to use the recommended policy. The default plugin policy can be set at + // runtime using the `--plugin-policy=[allow|detect|block]` command-line flag. + /// + int (CEF_CALLBACK *on_before_plugin_load)( + struct _cef_request_context_handler_t* self, + const cef_string_t* mime_type, const cef_string_t* plugin_url, + const cef_string_t* top_origin_url, + struct _cef_web_plugin_info_t* plugin_info, + cef_plugin_policy_t* plugin_policy); } cef_request_context_handler_t; diff --git a/include/capi/cef_request_handler_capi.h b/include/capi/cef_request_handler_capi.h index 45ff7718b..83bd825d0 100644 --- a/include/capi/cef_request_handler_capi.h +++ b/include/capi/cef_request_handler_capi.h @@ -46,7 +46,6 @@ #include "include/capi/cef_resource_handler_capi.h" #include "include/capi/cef_response_capi.h" #include "include/capi/cef_ssl_info_capi.h" -#include "include/capi/cef_web_plugin_capi.h" #ifdef __cplusplus extern "C" { @@ -214,14 +213,6 @@ typedef struct _cef_request_handler_t { const cef_string_t* request_url, struct _cef_sslinfo_t* ssl_info, struct _cef_request_callback_t* callback); - /// - // Called on the browser process IO thread before a plugin is loaded. Return - // true (1) to block loading of the plugin. - /// - int (CEF_CALLBACK *on_before_plugin_load)(struct _cef_request_handler_t* self, - struct _cef_browser_t* browser, const cef_string_t* url, - const cef_string_t* policy_url, struct _cef_web_plugin_info_t* info); - /// // Called on the browser process UI thread when a plugin has crashed. // |plugin_path| is the path of the plugin that crashed. diff --git a/include/capi/cef_resource_bundle_capi.h b/include/capi/cef_resource_bundle_capi.h new file mode 100644 index 000000000..fee978616 --- /dev/null +++ b/include/capi/cef_resource_bundle_capi.h @@ -0,0 +1,107 @@ +// Copyright (c) 2015 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool and should not edited +// by hand. See the translator.README.txt file in the tools directory for +// more information. +// + +#ifndef CEF_INCLUDE_CAPI_CEF_RESOURCE_BUNDLE_CAPI_H_ +#define CEF_INCLUDE_CAPI_CEF_RESOURCE_BUNDLE_CAPI_H_ +#pragma once + +#include "include/capi/cef_base_capi.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/// +// Structure used for retrieving resources from the resource bundle (*.pak) +// files loaded by CEF during startup or via the cef_resource_bundle_tHandler +// returned from cef_app_t::GetResourceBundleHandler. See CefSettings for +// additional options related to resource bundle loading. The functions of this +// structure may be called on any thread unless otherwise indicated. +/// +typedef struct _cef_resource_bundle_t { + /// + // Base structure. + /// + cef_base_t base; + + /// + // Returns the localized string for the specified |string_id| or an NULL + // string if the value is not found. Include cef_pack_strings.h for a listing + // of valid string ID values. + /// + // The resulting string must be freed by calling cef_string_userfree_free(). + cef_string_userfree_t (CEF_CALLBACK *get_localized_string)( + struct _cef_resource_bundle_t* self, int string_id); + + /// + // Retrieves the contents of the specified scale independent |resource_id|. If + // the value is found then |data| and |data_size| will be populated and this + // function will return true (1). If the value is not found then this function + // will return false (0). The returned |data| pointer will remain resident in + // memory and should not be freed. Include cef_pack_resources.h for a listing + // of valid resource ID values. + /// + int (CEF_CALLBACK *get_data_resource)(struct _cef_resource_bundle_t* self, + int resource_id, void** data, size_t* data_size); + + /// + // Retrieves the contents of the specified |resource_id| nearest the scale + // factor |scale_factor|. Use a |scale_factor| value of SCALE_FACTOR_NONE for + // scale independent resources or call GetDataResource instead. If the value + // is found then |data| and |data_size| will be populated and this function + // will return true (1). If the value is not found then this function will + // return false (0). The returned |data| pointer will remain resident in + // memory and should not be freed. Include cef_pack_resources.h for a listing + // of valid resource ID values. + /// + int (CEF_CALLBACK *get_data_resource_for_scale)( + struct _cef_resource_bundle_t* self, int resource_id, + cef_scale_factor_t scale_factor, void** data, size_t* data_size); +} cef_resource_bundle_t; + + +/// +// Returns the global resource bundle instance. +/// +CEF_EXPORT cef_resource_bundle_t* cef_resource_bundle_get_global(); + + +#ifdef __cplusplus +} +#endif + +#endif // CEF_INCLUDE_CAPI_CEF_RESOURCE_BUNDLE_CAPI_H_ diff --git a/include/capi/cef_resource_bundle_handler_capi.h b/include/capi/cef_resource_bundle_handler_capi.h index b84adc47a..7056bc562 100644 --- a/include/capi/cef_resource_bundle_handler_capi.h +++ b/include/capi/cef_resource_bundle_handler_capi.h @@ -46,8 +46,9 @@ extern "C" { /// -// Structure used to implement a custom resource bundle structure. The functions -// of this structure may be called on multiple threads. +// Structure used to implement a custom resource bundle structure. See +// CefSettings for additional options related to resource bundle loading. The +// functions of this structure may be called on multiple threads. /// typedef struct _cef_resource_bundle_handler_t { /// @@ -56,26 +57,38 @@ typedef struct _cef_resource_bundle_handler_t { cef_base_t base; /// - // Called to retrieve a localized translation for the string specified by - // |message_id|. To provide the translation set |string| to the translation - // string and return true (1). To use the default translation return false - // (0). Supported message IDs are listed in cef_pack_strings.h. + // Called to retrieve a localized translation for the specified |string_id|. + // To provide the translation set |string| to the translation string and + // return true (1). To use the default translation return false (0). Include + // cef_pack_strings.h for a listing of valid string ID values. /// int (CEF_CALLBACK *get_localized_string)( - struct _cef_resource_bundle_handler_t* self, int message_id, + struct _cef_resource_bundle_handler_t* self, int string_id, cef_string_t* string); /// - // Called to retrieve data for the resource specified by |resource_id|. To - // provide the resource data set |data| and |data_size| to the data pointer + // Called to retrieve data for the specified scale independent |resource_id|. + // To provide the resource data set |data| and |data_size| to the data pointer // and size respectively and return true (1). To use the default resource data // return false (0). The resource data will not be copied and must remain - // resident in memory. Supported resource IDs are listed in - // cef_pack_resources.h. + // resident in memory. Include cef_pack_resources.h for a listing of valid + // resource ID values. /// int (CEF_CALLBACK *get_data_resource)( struct _cef_resource_bundle_handler_t* self, int resource_id, void** data, size_t* data_size); + + /// + // Called to retrieve data for the specified |resource_id| nearest the scale + // factor |scale_factor|. To provide the resource data set |data| and + // |data_size| to the data pointer and size respectively and return true (1). + // To use the default resource data return false (0). The resource data will + // not be copied and must remain resident in memory. Include + // cef_pack_resources.h for a listing of valid resource ID values. + /// + int (CEF_CALLBACK *get_data_resource_for_scale)( + struct _cef_resource_bundle_handler_t* self, int resource_id, + cef_scale_factor_t scale_factor, void** data, size_t* data_size); } cef_resource_bundle_handler_t; diff --git a/include/capi/cef_web_plugin_capi.h b/include/capi/cef_web_plugin_capi.h index 05a779a1c..eb0ef1c87 100644 --- a/include/capi/cef_web_plugin_capi.h +++ b/include/capi/cef_web_plugin_capi.h @@ -39,12 +39,12 @@ #pragma once #include "include/capi/cef_base_capi.h" -#include "include/capi/cef_browser_capi.h" #ifdef __cplusplus extern "C" { #endif +struct _cef_browser_t; /// // Information about a specific web plugin. diff --git a/include/cef_context_menu_handler.h b/include/cef_context_menu_handler.h index d8751be6b..ab4503577 100644 --- a/include/cef_context_menu_handler.h +++ b/include/cef_context_menu_handler.h @@ -45,6 +45,30 @@ class CefContextMenuParams; + +/// +// Callback interface used for continuation of custom context menu display. +/// +/*--cef(source=library)--*/ +class CefRunContextMenuCallback : public virtual CefBase { + public: + typedef cef_event_flags_t EventFlags; + + /// + // Complete context menu display by selecting the specified |command_id| and + // |event_flags|. + /// + /*--cef(capi_name=cont)--*/ + virtual void Continue(int command_id, EventFlags event_flags) =0; + + /// + // Cancel context menu display. + /// + /*--cef()--*/ + virtual void Cancel() =0; +}; + + /// // Implement this interface to handle context menu events. The methods of this // class will be called on the UI thread. @@ -67,6 +91,23 @@ class CefContextMenuHandler : public virtual CefBase { CefRefPtr params, CefRefPtr model) {} + /// + // Called to allow custom display of the context menu. |params| provides + // information about the context menu state. |model| contains the context menu + // model resulting from OnBeforeContextMenu. For custom display return true + // and execute |callback| either synchronously or asynchronously with the + // selected command ID. For default display return false. Do not keep + // references to |params| or |model| outside of this callback. + /// + /*--cef()--*/ + virtual bool RunContextMenu(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr params, + CefRefPtr model, + CefRefPtr callback) { + return false; + } + /// // Called to execute a command selected from the context menu. Return true if // the command was handled or false for the default implementation. See @@ -226,6 +267,19 @@ class CefContextMenuParams : public virtual CefBase { /// /*--cef(default_retval=CM_EDITFLAG_NONE)--*/ virtual EditStateFlags GetEditStateFlags() =0; + + /// + // Returns true if the context menu contains items specified by the renderer + // process (for example, plugin placeholder or pepper plugin menu items). + /// + /*--cef()--*/ + virtual bool IsCustomMenu() =0; + + /// + // Returns true if the context menu was invoked from a pepper plugin. + /// + /*--cef()--*/ + virtual bool IsPepperMenu() =0; }; #endif // CEF_INCLUDE_CEF_CONTEXT_MENU_HANDLER_H_ diff --git a/include/cef_request_context_handler.h b/include/cef_request_context_handler.h index c69f119da..efe55fa41 100644 --- a/include/cef_request_context_handler.h +++ b/include/cef_request_context_handler.h @@ -40,6 +40,7 @@ #include "include/cef_base.h" #include "include/cef_cookie.h" +#include "include/cef_web_plugin.h" /// // Implement this interface to provide handler implementations. The handler @@ -49,13 +50,35 @@ /*--cef(source=client,no_debugct_check)--*/ class CefRequestContextHandler : public virtual CefBase { public: + typedef cef_plugin_policy_t PluginPolicy; + /// - // Called on the IO thread to retrieve the cookie manager. If this method - // returns NULL the default cookie manager retrievable via + // Called on the browser process IO thread to retrieve the cookie manager. If + // this method returns NULL the default cookie manager retrievable via // CefRequestContext::GetDefaultCookieManager() will be used. /// /*--cef()--*/ virtual CefRefPtr GetCookieManager() { return NULL; } + + /// + // Called on the browser process IO thread before a plugin instance is loaded. + // |mime_type| is the mime type of the plugin that will be loaded. + // |plugin_url| is the content URL that the plugin will load and may be empty. + // |top_origin_url| is the URL for the top-level frame that contains the + // plugin. |plugin_info| includes additional information about the plugin that + // will be loaded. |plugin_policy| is the recommended policy. Modify + // |plugin_policy| and return true to change the policy. Return false to use + // the recommended policy. The default plugin policy can be set at runtime + // using the `--plugin-policy=[allow|detect|block]` command-line flag. + /// + /*--cef(optional_param=plugin_url)--*/ + virtual bool OnBeforePluginLoad(const CefString& mime_type, + const CefString& plugin_url, + const CefString& top_origin_url, + CefRefPtr plugin_info, + PluginPolicy* plugin_policy) { + return false; + } }; #endif // CEF_INCLUDE_CEF_REQUEST_CONTEXT_HANDLER_H_ diff --git a/include/cef_request_handler.h b/include/cef_request_handler.h index 1e252c793..1327a8045 100644 --- a/include/cef_request_handler.h +++ b/include/cef_request_handler.h @@ -46,7 +46,6 @@ #include "include/cef_response.h" #include "include/cef_request.h" #include "include/cef_ssl_info.h" -#include "include/cef_web_plugin.h" /// @@ -248,18 +247,6 @@ class CefRequestHandler : public virtual CefBase { return false; } - /// - // Called on the browser process IO thread before a plugin is loaded. Return - // true to block loading of the plugin. - /// - /*--cef(optional_param=url,optional_param=policy_url)--*/ - virtual bool OnBeforePluginLoad(CefRefPtr browser, - const CefString& url, - const CefString& policy_url, - CefRefPtr info) { - return false; - } - /// // Called on the browser process UI thread when a plugin has crashed. // |plugin_path| is the path of the plugin that crashed. diff --git a/include/cef_resource_bundle.h b/include/cef_resource_bundle.h new file mode 100644 index 000000000..3b064ffec --- /dev/null +++ b/include/cef_resource_bundle.h @@ -0,0 +1,99 @@ +// Copyright (c) 2015 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_RESOURCE_BUNDLE_H_ +#define CEF_INCLUDE_CEF_RESOURCE_BUNDLE_H_ +#pragma once + +#include "include/cef_base.h" + +/// +// Class used for retrieving resources from the resource bundle (*.pak) files +// loaded by CEF during startup or via the CefResourceBundleHandler returned +// from CefApp::GetResourceBundleHandler. See CefSettings for additional options +// related to resource bundle loading. The methods of this class may be called +// on any thread unless otherwise indicated. +/// +/*--cef(source=library,no_debugct_check)--*/ +class CefResourceBundle : public virtual CefBase { + public: + typedef cef_scale_factor_t ScaleFactor; + + /// + // Returns the global resource bundle instance. + /// + /*--cef()--*/ + static CefRefPtr GetGlobal(); + + /// + // Returns the localized string for the specified |string_id| or an empty + // string if the value is not found. Include cef_pack_strings.h for a listing + // of valid string ID values. + /// + /*--cef()--*/ + virtual CefString GetLocalizedString(int string_id) =0; + + /// + // Retrieves the contents of the specified scale independent |resource_id|. + // If the value is found then |data| and |data_size| will be populated and + // this method will return true. If the value is not found then this method + // will return false. The returned |data| pointer will remain resident in + // memory and should not be freed. Include cef_pack_resources.h for a listing + // of valid resource ID values. + /// + /*--cef()--*/ + virtual bool GetDataResource(int resource_id, + void*& data, + size_t& data_size) =0; + + /// + // Retrieves the contents of the specified |resource_id| nearest the scale + // factor |scale_factor|. Use a |scale_factor| value of SCALE_FACTOR_NONE for + // scale independent resources or call GetDataResource instead. If the value + // is found then |data| and |data_size| will be populated and this method will + // return true. If the value is not found then this method will return false. + // The returned |data| pointer will remain resident in memory and should not + // be freed. Include cef_pack_resources.h for a listing of valid resource ID + // values. + /// + /*--cef()--*/ + virtual bool GetDataResourceForScale(int resource_id, + ScaleFactor scale_factor, + void*& data, + size_t& data_size) =0; +}; + +#endif // CEF_INCLUDE_CEF_RESOURCE_BUNDLE_H_ diff --git a/include/cef_resource_bundle_handler.h b/include/cef_resource_bundle_handler.h index 2cd39a5eb..afc46da74 100644 --- a/include/cef_resource_bundle_handler.h +++ b/include/cef_resource_bundle_handler.h @@ -41,33 +41,51 @@ #include "include/cef_base.h" /// -// Class used to implement a custom resource bundle interface. The methods of +// Class used to implement a custom resource bundle interface. See CefSettings +// for additional options related to resource bundle loading. The methods of // this class may be called on multiple threads. /// /*--cef(source=client)--*/ class CefResourceBundleHandler : public virtual CefBase { public: + typedef cef_scale_factor_t ScaleFactor; + /// - // Called to retrieve a localized translation for the string specified by - // |message_id|. To provide the translation set |string| to the translation - // string and return true. To use the default translation return false. - // Supported message IDs are listed in cef_pack_strings.h. + // Called to retrieve a localized translation for the specified |string_id|. + // To provide the translation set |string| to the translation string and + // return true. To use the default translation return false. Include + // cef_pack_strings.h for a listing of valid string ID values. /// /*--cef()--*/ - virtual bool GetLocalizedString(int message_id, + virtual bool GetLocalizedString(int string_id, CefString& string) =0; /// - // Called to retrieve data for the resource specified by |resource_id|. To - // provide the resource data set |data| and |data_size| to the data pointer + // Called to retrieve data for the specified scale independent |resource_id|. + // To provide the resource data set |data| and |data_size| to the data pointer // and size respectively and return true. To use the default resource data // return false. The resource data will not be copied and must remain resident - // in memory. Supported resource IDs are listed in cef_pack_resources.h. + // in memory. Include cef_pack_resources.h for a listing of valid resource ID + // values. /// /*--cef()--*/ virtual bool GetDataResource(int resource_id, void*& data, size_t& data_size) =0; + + /// + // Called to retrieve data for the specified |resource_id| nearest the scale + // factor |scale_factor|. To provide the resource data set |data| and + // |data_size| to the data pointer and size respectively and return true. To + // use the default resource data return false. The resource data will not be + // copied and must remain resident in memory. Include cef_pack_resources.h for + // a listing of valid resource ID values. + /// + /*--cef()--*/ + virtual bool GetDataResourceForScale(int resource_id, + ScaleFactor scale_factor, + void*& data, + size_t& data_size) =0; }; #endif // CEF_INCLUDE_CEF_RESOURCE_BUNDLE_HANDLER_H_ diff --git a/include/cef_web_plugin.h b/include/cef_web_plugin.h index 0ff2b8ea1..9247a4d9f 100644 --- a/include/cef_web_plugin.h +++ b/include/cef_web_plugin.h @@ -38,7 +38,8 @@ #define CEF_INCLUDE_CEF_WEB_PLUGIN_H_ #include "include/cef_base.h" -#include "include/cef_browser.h" + +class CefBrowser; /// // Information about a specific web plugin. diff --git a/include/internal/cef_types.h b/include/internal/cef_types.h index 2790f2c4e..bafef7e8c 100644 --- a/include/internal/cef_types.h +++ b/include/internal/cef_types.h @@ -1423,6 +1423,11 @@ typedef enum { MENU_ID_NO_SPELLING_SUGGESTIONS = 205, MENU_ID_ADD_TO_DICTIONARY = 206, + // Custom menu items originating from the renderer process. For example, + // plugin placeholder menu items or Flash menu items. + MENU_ID_CUSTOM_FIRST = 220, + MENU_ID_CUSTOM_LAST = 250, + // All user-defined menu IDs should come between MENU_ID_USER_FIRST and // MENU_ID_USER_LAST to avoid overlapping the Chromium and CEF ID ranges // defined in the tools/gritsettings/resource_ids file. @@ -2241,6 +2246,50 @@ typedef struct _cef_pdf_print_settings_t { } cef_pdf_print_settings_t; +/// +// Supported UI scale factors for the platform. SCALE_FACTOR_NONE is used for +// density independent resources such as string, html/js files or an image that +// can be used for any scale factors (such as wallpapers). +/// +typedef enum { + SCALE_FACTOR_NONE = 0, + SCALE_FACTOR_100P, + SCALE_FACTOR_125P, + SCALE_FACTOR_133P, + SCALE_FACTOR_140P, + SCALE_FACTOR_150P, + SCALE_FACTOR_180P, + SCALE_FACTOR_200P, + SCALE_FACTOR_250P, + SCALE_FACTOR_300P, +} cef_scale_factor_t; + +/// +// Plugin policies supported by CefRequestContextHandler::OnBeforePluginLoad. +/// +typedef enum { + /// + // Allow the content. + /// + PLUGIN_POLICY_ALLOW, + + /// + // Allow important content and block unimportant content based on heuristics. + // The user can manually load blocked content. + /// + PLUGIN_POLICY_DETECT_IMPORTANT, + + /// + // Block the content. The user can manually load blocked content. + /// + PLUGIN_POLICY_BLOCK, + + /// + // Disable the content. The user cannot load disabled content. + /// + PLUGIN_POLICY_DISABLE, +} cef_plugin_policy_t; + #ifdef __cplusplus } #endif diff --git a/libcef/browser/browser_context.cc b/libcef/browser/browser_context.cc index 7c532cbc2..7ceff98b0 100644 --- a/libcef/browser/browser_context.cc +++ b/libcef/browser/browser_context.cc @@ -59,7 +59,7 @@ void CefBrowserContext::Initialize() { // Spell checking support and possibly other subsystems retrieve the // PrefService associated with a BrowserContext via UserPrefs::Get(). - PrefService* pref_service = CefContentBrowserClient::Get()->pref_service(); + PrefService* pref_service = GetPrefs(); DCHECK(pref_service); user_prefs::UserPrefs::Set(this, pref_service); diff --git a/libcef/browser/browser_context.h b/libcef/browser/browser_context.h index f12ba503a..577000472 100644 --- a/libcef/browser/browser_context.h +++ b/libcef/browser/browser_context.h @@ -104,6 +104,9 @@ // CefURLRequestContextGetter* destruction. */ +class HostContentSettingsMap; +class PrefService; + namespace extensions { class CefExtensionSystem; } @@ -142,6 +145,12 @@ class CefBrowserContext content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors) = 0; + // Settings for plugins and extensions. + virtual HostContentSettingsMap* GetHostContentSettingsMap() = 0; + + // Preferences. + virtual PrefService* GetPrefs() = 0; + CefResourceContext* resource_context() const { return resource_context_.get(); } diff --git a/libcef/browser/browser_context_impl.cc b/libcef/browser/browser_context_impl.cc index 7aff01634..d087ba0c9 100644 --- a/libcef/browser/browser_context_impl.cc +++ b/libcef/browser/browser_context_impl.cc @@ -13,13 +13,17 @@ #include "libcef/browser/permission_manager.h" #include "libcef/browser/ssl_host_state_delegate.h" #include "libcef/browser/thread_util.h" +#include "libcef/common/cef_switches.h" #include "libcef/common/extensions/extensions_util.h" +#include "base/command_line.h" #include "base/files/file_util.h" #include "base/lazy_instance.h" #include "base/logging.h" +#include "base/strings/string_util.h" #include "base/threading/thread_restrictions.h" #include "chrome/browser/net/proxy_service_factory.h" +#include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/guest_view/browser/guest_view_manager.h" #include "content/public/browser/download_manager.h" #include "content/public/browser/browser_thread.h" @@ -129,6 +133,9 @@ CefBrowserContextImpl::CefBrowserContextImpl( CefBrowserContextImpl::~CefBrowserContextImpl() { pref_proxy_config_tracker_->DetachFromPrefService(); + if (host_content_settings_map_.get()) + host_content_settings_map_->ShutdownOnUIThread(); + // Delete the download manager delegate here because otherwise we'll crash // when it's accessed from the content::BrowserContext destructor. if (download_manager_delegate_.get()) @@ -164,7 +171,7 @@ void CefBrowserContextImpl::Initialize() { // Initialize proxy configuration tracker. pref_proxy_config_tracker_.reset( ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState( - CefContentBrowserClient::Get()->pref_service())); + GetPrefs())); // Create the CefURLRequestContextGetterImpl via an indirect call to // CreateRequestContext. Triggers a call to CefURLRequestContextGetterImpl:: @@ -340,3 +347,37 @@ net::URLRequestContextGetter* content::URLRequestInterceptorScopedVector request_interceptors) { return NULL; } + +HostContentSettingsMap* CefBrowserContextImpl::GetHostContentSettingsMap() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (!host_content_settings_map_.get()) { + // The |incognito| argument is intentionally set to false as it otherwise + // limits the types of values that can be stored in the settings map (for + // example, default values set via DefaultProvider::SetWebsiteSetting). + host_content_settings_map_ = new HostContentSettingsMap(GetPrefs(), false); + + // Change the default plugin policy. + const base::CommandLine* command_line = + base::CommandLine::ForCurrentProcess(); + const std::string& plugin_policy_str = + command_line->GetSwitchValueASCII(switches::kPluginPolicy); + if (!plugin_policy_str.empty()) { + ContentSetting plugin_policy = CONTENT_SETTING_ALLOW; + if (base::LowerCaseEqualsASCII(plugin_policy_str, + switches::kPluginPolicy_Detect)) { + plugin_policy = CONTENT_SETTING_DETECT_IMPORTANT_CONTENT; + } else if (base::LowerCaseEqualsASCII(plugin_policy_str, + switches::kPluginPolicy_Block)) { + plugin_policy = CONTENT_SETTING_BLOCK; + } + host_content_settings_map_->SetDefaultContentSetting( + CONTENT_SETTINGS_TYPE_PLUGINS, plugin_policy); + } + } + return host_content_settings_map_.get(); +} + +PrefService* CefBrowserContextImpl::GetPrefs() { + // TODO(cef): Perhaps use per-context settings. + return CefContentBrowserClient::Get()->pref_service(); +} diff --git a/libcef/browser/browser_context_impl.h b/libcef/browser/browser_context_impl.h index b8b02eb66..324707fca 100644 --- a/libcef/browser/browser_context_impl.h +++ b/libcef/browser/browser_context_impl.h @@ -87,6 +87,8 @@ class CefBrowserContextImpl : public CefBrowserContext { content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors) override; + HostContentSettingsMap* GetHostContentSettingsMap() override; + PrefService* GetPrefs() override; // Guaranteed to exist once this object has been initialized. scoped_refptr request_context() const { @@ -115,6 +117,7 @@ class CefBrowserContextImpl : public CefBrowserContext { scoped_refptr url_request_getter_; scoped_ptr permission_manager_; scoped_ptr ssl_host_state_delegate_; + scoped_refptr host_content_settings_map_; DISALLOW_COPY_AND_ASSIGN(CefBrowserContextImpl); }; diff --git a/libcef/browser/browser_context_proxy.cc b/libcef/browser/browser_context_proxy.cc index c1772becf..09e89f66e 100644 --- a/libcef/browser/browser_context_proxy.cc +++ b/libcef/browser/browser_context_proxy.cc @@ -169,3 +169,11 @@ net::URLRequestContextGetter* content::URLRequestInterceptorScopedVector request_interceptors) { return NULL; } + +HostContentSettingsMap* CefBrowserContextProxy::GetHostContentSettingsMap() { + return parent_->GetHostContentSettingsMap(); +} + +PrefService* CefBrowserContextProxy::GetPrefs() { + return parent_->GetPrefs(); +} diff --git a/libcef/browser/browser_context_proxy.h b/libcef/browser/browser_context_proxy.h index fea07432f..af1d219d4 100644 --- a/libcef/browser/browser_context_proxy.h +++ b/libcef/browser/browser_context_proxy.h @@ -69,6 +69,8 @@ class CefBrowserContextProxy : public CefBrowserContext { content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors) override; + HostContentSettingsMap* GetHostContentSettingsMap() override; + PrefService* GetPrefs() override; scoped_refptr parent() const { return parent_; diff --git a/libcef/browser/browser_main.cc b/libcef/browser/browser_main.cc index 0e338b446..7dfac643a 100644 --- a/libcef/browser/browser_main.cc +++ b/libcef/browser/browser_main.cc @@ -24,6 +24,7 @@ #include "base/command_line.h" #include "base/message_loop/message_loop.h" #include "base/strings/string_number_conversions.h" +#include "chrome/browser/plugins/plugin_finder.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" @@ -165,6 +166,9 @@ void CefBrowserMainParts::PreMainMessageLoopRun() { } } + // Triggers initialization of the singleton instance on UI thread. + PluginFinder::GetInstance()->Init(); + #if defined(OS_WIN) PlatformPreMainMessageLoopRun(); #endif diff --git a/libcef/browser/browser_pref_store.cc b/libcef/browser/browser_pref_store.cc index 3b9b3b4e3..77c6a3fa4 100644 --- a/libcef/browser/browser_pref_store.cc +++ b/libcef/browser/browser_pref_store.cc @@ -17,6 +17,7 @@ #include "chrome/browser/prefs/command_line_pref_store.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" +#include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/proxy_config/proxy_config_dictionary.h" #include "extensions/browser/extension_prefs.h" @@ -84,13 +85,14 @@ scoped_ptr CefBrowserPrefStore::CreateService() { new CommandLinePrefStore(command_line)); factory.set_user_prefs(this); - scoped_refptr< user_prefs::PrefRegistrySyncable> registry( + scoped_refptr registry( new user_prefs::PrefRegistrySyncable()); // Default settings. CefMediaCaptureDevicesDispatcher::RegisterPrefs(registry.get()); PrefProxyConfigTrackerImpl::RegisterPrefs(registry.get()); extensions::ExtensionPrefs::RegisterProfilePrefs(registry.get()); + HostContentSettingsMap::RegisterProfilePrefs(registry.get()); // Print settings. registry->RegisterBooleanPref(prefs::kPrintingEnabled, true); @@ -122,6 +124,11 @@ scoped_ptr CefBrowserPrefStore::CreateService() { registry->RegisterBooleanPref(prefs::kEnableDRM, false); registry->RegisterStringPref(prefs::kDRMSalt, ""); + // Plugin settings. + // Based on chrome::RegisterBrowserUserPrefs. + registry->RegisterBooleanPref(prefs::kPluginsAllowOutdated, false); + registry->RegisterBooleanPref(prefs::kPluginsAlwaysAuthorize, false); + return factory.Create(registry.get()); } diff --git a/libcef/browser/content_browser_client.cc b/libcef/browser/content_browser_client.cc index 205a789e2..033579dc6 100644 --- a/libcef/browser/content_browser_client.cc +++ b/libcef/browser/content_browser_client.cc @@ -16,9 +16,9 @@ #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/plugins/plugin_info_message_filter.h" #include "libcef/browser/printing/printing_message_filter.h" #include "libcef/browser/resource_dispatcher_host_delegate.h" #include "libcef/browser/speech_recognition_manager_delegate.h" @@ -38,14 +38,14 @@ #include "base/path_service.h" #include "chrome/browser/spellchecker/spellcheck_message_filter.h" #include "chrome/common/chrome_switches.h" -#include "content/browser/plugin_service_impl.h" #include "content/public/browser/access_token_store.h" +#include "content/public/browser/browser_ppapi_host.h" #include "content/public/browser/browser_url_handler.h" #include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/client_certificate_delegate.h" -#include "content/public/browser/plugin_service_filter.h" #include "content/public/browser/quota_permission_context.h" #include "content/public/browser/render_process_host.h" +#include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/resource_dispatcher_host.h" #include "content/public/common/content_switches.h" @@ -58,6 +58,7 @@ #include "extensions/browser/io_thread_extension_message_filter.h" #include "extensions/common/constants.h" #include "net/ssl/ssl_cert_request_info.h" +#include "ppapi/host/ppapi_host.h" #include "third_party/WebKit/public/web/WebWindowFeatures.h" #include "ui/base/ui_base_switches.h" #include "url/gurl.h" @@ -265,48 +266,6 @@ class CefQuotaPermissionContext : public content::QuotaPermissionContext { DISALLOW_COPY_AND_ASSIGN(CefQuotaPermissionContext); }; -class CefPluginServiceFilter : public content::PluginServiceFilter { - public: - CefPluginServiceFilter() {} - - bool IsPluginAvailable(int render_process_id, - int render_frame_id, - const void* context, - const GURL& url, - const GURL& policy_url, - content::WebPluginInfo* plugin) override { - bool allowed = true; - - CefRefPtr browser = - CefBrowserHostImpl::GetBrowserForFrame(render_process_id, - render_frame_id); - if (browser.get()) { - CefRefPtr client = browser->GetClient(); - if (client.get()) { - CefRefPtr handler = client->GetRequestHandler(); - if (handler.get()) { - CefRefPtr pluginInfo( - new CefWebPluginInfoImpl(*plugin)); - allowed = - !handler->OnBeforePluginLoad(browser.get(), - url.possibly_invalid_spec(), - policy_url.possibly_invalid_spec(), - pluginInfo.get()); - } - } - } - - return allowed; - } - - bool CanLoadPlugin(int render_process_id, - const base::FilePath& path) override { - return true; - } - - DISALLOW_COPY_AND_ASSIGN(CefPluginServiceFilter); -}; - void TranslatePopupFeatures(const blink::WebWindowFeatures& webKitFeatures, CefPopupFeatures& features) { features.x = static_cast(webKitFeatures.x); @@ -399,10 +358,6 @@ int GetCrashSignalFD(const base::CommandLine& command_line) { CefContentBrowserClient::CefContentBrowserClient() : browser_main_parts_(NULL), next_browser_id_(0) { - plugin_service_filter_.reset(new CefPluginServiceFilter); - content::PluginServiceImpl::GetInstance()->SetFilter( - plugin_service_filter_.get()); - last_create_window_params_.opener_process_id = MSG_ROUTING_NONE; } @@ -574,9 +529,10 @@ void CefContentBrowserClient::RenderProcessWillLaunch( content::BrowserContext* browser_context = host->GetBrowserContext(); + host->AddFilter(new CefPluginInfoMessageFilter(id, + static_cast(browser_context))); + if (extensions::ExtensionsEnabled()) { - host->AddFilter( - new extensions::CefPluginInfoMessageFilter(id, browser_context)); host->AddFilter( new extensions::ExtensionMessageFilter(id, browser_context)); host->AddFilter( diff --git a/libcef/browser/content_browser_client.h b/libcef/browser/content_browser_client.h index 35dfe4a72..afe018b44 100644 --- a/libcef/browser/content_browser_client.h +++ b/libcef/browser/content_browser_client.h @@ -32,7 +32,6 @@ class CefResourceDispatcherHostDelegate; class PrefService; namespace content { -class PluginServiceFilter; class SiteInstance; } @@ -174,7 +173,6 @@ class CefContentBrowserClient : public content::ContentBrowserClient { CefBrowserMainParts* browser_main_parts_; - scoped_ptr plugin_service_filter_; scoped_ptr resource_dispatcher_host_delegate_; diff --git a/libcef/browser/context_menu_params_impl.cc b/libcef/browser/context_menu_params_impl.cc index 09dd3a052..bdca98f34 100644 --- a/libcef/browser/context_menu_params_impl.cc +++ b/libcef/browser/context_menu_params_impl.cc @@ -133,3 +133,13 @@ CefContextMenuParamsImpl::EditStateFlags CEF_VALUE_VERIFY_RETURN(false, CM_EDITFLAG_NONE); return static_cast(const_value().edit_flags); } + +bool CefContextMenuParamsImpl::IsCustomMenu() { + CEF_VALUE_VERIFY_RETURN(false, false); + return !const_value().custom_items.empty(); +} + +bool CefContextMenuParamsImpl::IsPepperMenu() { + CEF_VALUE_VERIFY_RETURN(false, false); + return const_value().custom_context.is_pepper_menu; +} diff --git a/libcef/browser/context_menu_params_impl.h b/libcef/browser/context_menu_params_impl.h index f89bef1a6..2dbeac2da 100644 --- a/libcef/browser/context_menu_params_impl.h +++ b/libcef/browser/context_menu_params_impl.h @@ -37,6 +37,8 @@ class CefContextMenuParamsImpl bool IsEditable() override; bool IsSpellCheckEnabled() override; EditStateFlags GetEditStateFlags() override; + bool IsCustomMenu() override; + bool IsPepperMenu() override; DISALLOW_COPY_AND_ASSIGN(CefContextMenuParamsImpl); }; diff --git a/libcef/browser/extensions/extensions_browser_client.cc b/libcef/browser/extensions/extensions_browser_client.cc index d41a3ab06..937dfccca 100644 --- a/libcef/browser/extensions/extensions_browser_client.cc +++ b/libcef/browser/extensions/extensions_browser_client.cc @@ -5,7 +5,7 @@ #include "libcef/browser/extensions/extensions_browser_client.h" -#include "libcef/browser/content_browser_client.h" +#include "libcef/browser/browser_context_impl.h" #include "libcef/browser/extensions/component_extension_resource_manager.h" #include "libcef/browser/extensions/extension_system_factory.h" #include "libcef/browser/extensions/extension_web_contents_observer.h" @@ -124,8 +124,7 @@ bool CefExtensionsBrowserClient::AllowCrossRendererResourceLoad( PrefService* CefExtensionsBrowserClient::GetPrefServiceForContext( BrowserContext* context) { - // TODO(extensions): Do we need a per-context PrefService? - return CefContentBrowserClient::Get()->pref_service(); + return CefBrowserContextImpl::GetForContext(context)->GetPrefs(); } void CefExtensionsBrowserClient::GetEarlyExtensionPrefsObservers( diff --git a/libcef/browser/extensions/plugin_info_message_filter.cc b/libcef/browser/extensions/plugin_info_message_filter.cc deleted file mode 100644 index 12c872e21..000000000 --- a/libcef/browser/extensions/plugin_info_message_filter.cc +++ /dev/null @@ -1,245 +0,0 @@ -// Copyright 2015 The Chromium Embedded Framework Authors. -// Portions copyright 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "libcef/browser/extensions/plugin_info_message_filter.h" - -#include "libcef/common/cef_messages.h" - -#include "base/bind.h" -#include "base/memory/scoped_ptr.h" -#include "base/strings/utf_string_conversions.h" -#include "base/thread_task_runner_handle.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/plugin_service.h" -#include "content/public/browser/plugin_service_filter.h" -#include "content/public/common/content_constants.h" -#include "content/public/common/webplugininfo.h" -#include "extensions/browser/guest_view/web_view/web_view_renderer_state.h" -#include "extensions/common/constants.h" -#include "extensions/common/extension.h" -#include "url/gurl.h" - -using content::PluginService; -using content::WebPluginInfo; - -namespace extensions { - -namespace { - -#if defined(OS_WIN) || defined(OS_MACOSX) -// These are the mime-types of plugins which are known to have PPAPI versions. -const char* kPepperPluginMimeTypes[] = { - "application/pdf", - "application/x-google-chrome-pdf", - "application/x-nacl", - "application/x-pnacl", - "application/vnd.chromium.remoting-viewer", - "application/x-shockwave-flash", - "application/futuresplash", -}; -#endif - -} // namespace - -CefPluginInfoMessageFilter::Context::Context( - int render_process_id, - content::BrowserContext* browser_context) - : render_process_id_(render_process_id), - resource_context_(browser_context->GetResourceContext()) { -} - -CefPluginInfoMessageFilter::Context::~Context() { -} - -CefPluginInfoMessageFilter::CefPluginInfoMessageFilter( - int render_process_id, - content::BrowserContext* browser_context) - : BrowserMessageFilter(ExtensionMsgStart), - context_(render_process_id, browser_context), - main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()), - weak_ptr_factory_(this) { -} - -bool CefPluginInfoMessageFilter::OnMessageReceived(const IPC::Message& message) { - IPC_BEGIN_MESSAGE_MAP(CefPluginInfoMessageFilter, message) - IPC_MESSAGE_HANDLER_DELAY_REPLY(CefViewHostMsg_GetPluginInfo, - OnGetPluginInfo) - IPC_MESSAGE_HANDLER(CefViewHostMsg_IsInternalPluginAvailableForMimeType, - OnIsInternalPluginAvailableForMimeType) - IPC_MESSAGE_UNHANDLED(return false) - IPC_END_MESSAGE_MAP() - return true; -} - -void CefPluginInfoMessageFilter::OnDestruct() const { - const_cast(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& 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 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 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 matching_plugins; - std::vector mime_types; - PluginService::GetInstance()->GetPluginInfoArray( - url, mime_type, allow_wildcard, &matching_plugins, &mime_types); - if (matching_plugins.empty()) { - *status = CefViewHostMsg_GetPluginInfo_Status::kNotFound; -#if defined(OS_WIN) || defined(OS_MACOSX) - if (!PluginService::GetInstance()->NPAPIPluginsSupported()) { - // At this point it is not known for sure this is an NPAPI plugin as it - // could be a not-yet-installed Pepper plugin. To avoid notifying on - // these types, bail early based on a blacklist of pepper mime types. - for (auto pepper_mime_type : kPepperPluginMimeTypes) - if (pepper_mime_type == mime_type) - return false; - } -#endif - return false; - } - - content::PluginServiceFilter* filter = - PluginService::GetInstance()->GetFilter(); - size_t i = 0; - for (; i < matching_plugins.size(); ++i) { - if (!filter || filter->IsPluginAvailable(render_process_id_, - render_frame_id, - resource_context_, - url, - top_origin_url, - &matching_plugins[i])) { - break; - } - } - - // If we broke out of the loop, we have found an enabled plugin. - bool enabled = i < matching_plugins.size(); - if (!enabled) { - // Otherwise, we only found disabled plugins, so we take the first one. - i = 0; - *status = CefViewHostMsg_GetPluginInfo_Status::kDisabled; - } - - *plugin = matching_plugins[i]; - *actual_mime_type = mime_types[i]; - - return enabled; -} - -void CefPluginInfoMessageFilter::OnIsInternalPluginAvailableForMimeType( - const std::string& mime_type, - bool* is_available, - std::vector* additional_param_names, - std::vector* additional_param_values) { - std::vector plugins; - PluginService::GetInstance()->GetInternalPlugins(&plugins); - - for (size_t i = 0; i < plugins.size(); ++i) { - const WebPluginInfo& plugin = plugins[i]; - const std::vector& mime_types = - plugin.mime_types; - for (size_t j = 0; j < mime_types.size(); ++j) { - if (mime_types[j].mime_type == mime_type) { - // TODO(cef): Maybe allow plugins to be disabled here. - *is_available = true; - *additional_param_names = mime_types[j].additional_param_names; - *additional_param_values = mime_types[j].additional_param_values; - return; - } - } - } - - *is_available = false; -} - -} // namespace extensions diff --git a/libcef/browser/menu_creator.cc b/libcef/browser/menu_creator.cc index 850a94d9d..6215b1141 100644 --- a/libcef/browser/menu_creator.cc +++ b/libcef/browser/menu_creator.cc @@ -5,6 +5,7 @@ #include "libcef/browser/menu_creator.h" #include "libcef/browser/browser_host_impl.h" #include "libcef/browser/context_menu_params_impl.h" +#include "libcef/browser/thread_util.h" #include "libcef/common/content_client.h" #include "base/compiler_specific.h" @@ -31,12 +32,73 @@ CefString GetLabel(int message_id) { return label; } +const int kInvalidCommandId = -1; +const cef_event_flags_t kEmptyEventFlags = static_cast(0); + +class CefRunContextMenuCallbackImpl : public CefRunContextMenuCallback { + public: + typedef base::Callback Callback; + + explicit CefRunContextMenuCallbackImpl(const Callback& callback) + : callback_(callback) { + } + + ~CefRunContextMenuCallbackImpl() { + if (!callback_.is_null()) { + // The callback is still pending. Cancel it now. + if (CEF_CURRENTLY_ON_UIT()) { + RunNow(callback_, kInvalidCommandId, kEmptyEventFlags); + } else { + CEF_POST_TASK(CEF_UIT, + base::Bind(&CefRunContextMenuCallbackImpl::RunNow, callback_, + kInvalidCommandId, kEmptyEventFlags)); + } + } + } + + void Continue(int command_id, cef_event_flags_t event_flags) override { + if (CEF_CURRENTLY_ON_UIT()) { + if (!callback_.is_null()) { + RunNow(callback_, command_id, event_flags); + callback_.Reset(); + } + } else { + CEF_POST_TASK(CEF_UIT, + base::Bind(&CefRunContextMenuCallbackImpl::Continue, this, + command_id, event_flags)); + } + } + + void Cancel() override { + Continue(kInvalidCommandId, kEmptyEventFlags); + } + + void Disconnect() { + callback_.Reset(); + } + + private: + static void RunNow(const Callback& callback, + int command_id, + cef_event_flags_t event_flags) { + CEF_REQUIRE_UIT(); + callback.Run(command_id, event_flags); + } + + Callback callback_; + + IMPLEMENT_REFCOUNTING(CefRunContextMenuCallbackImpl); + DISALLOW_COPY_AND_ASSIGN(CefRunContextMenuCallbackImpl); +}; + } // namespace CefMenuCreator::CefMenuCreator(content::WebContents* web_contents, CefBrowserHostImpl* browser) : content::WebContentsObserver(web_contents), - browser_(browser) { + browser_(browser), + custom_menu_callback_(NULL), + weak_ptr_factory_(this) { DCHECK(web_contents); DCHECK(browser_); model_ = new CefMenuModelImpl(this); @@ -77,39 +139,75 @@ bool CefMenuCreator::CreateContextMenu( // Create the default menu model. CreateDefaultModel(); + bool custom_menu = false; + DCHECK(!custom_menu_callback_); + // Give the client a chance to modify the model. CefRefPtr client = browser_->GetClient(); if (client.get()) { - CefRefPtr handler = - client->GetContextMenuHandler(); - if (handler.get()) { - CefRefPtr paramsPtr( - new CefContextMenuParamsImpl(¶ms_)); + CefRefPtr handler = + client->GetContextMenuHandler(); + if (handler.get()) { + CefRefPtr paramsPtr( + new CefContextMenuParamsImpl(¶ms_)); + CefRefPtr frame = browser_->GetFocusedFrame(); - handler->OnBeforeContextMenu(browser_, - browser_->GetFocusedFrame(), - paramsPtr.get(), - model_.get()); + handler->OnBeforeContextMenu(browser_, + frame, + paramsPtr.get(), + model_.get()); - // Do not keep references to the parameters in the callback. - paramsPtr->Detach(NULL); - DCHECK(paramsPtr->HasOneRef()); - DCHECK(model_->VerifyRefCount()); + MenuWillShow(model_); - // Menu is empty so notify the client and return. - if (model_->GetCount() == 0) { - MenuClosed(model_); - return true; + if (model_->GetCount() > 0) { + CefRefPtr callbackImpl( + new CefRunContextMenuCallbackImpl( + base::Bind(&CefMenuCreator::ExecuteCommandCallback, + weak_ptr_factory_.GetWeakPtr()))); + + // This reference will be cleared when the callback is executed or + // the callback object is deleted. + custom_menu_callback_ = callbackImpl.get(); + + if (handler->RunContextMenu(browser_, + frame, + paramsPtr.get(), + model_.get(), + callbackImpl.get())) { + custom_menu = true; + } else { + // Callback should not be executed if the handler returns false. + DCHECK(custom_menu_callback_); + custom_menu_callback_ = NULL; + callbackImpl->Disconnect(); } } + + // Do not keep references to the parameters in the callback. + paramsPtr->Detach(NULL); + DCHECK(paramsPtr->HasOneRef()); + DCHECK(model_->VerifyRefCount()); + + // Menu is empty so notify the client and return. + if (model_->GetCount() == 0 && !custom_menu) { + MenuClosed(model_); + return true; + } + } } + if (custom_menu) + return true; return runner_->RunContextMenu(this); } void CefMenuCreator::CancelContextMenu() { - if (IsShowingContextMenu()) - runner_->CancelContextMenu(); + if (IsShowingContextMenu()) { + if (custom_menu_callback_) + custom_menu_callback_->Cancel(); + else + runner_->CancelContextMenu(); + } } bool CefMenuCreator::CreateRunner() { @@ -135,26 +233,26 @@ void CefMenuCreator::ExecuteCommand(CefRefPtr source, // Give the client a chance to handle the command. CefRefPtr client = browser_->GetClient(); if (client.get()) { - CefRefPtr handler = - client->GetContextMenuHandler(); - if (handler.get()) { - CefRefPtr paramsPtr( - new CefContextMenuParamsImpl(¶ms_)); + CefRefPtr handler = + client->GetContextMenuHandler(); + if (handler.get()) { + CefRefPtr paramsPtr( + new CefContextMenuParamsImpl(¶ms_)); - bool handled = handler->OnContextMenuCommand( - browser_, - browser_->GetFocusedFrame(), - paramsPtr.get(), - command_id, - event_flags); + bool handled = handler->OnContextMenuCommand( + browser_, + browser_->GetFocusedFrame(), + paramsPtr.get(), + command_id, + event_flags); - // Do not keep references to the parameters in the callback. - paramsPtr->Detach(NULL); - DCHECK(paramsPtr->HasOneRef()); + // Do not keep references to the parameters in the callback. + paramsPtr->Detach(NULL); + DCHECK(paramsPtr->HasOneRef()); - if (handled) - return; - } + if (handled) + return; + } } // Execute the default command handling. @@ -169,6 +267,10 @@ void CefMenuCreator::MenuWillShow(CefRefPtr source) { if (!web_contents()) return; + // May be called multiple times. + if (IsShowingContextMenu()) + return; + // Notify the host before showing the context menu. content::RenderWidgetHostView* view = web_contents()->GetRenderWidgetHostView(); @@ -181,31 +283,56 @@ void CefMenuCreator::MenuClosed(CefRefPtr source) { if (source.get() != model_.get()) return; + if (!web_contents()) + return; + + DCHECK(IsShowingContextMenu()); + // Notify the client. CefRefPtr client = browser_->GetClient(); if (client.get()) { - CefRefPtr handler = - client->GetContextMenuHandler(); - if (handler.get()) { - handler->OnContextMenuDismissed(browser_, browser_->GetFocusedFrame()); - } + CefRefPtr handler = + client->GetContextMenuHandler(); + if (handler.get()) { + handler->OnContextMenuDismissed(browser_, browser_->GetFocusedFrame()); + } } - if (IsShowingContextMenu() && web_contents()) { - // Notify the host after closing the context menu. - content::RenderWidgetHostView* view = - web_contents()->GetRenderWidgetHostView(); - if (view) - view->SetShowingContextMenu(false); - web_contents()->NotifyContextMenuClosed(params_.custom_context); - } + // Notify the host after closing the context menu. + content::RenderWidgetHostView* view = + web_contents()->GetRenderWidgetHostView(); + if (view) + view->SetShowingContextMenu(false); + web_contents()->NotifyContextMenuClosed(params_.custom_context); } bool CefMenuCreator::FormatLabel(base::string16& label) { return runner_->FormatLabel(label); } +void CefMenuCreator::ExecuteCommandCallback(int command_id, + cef_event_flags_t event_flags) { + DCHECK(IsShowingContextMenu()); + DCHECK(custom_menu_callback_); + if (command_id != kInvalidCommandId) + ExecuteCommand(model_, command_id, event_flags); + MenuClosed(model_); + custom_menu_callback_ = NULL; +} + void CefMenuCreator::CreateDefaultModel() { + if (!params_.custom_items.empty()) { + // Custom menu items originating from the renderer process. For example, + // plugin placeholder menu items or Flash menu items. + for (size_t i = 0; i < params_.custom_items.size(); ++i) { + content::MenuItem menu_item = params_.custom_items[i]; + menu_item.action += MENU_ID_CUSTOM_FIRST; + DCHECK_LE(static_cast(menu_item.action), MENU_ID_CUSTOM_LAST); + model_->AddMenuItem(menu_item); + } + return; + } + if (params_.is_editable) { // Editable node. model_->AddItem(MENU_ID_UNDO, GetLabel(IDS_MENU_UNDO)); @@ -284,6 +411,14 @@ void CefMenuCreator::CreateDefaultModel() { } void CefMenuCreator::ExecuteDefaultCommand(int command_id) { + if (IsCustomContextMenuCommand(command_id)) { + if (web_contents()) { + web_contents()->ExecuteCustomContextMenuCommand( + command_id - MENU_ID_CUSTOM_FIRST, params_.custom_context); + } + return; + } + // If the user chose a replacement word for a misspelling, replace it here. if (command_id >= MENU_ID_SPELLCHECK_SUGGESTION_0 && command_id <= MENU_ID_SPELLCHECK_SUGGESTION_LAST) { @@ -358,3 +493,20 @@ void CefMenuCreator::ExecuteDefaultCommand(int command_id) { break; } } + +bool CefMenuCreator::IsCustomContextMenuCommand(int command_id) { + // Verify that the command ID is in the correct range. + if (command_id < MENU_ID_CUSTOM_FIRST || command_id > MENU_ID_CUSTOM_LAST) + return false; + + command_id -= MENU_ID_CUSTOM_FIRST; + + // Verify that the specific command ID was passed from the renderer process. + if (!params_.custom_items.empty()) { + for (size_t i = 0; i < params_.custom_items.size(); ++i) { + if (static_cast(params_.custom_items[i].action) == command_id) + return true; + } + } + return false; +} diff --git a/libcef/browser/menu_creator.h b/libcef/browser/menu_creator.h index 7cc9b861f..4caa43333 100644 --- a/libcef/browser/menu_creator.h +++ b/libcef/browser/menu_creator.h @@ -9,6 +9,7 @@ #include "libcef/browser/menu_model_impl.h" #include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/common/context_menu_params.h" @@ -17,6 +18,7 @@ class RenderFrameHost; class WebContents; }; +class CefRunContextMenuCallback; class CefBrowserHostImpl; class CefMenuCreator : public CefMenuModelImpl::Delegate, @@ -58,11 +60,17 @@ class CefMenuCreator : public CefMenuModelImpl::Delegate, void MenuClosed(CefRefPtr source) override; bool FormatLabel(base::string16& label) override; + void ExecuteCommandCallback(int command_id, + cef_event_flags_t event_flags); + // Create the default menu model. void CreateDefaultModel(); // Execute the default command handling. void ExecuteDefaultCommand(int command_id); + // Returns true if the specified id is a custom context menu command. + bool IsCustomContextMenuCommand(int command_id); + // CefBrowserHostImpl pointer is guaranteed to outlive this object. CefBrowserHostImpl* browser_; @@ -70,6 +78,12 @@ class CefMenuCreator : public CefMenuModelImpl::Delegate, content::ContextMenuParams params_; scoped_ptr runner_; + // Not owned by this class. + CefRunContextMenuCallback* custom_menu_callback_; + + // Must be the last member. + base::WeakPtrFactory weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(CefMenuCreator); }; diff --git a/libcef/browser/menu_model_impl.cc b/libcef/browser/menu_model_impl.cc index a847ffc4c..46f636caa 100644 --- a/libcef/browser/menu_model_impl.cc +++ b/libcef/browser/menu_model_impl.cc @@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/logging.h" #include "base/message_loop/message_loop.h" +#include "content/public/common/menu_item.h" #include "ui/base/accelerators/accelerator.h" namespace { @@ -661,6 +662,41 @@ bool CefMenuModelImpl::VerifyRefCount() { return true; } +void CefMenuModelImpl::AddMenuItem(const content::MenuItem& menu_item) { + const int command_id = static_cast(menu_item.action); + + switch (menu_item.type) { + case content::MenuItem::OPTION: + AddItem(command_id, menu_item.label); + break; + case content::MenuItem::CHECKABLE_OPTION: + AddCheckItem(command_id, menu_item.label); + break; + case content::MenuItem::GROUP: + AddRadioItem(command_id, menu_item.label, 0); + break; + case content::MenuItem::SEPARATOR: + AddSeparator(); + break; + case content::MenuItem::SUBMENU: { + CefRefPtr sub_menu = static_cast( + AddSubMenu(command_id, menu_item.label).get()); + for (size_t i = 0; i < menu_item.submenu.size(); ++i) + sub_menu->AddMenuItem(menu_item.submenu[i]); + break; + } + } + + if (!menu_item.enabled && menu_item.type != content::MenuItem::SEPARATOR) + SetEnabled(command_id, false); + + if (menu_item.checked && + (menu_item.type == content::MenuItem::CHECKABLE_OPTION || + menu_item.type == content::MenuItem::GROUP)) { + SetChecked(command_id, true); + } +} + void CefMenuModelImpl::AppendItem(const Item& item) { ValidateItem(item); items_.push_back(item); diff --git a/libcef/browser/menu_model_impl.h b/libcef/browser/menu_model_impl.h index 6e3996861..aa12b47c7 100644 --- a/libcef/browser/menu_model_impl.h +++ b/libcef/browser/menu_model_impl.h @@ -15,6 +15,10 @@ #include "base/threading/platform_thread.h" #include "ui/base/models/menu_model.h" +namespace content { +struct MenuItem; +} + class CefMenuModelImpl : public CefMenuModel { public: class Delegate { @@ -112,6 +116,9 @@ class CefMenuModelImpl : public CefMenuModel { // Verify that only a single reference exists to all CefMenuModelImpl objects. bool VerifyRefCount(); + // Helper for adding custom menu items originating from the renderer process. + void AddMenuItem(const content::MenuItem& menu_item); + ui::MenuModel* model() { return model_.get(); } Delegate* delegate() { return delegate_; } void set_delegate(Delegate* delegate) { delegate_ = NULL; } diff --git a/libcef/browser/plugins/plugin_info_message_filter.cc b/libcef/browser/plugins/plugin_info_message_filter.cc new file mode 100644 index 000000000..3c6370bb8 --- /dev/null +++ b/libcef/browser/plugins/plugin_info_message_filter.cc @@ -0,0 +1,615 @@ +// 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/plugins/plugin_info_message_filter.h" + +#include "libcef/browser/browser_context.h" +#include "libcef/browser/web_plugin_impl.h" +#include "libcef/common/cef_messages.h" +#include "libcef/common/content_client.h" + +#include "base/bind.h" +#include "base/memory/scoped_ptr.h" +#include "base/metrics/histogram_macros.h" +#include "base/strings/utf_string_conversions.h" +#include "base/thread_task_runner_handle.h" +#include "chrome/browser/plugins/plugin_finder.h" +#include "chrome/common/pref_names.h" +#include "components/content_settings/core/browser/content_settings_utils.h" +#include "components/content_settings/core/browser/plugins_field_trial.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/extension_registry.h" +#include "extensions/browser/guest_view/web_view/web_view_renderer_state.h" +#include "extensions/common/constants.h" +#include "extensions/common/extension.h" +#include "extensions/common/manifest_constants.h" +#include "extensions/common/manifest_handlers/webview_info.h" +#include "url/gurl.h" + +#include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. + +#if defined(OS_WIN) +#include "base/win/metro.h" +#endif + +#if !defined(DISABLE_NACL) +#include "components/nacl/common/nacl_constants.h" +#endif + +using content::PluginService; +using content::WebPluginInfo; + +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 + +// For certain sandboxed Pepper plugins, use the JavaScript Content Settings. +bool ShouldUseJavaScriptSettingForPlugin(const WebPluginInfo& plugin) { + if (plugin.type != WebPluginInfo::PLUGIN_TYPE_PEPPER_IN_PROCESS && + plugin.type != WebPluginInfo::PLUGIN_TYPE_PEPPER_OUT_OF_PROCESS) { + return false; + } + +#if !defined(DISABLE_NACL) + // Treat Native Client invocations like JavaScript. + if (plugin.name == base::ASCIIToUTF16(nacl::kNaClPluginName)) + return true; +#endif + +#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS) + // Treat CDM invocations like JavaScript. + if (plugin.name == base::ASCIIToUTF16(kWidevineCdmDisplayName)) { + DCHECK(plugin.type == WebPluginInfo::PLUGIN_TYPE_PEPPER_OUT_OF_PROCESS); + return true; + } +#endif // defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS) + + return false; +} + +#if defined(ENABLE_PEPPER_CDMS) + +enum PluginAvailabilityStatusForUMA { + PLUGIN_NOT_REGISTERED, + PLUGIN_AVAILABLE, + PLUGIN_DISABLED, + PLUGIN_AVAILABILITY_STATUS_MAX +}; + +static void SendPluginAvailabilityUMA(const std::string& mime_type, + PluginAvailabilityStatusForUMA status) { +#if defined(WIDEVINE_CDM_AVAILABLE) + // Only report results for Widevine CDM. + if (mime_type != kWidevineCdmPluginMimeType) + return; + + UMA_HISTOGRAM_ENUMERATION("Plugin.AvailabilityStatus.WidevineCdm", + status, PLUGIN_AVAILABILITY_STATUS_MAX); +#endif // defined(WIDEVINE_CDM_AVAILABLE) +} + +#endif // defined(ENABLE_PEPPER_CDMS) + +void ReportMetrics(const std::string& mime_type, + const GURL& url, + const GURL& origin_url) { +} + +#if defined(ENABLE_EXTENSIONS) +// Returns whether a request from a plugin to load |resource| from a renderer +// with process id |process_id| is a request for an internal resource by an app +// listed in |accessible_resources| in its manifest. +bool IsPluginLoadingAccessibleResourceInWebView( + extensions::ExtensionRegistry* extension_registry, + int process_id, + const GURL& resource) { + extensions::WebViewRendererState* renderer_state = + extensions::WebViewRendererState::GetInstance(); + std::string partition_id; + if (!renderer_state->IsGuest(process_id) || + !renderer_state->GetPartitionID(process_id, &partition_id)) { + return false; + } + + const std::string extension_id = resource.host(); + const extensions::Extension* extension = + extension_registry->GetExtensionById(extension_id, + extensions::ExtensionRegistry::ENABLED); + if (!extension) + return false; + const extensions::WebviewInfo* webview_info = + static_cast(extension->GetManifestData( + extensions::manifest_keys::kWebviewAccessibleResources)); + if (!webview_info || + !webview_info->IsResourceWebviewAccessible(extension, partition_id, + resource.path())) { + return false; + } + + // Make sure the renderer making the request actually belongs to the + // same extension. + std::string owner_extension; + return renderer_state->GetOwnerInfo(process_id, nullptr, &owner_extension) && + owner_extension == extension_id; +} +#endif // defined(ENABLE_EXTENSIONS) + +} // namespace + +CefPluginInfoMessageFilter::Context::Context( + int render_process_id, + CefBrowserContext* profile) + : render_process_id_(render_process_id), + resource_context_(profile->GetResourceContext()), +#if defined(ENABLE_EXTENSIONS) + extension_registry_(extensions::ExtensionRegistry::Get(profile)), +#endif + host_content_settings_map_(profile->GetHostContentSettingsMap()) { + allow_outdated_plugins_.Init(prefs::kPluginsAllowOutdated, + profile->GetPrefs()); + allow_outdated_plugins_.MoveToThread( + content::BrowserThread::GetMessageLoopProxyForThread( + content::BrowserThread::IO)); + always_authorize_plugins_.Init(prefs::kPluginsAlwaysAuthorize, + profile->GetPrefs()); + always_authorize_plugins_.MoveToThread( + content::BrowserThread::GetMessageLoopProxyForThread( + content::BrowserThread::IO)); +} + +CefPluginInfoMessageFilter::Context::~Context() { +} + +CefPluginInfoMessageFilter::CefPluginInfoMessageFilter( + int render_process_id, + CefBrowserContext* profile) + : BrowserMessageFilter(ExtensionMsgStart), + context_(render_process_id, profile), + browser_context_(profile), + 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) +#if defined(ENABLE_PEPPER_CDMS) + IPC_MESSAGE_HANDLER( + CefViewHostMsg_IsInternalPluginAvailableForMimeType, + OnIsInternalPluginAvailableForMimeType) +#endif + IPC_MESSAGE_UNHANDLED(return false) + IPC_END_MESSAGE_MAP() + return true; +} + +void CefPluginInfoMessageFilter::OnDestruct() const { + const_cast(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& plugins) { + CefViewHostMsg_GetPluginInfo_Output output; + // This also fills in |actual_mime_type|. + scoped_ptr plugin_metadata; + if (context_.FindEnabledPlugin(params.render_frame_id, params.url, + params.top_origin_url, params.mime_type, + &output.status, &output.plugin, + &output.actual_mime_type, + &plugin_metadata)) { + context_.DecidePluginStatus(params, output.plugin, plugin_metadata.get(), + &output.status); + + const bool is_found = + output.status != CefViewHostMsg_GetPluginInfo_Status::kNotFound && + output.status != CefViewHostMsg_GetPluginInfo_Status::kNPAPINotSupported; + + const bool is_internal_pdf_plugin = + is_found && + (output.plugin.path == CefString(CefContentClient::kPDFPluginPath)); + if (is_internal_pdf_plugin && + output.status != CefViewHostMsg_GetPluginInfo_Status::kAllowed) { + // Always allow the internal PDF plugin to load if it exists. + output.status = CefViewHostMsg_GetPluginInfo_Status::kAllowed; + } + + // Give the handler an opportunity to modify the policy. + CefRefPtr handler = + browser_context_->GetHandler(); + if (handler.get() && + is_found && + !is_internal_pdf_plugin) { + cef_plugin_policy_t plugin_policy = PLUGIN_POLICY_DISABLE; + switch (output.status) { + case CefViewHostMsg_GetPluginInfo_Status::kAllowed: + plugin_policy = PLUGIN_POLICY_ALLOW; + break; + case CefViewHostMsg_GetPluginInfo_Status::kBlocked: + case CefViewHostMsg_GetPluginInfo_Status::kBlockedByPolicy: + case CefViewHostMsg_GetPluginInfo_Status::kOutdatedBlocked: + case CefViewHostMsg_GetPluginInfo_Status::kOutdatedDisallowed: + case CefViewHostMsg_GetPluginInfo_Status::kUnauthorized: + plugin_policy = PLUGIN_POLICY_BLOCK; + break; + case CefViewHostMsg_GetPluginInfo_Status::kDisabled: + plugin_policy = PLUGIN_POLICY_DISABLE; + break; + case CefViewHostMsg_GetPluginInfo_Status::kPlayImportantContent: + plugin_policy = PLUGIN_POLICY_DETECT_IMPORTANT; + break; + default: + NOTREACHED(); + break; + } + + CefRefPtr pluginInfo( + new CefWebPluginInfoImpl(output.plugin)); + if (handler->OnBeforePluginLoad(output.actual_mime_type, + params.url.spec(), + params.top_origin_url.spec(), + pluginInfo.get(), + &plugin_policy)) { + switch (plugin_policy) { + case PLUGIN_POLICY_ALLOW: + output.status = CefViewHostMsg_GetPluginInfo_Status::kAllowed; + break; + case PLUGIN_POLICY_DETECT_IMPORTANT: + output.status = + CefViewHostMsg_GetPluginInfo_Status::kPlayImportantContent; + break; + case PLUGIN_POLICY_BLOCK: + output.status = CefViewHostMsg_GetPluginInfo_Status::kBlocked; + break; + case PLUGIN_POLICY_DISABLE: + output.status = CefViewHostMsg_GetPluginInfo_Status::kDisabled; + break; + } + } + } + } + + if (plugin_metadata) { + output.group_identifier = plugin_metadata->identifier(); + output.group_name = plugin_metadata->name(); + } + + CefViewHostMsg_GetPluginInfo::WriteReplyParams(reply_msg, output); + Send(reply_msg); + if (output.status != + CefViewHostMsg_GetPluginInfo_Status::kNotFound) { + main_thread_task_runner_->PostTask( + FROM_HERE, base::Bind(&ReportMetrics, output.actual_mime_type, + params.url, params.top_origin_url)); + } +} + +#if defined(ENABLE_PEPPER_CDMS) + +void CefPluginInfoMessageFilter::OnIsInternalPluginAvailableForMimeType( + const std::string& mime_type, + bool* is_available, + std::vector* additional_param_names, + std::vector* additional_param_values) { + std::vector plugins; + PluginService::GetInstance()->GetInternalPlugins(&plugins); + + bool is_plugin_disabled = false; + for (size_t i = 0; i < plugins.size(); ++i) { + const WebPluginInfo& plugin = plugins[i]; + const std::vector& mime_types = + plugin.mime_types; + for (size_t j = 0; j < mime_types.size(); ++j) { + if (mime_types[j].mime_type == mime_type) { + if (!context_.IsPluginEnabled(plugin)) { + is_plugin_disabled = true; + break; + } + + *is_available = true; + *additional_param_names = mime_types[j].additional_param_names; + *additional_param_values = mime_types[j].additional_param_values; + SendPluginAvailabilityUMA(mime_type, PLUGIN_AVAILABLE); + return; + } + } + } + + *is_available = false; + SendPluginAvailabilityUMA( + mime_type, is_plugin_disabled ? PLUGIN_DISABLED : PLUGIN_NOT_REGISTERED); +} + +#endif // defined(ENABLE_PEPPER_CDMS) + +void CefPluginInfoMessageFilter::Context::DecidePluginStatus( + const GetPluginInfo_Params& params, + const WebPluginInfo& plugin, + const PluginMetadata* plugin_metadata, + CefViewHostMsg_GetPluginInfo_Status* status) const { +#if defined(OS_WIN) + if (plugin.type == WebPluginInfo::PLUGIN_TYPE_NPAPI && + base::win::IsMetroProcess()) { + *status = CefViewHostMsg_GetPluginInfo_Status::kNPAPINotSupported; + return; + } +#endif + if (plugin.type == WebPluginInfo::PLUGIN_TYPE_NPAPI) { + CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); + // NPAPI plugins are not supported inside guests. +#if defined(ENABLE_EXTENSIONS) + if (extensions::WebViewRendererState::GetInstance()->IsGuest( + render_process_id_)) { + *status = CefViewHostMsg_GetPluginInfo_Status::kNPAPINotSupported; + return; + } +#endif + } + + ContentSetting plugin_setting = CONTENT_SETTING_DEFAULT; + bool uses_default_content_setting = true; + bool is_managed = false; + // Check plugin content settings. The primary URL is the top origin URL and + // the secondary URL is the plugin URL. + GetPluginContentSetting(plugin, params.top_origin_url, params.url, + plugin_metadata->identifier(), &plugin_setting, + &uses_default_content_setting, &is_managed); + + // TODO(tommycli): Remove once we deprecate the plugin ASK policy. + bool legacy_ask_user = plugin_setting == CONTENT_SETTING_ASK; + plugin_setting = content_settings::PluginsFieldTrial::EffectiveContentSetting( + CONTENT_SETTINGS_TYPE_PLUGINS, plugin_setting); + + DCHECK(plugin_setting != CONTENT_SETTING_DEFAULT); + DCHECK(plugin_setting != CONTENT_SETTING_ASK); + + PluginMetadata::SecurityStatus plugin_status = + plugin_metadata->GetSecurityStatus(plugin); +#if defined(ENABLE_PLUGIN_INSTALLATION) + // Check if the plugin is outdated. + if (plugin_status == PluginMetadata::SECURITY_STATUS_OUT_OF_DATE && + !allow_outdated_plugins_.GetValue()) { + if (allow_outdated_plugins_.IsManaged()) { + *status = CefViewHostMsg_GetPluginInfo_Status::kOutdatedDisallowed; + } else { + *status = CefViewHostMsg_GetPluginInfo_Status::kOutdatedBlocked; + } + return; + } +#endif + // Check if the plugin requires authorization. + if (plugin_status == + PluginMetadata::SECURITY_STATUS_REQUIRES_AUTHORIZATION && + plugin.type != WebPluginInfo::PLUGIN_TYPE_PEPPER_IN_PROCESS && + plugin.type != WebPluginInfo::PLUGIN_TYPE_PEPPER_OUT_OF_PROCESS && + plugin.type != WebPluginInfo::PLUGIN_TYPE_BROWSER_PLUGIN && + !always_authorize_plugins_.GetValue() && + plugin_setting != CONTENT_SETTING_BLOCK && + uses_default_content_setting) { + *status = CefViewHostMsg_GetPluginInfo_Status::kUnauthorized; + return; + } + + // Check if the plugin is crashing too much. + if (PluginService::GetInstance()->IsPluginUnstable(plugin.path) && + !always_authorize_plugins_.GetValue() && + plugin_setting != CONTENT_SETTING_BLOCK && + uses_default_content_setting) { + *status = CefViewHostMsg_GetPluginInfo_Status::kUnauthorized; + return; + } + +#if defined(ENABLE_EXTENSIONS) + // If an app has explicitly made internal resources available by listing them + // in |accessible_resources| in the manifest, then allow them to be loaded by + // plugins inside a guest-view. + if (params.url.SchemeIs(extensions::kExtensionScheme) && !is_managed && + plugin_setting == CONTENT_SETTING_BLOCK && + IsPluginLoadingAccessibleResourceInWebView( + extension_registry_, render_process_id_, params.url)) { + plugin_setting = CONTENT_SETTING_ALLOW; + } +#endif // defined(ENABLE_EXTENSIONS) + + if (plugin_setting == CONTENT_SETTING_DETECT_IMPORTANT_CONTENT) { + *status = CefViewHostMsg_GetPluginInfo_Status::kPlayImportantContent; + } else if (plugin_setting == CONTENT_SETTING_BLOCK) { + // For managed users with the ASK policy, we allow manually running plugins + // via context menu. This is the closest to admin intent. + *status = is_managed && !legacy_ask_user + ? CefViewHostMsg_GetPluginInfo_Status::kBlockedByPolicy + : CefViewHostMsg_GetPluginInfo_Status::kBlocked; + } + + if (*status == CefViewHostMsg_GetPluginInfo_Status::kAllowed) { + // Allow an embedder of 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 defined(ENABLE_EXTENSIONS) + if (extensions::WebViewRendererState::GetInstance()->IsGuest( + render_process_id_)) { + *status = CefViewHostMsg_GetPluginInfo_Status::kUnauthorized; + } +#endif + } +} + +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, + scoped_ptr* plugin_metadata) const { + *status = CefViewHostMsg_GetPluginInfo_Status::kAllowed; + + bool allow_wildcard = true; + std::vector matching_plugins; + std::vector 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]; + if (plugin_metadata) + *plugin_metadata = PluginFinder::GetInstance()->GetPluginMetadata(*plugin); + + return enabled; +} + +void CefPluginInfoMessageFilter::Context::GetPluginContentSetting( + const WebPluginInfo& plugin, + const GURL& policy_url, + const GURL& plugin_url, + const std::string& resource, + ContentSetting* setting, + bool* uses_default_content_setting, + bool* is_managed) const { + scoped_ptr value; + content_settings::SettingInfo info; + bool uses_plugin_specific_setting = false; + if (ShouldUseJavaScriptSettingForPlugin(plugin)) { + value = host_content_settings_map_->GetWebsiteSetting( + policy_url, + policy_url, + CONTENT_SETTINGS_TYPE_JAVASCRIPT, + std::string(), + &info); + } else { + content_settings::SettingInfo specific_info; + scoped_ptr specific_setting = + host_content_settings_map_->GetWebsiteSetting( + policy_url, + plugin_url, + CONTENT_SETTINGS_TYPE_PLUGINS, + resource, + &specific_info); + content_settings::SettingInfo general_info; + scoped_ptr general_setting = + host_content_settings_map_->GetWebsiteSetting( + policy_url, + plugin_url, + CONTENT_SETTINGS_TYPE_PLUGINS, + std::string(), + &general_info); + + // If there is a plugin-specific setting, we use it, unless the general + // setting was set by policy, in which case it takes precedence. + // TODO(tommycli): Remove once we deprecate the plugin ASK policy. + bool legacy_ask_user = content_settings::ValueToContentSetting( + general_setting.get()) == CONTENT_SETTING_ASK; + bool use_policy = + general_info.source == content_settings::SETTING_SOURCE_POLICY && + !legacy_ask_user; + uses_plugin_specific_setting = specific_setting && !use_policy; + if (uses_plugin_specific_setting) { + value = specific_setting.Pass(); + info = specific_info; + } else { + value = general_setting.Pass(); + info = general_info; + } + } + *setting = content_settings::ValueToContentSetting(value.get()); + *uses_default_content_setting = + !uses_plugin_specific_setting && + info.primary_pattern == ContentSettingsPattern::Wildcard() && + info.secondary_pattern == ContentSettingsPattern::Wildcard(); + *is_managed = info.source == content_settings::SETTING_SOURCE_POLICY; +} + +bool CefPluginInfoMessageFilter::Context::IsPluginEnabled( + const content::WebPluginInfo& plugin) const { + return true; +} diff --git a/libcef/browser/extensions/plugin_info_message_filter.h b/libcef/browser/plugins/plugin_info_message_filter.h similarity index 58% rename from libcef/browser/extensions/plugin_info_message_filter.h rename to libcef/browser/plugins/plugin_info_message_filter.h index a67c278a9..433dc6123 100644 --- a/libcef/browser/extensions/plugin_info_message_filter.h +++ b/libcef/browser/plugins/plugin_info_message_filter.h @@ -3,8 +3,8 @@ // 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_ +#ifndef CEF_LIBCEF_BROWSER_PLUGINS_PLUGIN_INFO_MESSAGE_FILTER_H_ +#define CEF_LIBCEF_BROWSER_PLUGINS_PLUGIN_INFO_MESSAGE_FILTER_H_ #include #include @@ -14,19 +14,24 @@ #include "base/memory/weak_ptr.h" #include "base/prefs/pref_member.h" #include "base/sequenced_task_runner_helpers.h" +#include "chrome/browser/plugins/plugin_metadata.h" +#include "components/content_settings/core/browser/host_content_settings_map.h" +#include "components/content_settings/core/common/content_settings.h" #include "content/public/browser/browser_message_filter.h" +class CefBrowserContext; struct CefViewHostMsg_GetPluginInfo_Output; enum class CefViewHostMsg_GetPluginInfo_Status; class GURL; namespace content { -class BrowserContext; class ResourceContext; struct WebPluginInfo; } namespace extensions { +class ExtensionRegistry; +} // This class filters out incoming IPC messages requesting plugin information. class CefPluginInfoMessageFilter : public content::BrowserMessageFilter { @@ -36,13 +41,14 @@ class CefPluginInfoMessageFilter : public content::BrowserMessageFilter { // Contains all the information needed by the CefPluginInfoMessageFilter. class Context { public: - Context(int render_process_id, content::BrowserContext* browser_context); + Context(int render_process_id, CefBrowserContext* profile); ~Context(); void DecidePluginStatus( const GetPluginInfo_Params& params, const content::WebPluginInfo& plugin, + const PluginMetadata* plugin_metadata, CefViewHostMsg_GetPluginInfo_Status* status) const; bool FindEnabledPlugin(int render_frame_id, const GURL& url, @@ -50,15 +56,33 @@ class CefPluginInfoMessageFilter : public content::BrowserMessageFilter { const std::string& mime_type, CefViewHostMsg_GetPluginInfo_Status* status, content::WebPluginInfo* plugin, - std::string* actual_mime_type) const; + std::string* actual_mime_type, + scoped_ptr* plugin_metadata) const; + void GetPluginContentSetting(const content::WebPluginInfo& plugin, + const GURL& policy_url, + const GURL& plugin_url, + const std::string& resource, + ContentSetting* setting, + bool* is_default, + bool* is_managed) const; + void MaybeGrantAccess(CefViewHostMsg_GetPluginInfo_Status status, + const base::FilePath& path) const; + bool IsPluginEnabled(const content::WebPluginInfo& plugin) const; private: int render_process_id_; content::ResourceContext* resource_context_; +#if defined(ENABLE_EXTENSIONS) + extensions::ExtensionRegistry* extension_registry_; +#endif + const HostContentSettingsMap* host_content_settings_map_; + + BooleanPrefMember allow_outdated_plugins_; + BooleanPrefMember always_authorize_plugins_; }; CefPluginInfoMessageFilter(int render_process_id, - content::BrowserContext* browser_context); + CefBrowserContext* profile); // content::BrowserMessageFilter methods: bool OnMessageReceived(const IPC::Message& message) override; @@ -76,11 +100,6 @@ class CefPluginInfoMessageFilter : public content::BrowserMessageFilter { const GURL& top_origin_url, const std::string& mime_type, IPC::Message* reply_msg); - void OnIsInternalPluginAvailableForMimeType( - const std::string& mime_type, - bool* is_available, - std::vector* additional_param_names, - std::vector* additional_param_values); // |params| wraps the parameters passed to |OnGetPluginInfo|, because // |base::Bind| doesn't support the required arity . @@ -88,7 +107,23 @@ class CefPluginInfoMessageFilter : public content::BrowserMessageFilter { IPC::Message* reply_msg, const std::vector& plugins); +#if defined(ENABLE_PEPPER_CDMS) + // Returns whether any internal plugin supporting |mime_type| is registered + // and enabled. Does not determine whether the plugin can actually be + // instantiated (e.g. whether it has all its dependencies). + // When the returned *|is_available| is true, |additional_param_names| and + // |additional_param_values| contain the name-value pairs, if any, specified + // for the *first* non-disabled plugin found that is registered for + // |mime_type|. + void OnIsInternalPluginAvailableForMimeType( + const std::string& mime_type, + bool* is_available, + std::vector* additional_param_names, + std::vector* additional_param_values); +#endif + Context context_; + CefBrowserContext* browser_context_; scoped_refptr main_thread_task_runner_; base::WeakPtrFactory weak_ptr_factory_; @@ -96,6 +131,4 @@ class CefPluginInfoMessageFilter : public content::BrowserMessageFilter { DISALLOW_COPY_AND_ASSIGN(CefPluginInfoMessageFilter); }; -} // namespace extensions - -#endif // CEF_LIBCEF_BROWSER_EXTENSIONS_PLUGIN_INFO_MESSAGE_FILTER_H_ +#endif // CEF_LIBCEF_BROWSER_PLUGINS_PLUGIN_INFO_MESSAGE_FILTER_H_ diff --git a/libcef/common/cef_messages.h b/libcef/common/cef_messages.h index b88173708..e867c5d75 100644 --- a/libcef/common/cef_messages.h +++ b/libcef/common/cef_messages.h @@ -163,6 +163,11 @@ IPC_MESSAGE_ROUTED1(CefMsg_Response, IPC_MESSAGE_ROUTED1(CefMsg_ResponseAck, int /* request_id */) +// Tells the render frame to load all blocked plugins with the given identifier. +// Based on ChromeViewMsg_LoadBlockedPlugins. +IPC_MESSAGE_ROUTED1(CefViewMsg_LoadBlockedPlugins, + std::string /* identifier */) + // Sent on process startup to indicate whether this process is running in // incognito mode. Based on ChromeViewMsg_SetIsIncognitoProcess. IPC_MESSAGE_CONTROL1(CefProcessMsg_SetIsIncognitoProcess, diff --git a/libcef/common/cef_switches.cc b/libcef/common/cef_switches.cc index c20841f2a..8031ba8e9 100644 --- a/libcef/common/cef_switches.cc +++ b/libcef/common/cef_switches.cc @@ -116,4 +116,14 @@ const char kWidevineCdmPath[] = "widevine-cdm-path"; // Widevine CDM version. const char kWidevineCdmVersion[] = "widevine-cdm-version"; +// Default plugin policy action. +const char kPluginPolicy[] = "plugin-policy"; +// Allow the content. This is the default value. +const char kPluginPolicy_Allow[] = "allow"; +// Allow important content and block unimportant content based on heuristics. +// The user can manually load blocked content. +const char kPluginPolicy_Detect[] = "detect"; +// Block the content. The user can manually load blocked content. +const char kPluginPolicy_Block[] = "block"; + } // namespace switches diff --git a/libcef/common/cef_switches.h b/libcef/common/cef_switches.h index 0281167aa..e691dd2ce 100644 --- a/libcef/common/cef_switches.h +++ b/libcef/common/cef_switches.h @@ -48,6 +48,10 @@ extern const char kEnableNPAPI[]; extern const char kEnableWidevineCdm[]; extern const char kWidevineCdmPath[]; extern const char kWidevineCdmVersion[]; +extern const char kPluginPolicy[]; +extern const char kPluginPolicy_Allow[]; +extern const char kPluginPolicy_Detect[]; +extern const char kPluginPolicy_Block[]; } // namespace switches diff --git a/libcef/common/content_client.cc b/libcef/common/content_client.cc index 798ddf1c3..fd0faac90 100644 --- a/libcef/common/content_client.cc +++ b/libcef/common/content_client.cc @@ -433,8 +433,15 @@ bool CefContentClient::GetRawDataResource(int resource_id, if (handler.get()) { void* data = NULL; size_t data_size = 0; - if (handler->GetDataResource(resource_id, data, data_size)) + if (scale_factor != ui::SCALE_FACTOR_NONE) { + if (handler->GetDataResourceForScale( + resource_id, static_cast(scale_factor), data, + data_size)) { + *value = base::StringPiece(static_cast(data), data_size); + } + } else if (handler->GetDataResource(resource_id, data, data_size)) { *value = base::StringPiece(static_cast(data), data_size); + } } } diff --git a/libcef/common/main_delegate.cc b/libcef/common/main_delegate.cc index 19c2c9083..7a9e372d0 100644 --- a/libcef/common/main_delegate.cc +++ b/libcef/common/main_delegate.cc @@ -27,10 +27,12 @@ #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/widevine_cdm_constants.h" +#include "components/content_settings/core/common/content_settings_pattern.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 "extensions/common/constants.h" #include "pdf/pdf.h" #include "ui/base/layout.h" #include "ui/base/resource/resource_bundle.h" @@ -483,6 +485,9 @@ bool CefMainDelegate::BasicStartupComplete(int* exit_code) { logging::InitLogging(log_settings); + ContentSettingsPattern::SetNonWildcardDomainNonPortScheme( + extensions::kExtensionScheme); + content::SetContentClient(&content_client_); return false; diff --git a/libcef/common/parser_impl.cc b/libcef/common/parser_impl.cc index 473b4b400..a2fdc360a 100644 --- a/libcef/common/parser_impl.cc +++ b/libcef/common/parser_impl.cc @@ -8,6 +8,7 @@ #include "libcef/renderer/webkit_glue.h" #include "base/base64.h" +#include "base/threading/thread_restrictions.h" #include "net/base/escape.h" #include "net/base/mime_util.h" #include "third_party/WebKit/public/platform/WebString.h" @@ -76,6 +77,10 @@ bool CefCreateURL(const CefURLParts& parts, } CefString CefGetMimeType(const CefString& extension) { + // Requests should not block on the disk! On POSIX this goes to disk. + // http://code.google.com/p/chromium/issues/detail?id=59849 + base::ThreadRestrictions::ScopedAllowIO allow_io; + std::string mime_type; net::GetMimeTypeFromExtension(extension, &mime_type); return mime_type; diff --git a/libcef/common/resource_bundle_impl.cc b/libcef/common/resource_bundle_impl.cc new file mode 100644 index 000000000..53e51524d --- /dev/null +++ b/libcef/common/resource_bundle_impl.cc @@ -0,0 +1,47 @@ +// 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/common/resource_bundle_impl.h" + +#include "ui/base/resource/resource_bundle.h" + +CefResourceBundleImpl::CefResourceBundleImpl() { +} + +CefString CefResourceBundleImpl::GetLocalizedString(int string_id) { + if (!ui::ResourceBundle::HasSharedInstance()) + return CefString(); + + return ui::ResourceBundle::GetSharedInstance().GetLocalizedString(string_id); +} + +bool CefResourceBundleImpl::GetDataResource(int resource_id, + void*& data, + size_t& data_size) { + return GetDataResourceForScale(resource_id, SCALE_FACTOR_NONE, data, + data_size); +} + +bool CefResourceBundleImpl::GetDataResourceForScale(int resource_id, + ScaleFactor scale_factor, + void*& data, + size_t& data_size) { + if (!ui::ResourceBundle::HasSharedInstance()) + return false; + + const base::StringPiece& result = + ui::ResourceBundle::GetSharedInstance().GetRawDataResourceForScale( + resource_id, static_cast(scale_factor)); + if (result.empty()) + return false; + + data = const_cast(result.data()); + data_size = result.size(); + return true; +} + +// static +CefRefPtr CefResourceBundle::GetGlobal() { + return new CefResourceBundleImpl(); +} diff --git a/libcef/common/resource_bundle_impl.h b/libcef/common/resource_bundle_impl.h new file mode 100644 index 000000000..eceee7c1d --- /dev/null +++ b/libcef/common/resource_bundle_impl.h @@ -0,0 +1,31 @@ +// 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_COMMON_RESOURCE_BUNDLE_IMPL_H_ +#define CEF_LIBCEF_COMMON_RESOURCE_BUNDLE_IMPL_H_ +#pragma once + + +#include "include/cef_resource_bundle.h" + +class CefResourceBundleImpl : public CefResourceBundle { + public: + CefResourceBundleImpl(); + + // CefResourceBundle methods. + CefString GetLocalizedString(int string_id) override; + bool GetDataResource(int resource_id, + void*& data, + size_t& data_size) override; + bool GetDataResourceForScale(int resource_id, + ScaleFactor scale_factor, + void*& data, + size_t& data_size) override; + + private: + IMPLEMENT_REFCOUNTING(CefResourceBundleImpl); + DISALLOW_COPY_AND_ASSIGN(CefResourceBundleImpl); +}; + +#endif // CEF_LIBCEF_COMMON_RESOURCE_BUNDLE_IMPL_H_ diff --git a/libcef/renderer/content_renderer_client.cc b/libcef/renderer/content_renderer_client.cc index c97b2a52a..c92ffd302 100644 --- a/libcef/renderer/content_renderer_client.cc +++ b/libcef/renderer/content_renderer_client.cc @@ -19,6 +19,8 @@ #include "libcef/renderer/extensions/print_web_view_helper_delegate.h" #include "libcef/renderer/media/cef_key_systems.h" #include "libcef/renderer/pepper/pepper_helper.h" +#include "libcef/renderer/plugins/cef_plugin_placeholder.h" +#include "libcef/renderer/plugins/plugin_preroller.h" #include "libcef/renderer/render_frame_observer.h" #include "libcef/renderer/render_message_filter.h" #include "libcef/renderer/render_process_observer.h" @@ -27,15 +29,20 @@ #include "libcef/renderer/webkit_glue.h" #include "base/command_line.h" +#include "base/metrics/user_metrics_action.h" #include "base/path_service.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" +#include "chrome/common/chrome_switches.h" #include "chrome/common/pepper_permission_util.h" +#include "chrome/grit/generated_resources.h" +#include "chrome/renderer/content_settings_observer.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/nacl/common/nacl_constants.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" @@ -62,6 +69,7 @@ #include "third_party/WebKit/public/platform/WebPrerenderingSupport.h" #include "third_party/WebKit/public/platform/WebString.h" #include "third_party/WebKit/public/platform/WebURL.h" +#include "third_party/WebKit/public/web/WebConsoleMessage.h" #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebElement.h" #include "third_party/WebKit/public/web/WebFrame.h" @@ -71,6 +79,7 @@ #include "third_party/WebKit/public/web/WebRuntimeFeatures.h" #include "third_party/WebKit/public/web/WebSecurityPolicy.h" #include "third_party/WebKit/public/web/WebView.h" +#include "ui/base/l10n/l10n_util.h" #if defined(OS_MACOSX) #include "base/mac/mac_util.h" @@ -186,6 +195,19 @@ void AppendParams(const std::vector& additional_names, existing_values->swap(values); } +std::string GetPluginInstancePosterAttribute( + const blink::WebPluginParams& params) { + DCHECK_EQ(params.attributeNames.size(), params.attributeValues.size()); + + for (size_t i = 0; i < params.attributeNames.size(); ++i) { + if (params.attributeNames[i].utf8() == "poster" && + !params.attributeValues[i].isEmpty()) { + return params.attributeValues[i].utf8(); + } + } + return std::string(); +} + } // namespace CefContentRendererClient::CefContentRendererClient() @@ -660,6 +682,7 @@ void CefContentRendererClient::WillDestroyCurrentMessageLoop() { single_process_cleanup_complete_ = true; } +// static bool CefContentRendererClient::IsExtensionOrSharedModuleWhitelisted( const GURL& url, const std::set& whitelist) { DCHECK(extensions::ExtensionsEnabled()); @@ -669,6 +692,167 @@ bool CefContentRendererClient::IsExtensionOrSharedModuleWhitelisted( whitelist); } +// static +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; + const base::string16& group_name = output.group_name; + const std::string& identifier = output.group_identifier; + CefViewHostMsg_GetPluginInfo_Status status = output.status; + GURL url(original_params.url); + std::string orig_mime_type = original_params.mimeType.utf8(); + CefPluginPlaceholder* placeholder = NULL; + + // 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) { + placeholder = CefPluginPlaceholder::CreateLoadableMissingPlugin( + render_frame, frame, original_params); + } 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()); + } + + auto create_blocked_plugin = + [&render_frame, &frame, ¶ms, &info, &identifier, &group_name]( + int template_id, const base::string16& message) { + return CefPluginPlaceholder::CreateBlockedPlugin( + render_frame, frame, params, info, identifier, group_name, + template_id, message, PlaceholderPosterInfo()); + }; + switch (status) { + case CefViewHostMsg_GetPluginInfo_Status::kNotFound: { + NOTREACHED(); + break; + } + case CefViewHostMsg_GetPluginInfo_Status::kAllowed: + case CefViewHostMsg_GetPluginInfo_Status::kPlayImportantContent: { + // Delay loading plugins if prerendering. + // TODO(mmenke): In the case of prerendering, feed into + // CefContentRendererClient::CreatePlugin instead, to + // reduce the chance of future regressions. + bool is_prerendering = false; + bool power_saver_enabled = + status == + CefViewHostMsg_GetPluginInfo_Status::kPlayImportantContent; + bool blocked_for_background_tab = + render_frame->IsHidden() && power_saver_enabled; + + PlaceholderPosterInfo poster_info; + if (power_saver_enabled) { + poster_info.poster_attribute = + GetPluginInstancePosterAttribute(params); + poster_info.base_url = frame->document().url(); + } + + if (blocked_for_background_tab || is_prerendering || + !poster_info.poster_attribute.empty()) { + placeholder = CefPluginPlaceholder::CreateBlockedPlugin( + render_frame, frame, params, info, identifier, group_name, + poster_info.poster_attribute.empty() ? IDR_BLOCKED_PLUGIN_HTML + : IDR_PLUGIN_POSTER_HTML, + l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED, group_name), + poster_info); + placeholder->set_blocked_for_background_tab( + blocked_for_background_tab); + placeholder->set_blocked_for_prerendering(is_prerendering); + placeholder->set_power_saver_enabled(power_saver_enabled); + placeholder->AllowLoading(); + break; + } + + scoped_ptr throttler; + if (power_saver_enabled) { + throttler = content::PluginInstanceThrottler::Create(); + // PluginPreroller manages its own lifetime. + new CefPluginPreroller( + render_frame, frame, params, info, identifier, group_name, + l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED, group_name), + throttler.get()); + } + + return render_frame->CreatePlugin(frame, info, params, + throttler.Pass()); + } + case CefViewHostMsg_GetPluginInfo_Status::kNPAPINotSupported: { + content::RenderThread::Get()->RecordAction( + base::UserMetricsAction("Plugin_NPAPINotSupported")); + placeholder = create_blocked_plugin( + IDR_BLOCKED_PLUGIN_HTML, + l10n_util::GetStringUTF16(IDS_PLUGIN_NOT_SUPPORTED_METRO)); + break; + } + case CefViewHostMsg_GetPluginInfo_Status::kDisabled: { + // Intentionally using the blocked plugin resources instead of the + // disabled plugin resources. This provides better messaging (no link to + // chrome://plugins) and adds testing support. + placeholder = create_blocked_plugin( + IDR_BLOCKED_PLUGIN_HTML, + l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED_BY_POLICY, + group_name)); + break; + } + case CefViewHostMsg_GetPluginInfo_Status::kOutdatedBlocked: { + NOTREACHED() << "Plugin installation is not supported."; + break; + } + case CefViewHostMsg_GetPluginInfo_Status::kOutdatedDisallowed: { + placeholder = create_blocked_plugin( + IDR_BLOCKED_PLUGIN_HTML, + l10n_util::GetStringFUTF16(IDS_PLUGIN_OUTDATED, group_name)); + break; + } + case CefViewHostMsg_GetPluginInfo_Status::kUnauthorized: { + placeholder = create_blocked_plugin( + IDR_BLOCKED_PLUGIN_HTML, + l10n_util::GetStringFUTF16(IDS_PLUGIN_NOT_AUTHORIZED, group_name)); + placeholder->AllowLoading(); + break; + } + case CefViewHostMsg_GetPluginInfo_Status::kBlocked: { + placeholder = create_blocked_plugin( + IDR_BLOCKED_PLUGIN_HTML, + l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED, group_name)); + placeholder->AllowLoading(); + content::RenderThread::Get()->RecordAction( + base::UserMetricsAction("Plugin_Blocked")); + break; + } + case CefViewHostMsg_GetPluginInfo_Status::kBlockedByPolicy: { + placeholder = create_blocked_plugin( + IDR_BLOCKED_PLUGIN_HTML, + l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED_BY_POLICY, + group_name)); + content::RenderThread::Get()->RecordAction( + base::UserMetricsAction("Plugin_BlockedByPolicy")); + break; + } + } + } + placeholder->SetStatus(status); + return placeholder->plugin(); +} + void CefContentRendererClient::BrowserCreated( content::RenderView* render_view, content::RenderFrame* render_frame) { @@ -743,57 +927,3 @@ 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; -} diff --git a/libcef/renderer/content_renderer_client.h b/libcef/renderer/content_renderer_client.h index 40a81762e..e510fc68e 100644 --- a/libcef/renderer/content_renderer_client.h +++ b/libcef/renderer/content_renderer_client.h @@ -116,6 +116,12 @@ class CefContentRendererClient : public content::ContentRendererClient, static bool IsExtensionOrSharedModuleWhitelisted( const GURL& url, const std::set& whitelist); + static blink::WebPlugin* CreatePlugin( + content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params, + const CefViewHostMsg_GetPluginInfo_Output& output); + private: void BrowserCreated(content::RenderView* render_view, content::RenderFrame* render_frame); @@ -123,12 +129,6 @@ 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 render_task_runner_; scoped_ptr observer_; scoped_ptr web_cache_observer_; diff --git a/libcef/renderer/plugins/cef_plugin_placeholder.cc b/libcef/renderer/plugins/cef_plugin_placeholder.cc new file mode 100644 index 000000000..14f79e0f4 --- /dev/null +++ b/libcef/renderer/plugins/cef_plugin_placeholder.cc @@ -0,0 +1,285 @@ +// Copyright 2013 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/plugins/cef_plugin_placeholder.h" + +#include "libcef/common/cef_messages.h" +#include "libcef/renderer/content_renderer_client.h" +#include "libcef/renderer/plugins/plugin_preroller.h" + +#include "base/strings/string_number_conversions.h" +#include "base/strings/utf_string_conversions.h" +#include "base/values.h" +#include "chrome/grit/generated_resources.h" +#include "chrome/renderer/custom_menu_commands.h" +#include "components/content_settings/content/common/content_settings_messages.h" +#include "content/public/common/context_menu_params.h" +#include "content/public/renderer/render_frame.h" +#include "content/public/renderer/render_thread.h" +#include "gin/object_template_builder.h" +#include "third_party/WebKit/public/web/WebDocument.h" +#include "third_party/WebKit/public/web/WebInputEvent.h" +#include "third_party/WebKit/public/web/WebLocalFrame.h" +#include "third_party/WebKit/public/web/WebScriptSource.h" +#include "third_party/WebKit/public/web/WebView.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/base/webui/jstemplate_builder.h" +#include "ui/gfx/geometry/size.h" +#include "url/url_util.h" + +using base::UserMetricsAction; +using content::RenderThread; +using content::RenderView; + +namespace { +const CefPluginPlaceholder* g_last_active_menu = NULL; +} // namespace + +gin::WrapperInfo CefPluginPlaceholder::kWrapperInfo = { + gin::kEmbedderNativeGin}; + +CefPluginPlaceholder::CefPluginPlaceholder( + content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params, + const std::string& html_data, + const base::string16& title) + : plugins::LoadablePluginPlaceholder(render_frame, + frame, + params, + html_data), + status_(CefViewHostMsg_GetPluginInfo_Status::kAllowed), + title_(title), + has_host_(false), + context_menu_request_id_(0) { + RenderThread::Get()->AddObserver(this); +} + +CefPluginPlaceholder::~CefPluginPlaceholder() { + RenderThread::Get()->RemoveObserver(this); + if (context_menu_request_id_ && render_frame()) + render_frame()->CancelContextMenu(context_menu_request_id_); +} + +// static +CefPluginPlaceholder* CefPluginPlaceholder::CreateLoadableMissingPlugin( + content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params) { + const base::StringPiece template_html( + ResourceBundle::GetSharedInstance().GetRawDataResource( + IDR_BLOCKED_PLUGIN_HTML)); + + base::DictionaryValue values; + values.SetString("message", + l10n_util::GetStringUTF8(IDS_PLUGIN_NOT_SUPPORTED)); + + std::string html_data = webui::GetI18nTemplateHtml(template_html, &values); + + // Will destroy itself when its WebViewPlugin is going away. + return new CefPluginPlaceholder(render_frame, frame, params, html_data, + params.mimeType); +} + +// static +CefPluginPlaceholder* CefPluginPlaceholder::CreateBlockedPlugin( + content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params, + const content::WebPluginInfo& info, + const std::string& identifier, + const base::string16& name, + int template_id, + const base::string16& message, + const PlaceholderPosterInfo& poster_info) { + base::DictionaryValue values; + values.SetString("message", message); + values.SetString("name", name); + values.SetString("hide", l10n_util::GetStringUTF8(IDS_PLUGIN_HIDE)); + values.SetString("pluginType", + frame->view()->mainFrame()->document().isPluginDocument() + ? "document" + : "embedded"); + + if (!poster_info.poster_attribute.empty()) { + values.SetString("poster", poster_info.poster_attribute); + values.SetString("baseurl", poster_info.base_url.spec()); + + if (!poster_info.custom_poster_size.IsEmpty()) { + float zoom_factor = + blink::WebView::zoomLevelToZoomFactor(frame->view()->zoomLevel()); + int width = roundf(poster_info.custom_poster_size.width() / zoom_factor); + int height = + roundf(poster_info.custom_poster_size.height() / zoom_factor); + values.SetString("visibleWidth", base::IntToString(width) + "px"); + values.SetString("visibleHeight", base::IntToString(height) + "px"); + } + } + + const base::StringPiece template_html( + ResourceBundle::GetSharedInstance().GetRawDataResource(template_id)); + + DCHECK(!template_html.empty()) << "unable to load template. ID: " + << template_id; + std::string html_data = webui::GetI18nTemplateHtml(template_html, &values); + + // |blocked_plugin| will destroy itself when its WebViewPlugin is going away. + CefPluginPlaceholder* blocked_plugin = new CefPluginPlaceholder( + render_frame, frame, params, html_data, name); + + if (!poster_info.poster_attribute.empty()) + blocked_plugin->BlockForPowerSaverPoster(); + blocked_plugin->SetPluginInfo(info); + blocked_plugin->SetIdentifier(identifier); + return blocked_plugin; +} + +void CefPluginPlaceholder::SetStatus( + CefViewHostMsg_GetPluginInfo_Status status) { + status_ = status; +} + +bool CefPluginPlaceholder::OnMessageReceived(const IPC::Message& message) { + // We don't swallow these messages because multiple blocked plugins and other + // objects have an interest in them. + IPC_BEGIN_MESSAGE_MAP(CefPluginPlaceholder, message) + IPC_MESSAGE_HANDLER(CefViewMsg_LoadBlockedPlugins, OnLoadBlockedPlugins) + IPC_END_MESSAGE_MAP() + + return false; +} + +void CefPluginPlaceholder::OpenAboutPluginsCallback() { + // CEF does not use IDR_DISABLED_PLUGIN_HTML which would originate this + // callback for the chrome://plugins link. + NOTREACHED(); +} + +void CefPluginPlaceholder::PluginListChanged() { + if (!GetFrame() || !plugin()) + return; + blink::WebDocument document = GetFrame()->top()->document(); + if (document.isNull()) + return; + + CefViewHostMsg_GetPluginInfo_Output output; + std::string mime_type(GetPluginParams().mimeType.utf8()); + blink::WebString top_origin = GetFrame()->top()->securityOrigin().toString(); + render_frame()->Send( + new CefViewHostMsg_GetPluginInfo(routing_id(), + GURL(GetPluginParams().url), + GURL(top_origin), + mime_type, + &output)); + if (output.status == status_) + return; + blink::WebPlugin* new_plugin = CefContentRendererClient::CreatePlugin( + render_frame(), GetFrame(), GetPluginParams(), output); + ReplacePlugin(new_plugin); +} + +void CefPluginPlaceholder::OnMenuAction(int request_id, unsigned action) { + DCHECK_EQ(context_menu_request_id_, request_id); + if (g_last_active_menu != this) + return; + switch (action) { + case chrome::MENU_COMMAND_PLUGIN_RUN: { + RenderThread::Get()->RecordAction(UserMetricsAction("Plugin_Load_Menu")); + MarkPluginEssential( + content::PluginInstanceThrottler::UNTHROTTLE_METHOD_BY_CLICK); + LoadPlugin(); + break; + } + case chrome::MENU_COMMAND_PLUGIN_HIDE: { + RenderThread::Get()->RecordAction(UserMetricsAction("Plugin_Hide_Menu")); + HidePlugin(); + break; + } + default: + NOTREACHED(); + } +} + +void CefPluginPlaceholder::OnMenuClosed(int request_id) { + DCHECK_EQ(context_menu_request_id_, request_id); + context_menu_request_id_ = 0; +} + +v8::Local CefPluginPlaceholder::GetV8Handle( + v8::Isolate* isolate) { + return gin::CreateHandle(isolate, this).ToV8(); +} + +void CefPluginPlaceholder::ShowContextMenu( + const blink::WebMouseEvent& event) { + if (context_menu_request_id_) + return; // Don't allow nested context menu requests. + + content::ContextMenuParams params; + + if (!title_.empty()) { + content::MenuItem name_item; + name_item.label = title_; + params.custom_items.push_back(name_item); + + content::MenuItem separator_item; + separator_item.type = content::MenuItem::SEPARATOR; + params.custom_items.push_back(separator_item); + } + + if (!GetPluginInfo().path.value().empty()) { + content::MenuItem run_item; + run_item.action = chrome::MENU_COMMAND_PLUGIN_RUN; + // Disable this menu item if the plugin is blocked by policy. + run_item.enabled = LoadingAllowed(); + run_item.label = l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_PLUGIN_RUN); + params.custom_items.push_back(run_item); + } + + content::MenuItem hide_item; + hide_item.action = chrome::MENU_COMMAND_PLUGIN_HIDE; + hide_item.enabled = + !GetFrame()->view()->mainFrame()->document().isPluginDocument(); + hide_item.label = l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_PLUGIN_HIDE); + params.custom_items.push_back(hide_item); + + params.x = event.windowX; + params.y = event.windowY; + + context_menu_request_id_ = render_frame()->ShowContextMenu(this, params); + g_last_active_menu = this; +} + +blink::WebPlugin* CefPluginPlaceholder::CreatePlugin() { + scoped_ptr throttler; + // If the plugin has already been marked essential in its placeholder form, + // we shouldn't create a new throttler and start the process all over again. + if (power_saver_enabled()) { + throttler = content::PluginInstanceThrottler::Create(); + // PluginPreroller manages its own lifetime. + new CefPluginPreroller( + render_frame(), GetFrame(), GetPluginParams(), + GetPluginInfo(), GetIdentifier(), title_, + l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED, title_), + throttler.get()); + } + return render_frame()->CreatePlugin(GetFrame(), GetPluginInfo(), + GetPluginParams(), throttler.Pass()); +} + +gin::ObjectTemplateBuilder CefPluginPlaceholder::GetObjectTemplateBuilder( + v8::Isolate* isolate) { + return gin::Wrappable::GetObjectTemplateBuilder( + isolate) + .SetMethod( + "hide", &CefPluginPlaceholder::HideCallback) + .SetMethod( + "load", &CefPluginPlaceholder::LoadCallback) + .SetMethod( + "didFinishLoading", + &CefPluginPlaceholder::DidFinishLoadingCallback) + .SetMethod("openAboutPlugins", + &CefPluginPlaceholder::OpenAboutPluginsCallback); +} diff --git a/libcef/renderer/plugins/cef_plugin_placeholder.h b/libcef/renderer/plugins/cef_plugin_placeholder.h new file mode 100644 index 000000000..47e244adc --- /dev/null +++ b/libcef/renderer/plugins/cef_plugin_placeholder.h @@ -0,0 +1,102 @@ +// Copyright 2013 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_PLUGINS_CEF_PLUGIN_PLACEHOLDER_H_ +#define CEF_LIBCEF_RENDERER_PLUGINS_CEF_PLUGIN_PLACEHOLDER_H_ + +#include "components/plugins/renderer/loadable_plugin_placeholder.h" +#include "content/public/renderer/context_menu_client.h" +#include "content/public/renderer/render_process_observer.h" + +namespace gfx { +class Size; +} + +enum class CefViewHostMsg_GetPluginInfo_Status; + +// This contains information specifying the poster image of plugin placeholders. +// The default constructor specifies no poster image. +struct PlaceholderPosterInfo { + // The poster image specified in image 'srcset' attribute format. + std::string poster_attribute; + + // Used to resolve relative paths in |poster_attribute|. + GURL base_url; + + // Specify this to provide partially obscured plugins a centered poster image. + gfx::Size custom_poster_size; +}; + +class CefPluginPlaceholder final + : public plugins::LoadablePluginPlaceholder, + public content::RenderProcessObserver, + public content::ContextMenuClient, + public gin::Wrappable { + public: + static gin::WrapperInfo kWrapperInfo; + + static CefPluginPlaceholder* CreateBlockedPlugin( + content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params, + const content::WebPluginInfo& info, + const std::string& identifier, + const base::string16& name, + int resource_id, + const base::string16& message, + const PlaceholderPosterInfo& poster_info); + + // Creates a new WebViewPlugin with a MissingPlugin as a delegate. + static CefPluginPlaceholder* CreateLoadableMissingPlugin( + content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params); + + void SetStatus(CefViewHostMsg_GetPluginInfo_Status status); + + private: + CefPluginPlaceholder(content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params, + const std::string& html_data, + const base::string16& title); + ~CefPluginPlaceholder() override; + + // content::LoadablePluginPlaceholder method + blink::WebPlugin* CreatePlugin() override; + + // gin::Wrappable (via PluginPlaceholder) method + gin::ObjectTemplateBuilder GetObjectTemplateBuilder( + v8::Isolate* isolate) final; + + // content::RenderViewObserver (via PluginPlaceholder) override: + bool OnMessageReceived(const IPC::Message& message) override; + + // WebViewPlugin::Delegate (via PluginPlaceholder) methods: + v8::Local GetV8Handle(v8::Isolate* isolate) override; + void ShowContextMenu(const blink::WebMouseEvent&) override; + + // content::RenderProcessObserver methods: + void PluginListChanged() override; + + // content::ContextMenuClient methods: + void OnMenuAction(int request_id, unsigned action) override; + void OnMenuClosed(int request_id) override; + + // Javascript callbacks: + // Open chrome://plugins in a new tab. + void OpenAboutPluginsCallback(); + + CefViewHostMsg_GetPluginInfo_Status status_; + + base::string16 title_; + + bool has_host_; + int context_menu_request_id_; // Nonzero when request pending. + base::string16 plugin_name_; + + DISALLOW_COPY_AND_ASSIGN(CefPluginPlaceholder); +}; + +#endif // CEF_LIBCEF_RENDERER_PLUGINS_CEF_PLUGIN_PLACEHOLDER_H_ diff --git a/libcef/renderer/plugins/plugin_preroller.cc b/libcef/renderer/plugins/plugin_preroller.cc new file mode 100644 index 000000000..7870232d5 --- /dev/null +++ b/libcef/renderer/plugins/plugin_preroller.cc @@ -0,0 +1,91 @@ +// 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/plugins/plugin_preroller.h" + +#include "libcef/renderer/plugins/cef_plugin_placeholder.h" + +#include "base/base64.h" +#include "chrome/grit/generated_resources.h" +#include "third_party/WebKit/public/platform/WebRect.h" +#include "third_party/WebKit/public/web/WebElement.h" +#include "third_party/WebKit/public/web/WebPlugin.h" +#include "third_party/WebKit/public/web/WebPluginContainer.h" +#include "ui/gfx/codec/png_codec.h" + +CefPluginPreroller::CefPluginPreroller( + content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params, + const content::WebPluginInfo& info, + const std::string& identifier, + const base::string16& name, + const base::string16& message, + content::PluginInstanceThrottler* throttler) + : RenderFrameObserver(render_frame), + frame_(frame), + params_(params), + info_(info), + identifier_(identifier), + name_(name), + message_(message), + throttler_(throttler) { + DCHECK(throttler); + throttler_->AddObserver(this); +} + +CefPluginPreroller::~CefPluginPreroller() { + if (throttler_) + throttler_->RemoveObserver(this); +} + +void CefPluginPreroller::OnKeyframeExtracted(const SkBitmap* bitmap) { + std::vector png_data; + if (!gfx::PNGCodec::EncodeBGRASkBitmap(*bitmap, false, &png_data)) { + DLOG(ERROR) << "Provided keyframe could not be encoded as PNG."; + return; + } + + base::StringPiece png_as_string(reinterpret_cast(&png_data[0]), + png_data.size()); + + std::string data_url_header = "data:image/png;base64,"; + std::string data_url_body; + base::Base64Encode(png_as_string, &data_url_body); + keyframe_data_url_ = GURL(data_url_header + data_url_body); +} + +void CefPluginPreroller::OnThrottleStateChange() { + if (!throttler_->IsThrottled()) + return; + + PlaceholderPosterInfo poster_info; + poster_info.poster_attribute = keyframe_data_url_.spec(); + poster_info.custom_poster_size = throttler_->GetSize(); + + CefPluginPlaceholder* placeholder = + CefPluginPlaceholder::CreateBlockedPlugin( + render_frame(), frame_, params_, info_, identifier_, name_, + IDR_PLUGIN_POSTER_HTML, message_, poster_info); + placeholder->SetPremadePlugin(throttler_); + placeholder->set_power_saver_enabled(true); + placeholder->AllowLoading(); + + blink::WebPluginContainer* container = + throttler_->GetWebPlugin()->container(); + container->setPlugin(placeholder->plugin()); + + bool success = placeholder->plugin()->initialize(container); + DCHECK(success); + + container->invalidate(); + container->reportGeometry(); + + delete this; +} + +void CefPluginPreroller::OnThrottlerDestroyed() { + throttler_ = nullptr; + delete this; +} diff --git a/libcef/renderer/plugins/plugin_preroller.h b/libcef/renderer/plugins/plugin_preroller.h new file mode 100644 index 000000000..620ddbe17 --- /dev/null +++ b/libcef/renderer/plugins/plugin_preroller.h @@ -0,0 +1,61 @@ +// 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_PLUGINS_PLUGIN_PREROLLER_H_ +#define CEF_LIBCEF_RENDERER_PLUGINS_PLUGIN_PREROLLER_H_ + +#include "base/macros.h" +#include "content/public/common/webplugininfo.h" +#include "content/public/renderer/plugin_instance_throttler.h" +#include "content/public/renderer/render_frame_observer.h" +#include "third_party/WebKit/public/web/WebPluginParams.h" +#include "url/gurl.h" + +namespace blink { +class WebLocalFrame; +class WebPlugin; +} + +class SkBitmap; + +// This class manages a plugin briefly for the purposes of keyframe extraction. +// Once a keyframe has been extracted, this class will replace the plugin with +// a ChromePluginPlaceholder. The actual plugin will continue to live in a +// throttled state. This class manages its own lifetime. +class CefPluginPreroller : public content::PluginInstanceThrottler::Observer, + public content::RenderFrameObserver { + public: + // Does not take ownership of either |plugin| or |throttler|. + CefPluginPreroller(content::RenderFrame* render_frame, + blink::WebLocalFrame* frame, + const blink::WebPluginParams& params, + const content::WebPluginInfo& info, + const std::string& identifier, + const base::string16& name, + const base::string16& message, + content::PluginInstanceThrottler* throttler); + + ~CefPluginPreroller() override; + + private: + // content::PluginInstanceThrottler::Observer methods: + void OnKeyframeExtracted(const SkBitmap* bitmap) override; + void OnThrottleStateChange() override; + void OnThrottlerDestroyed() override; + + blink::WebLocalFrame* frame_; + blink::WebPluginParams params_; + content::WebPluginInfo info_; + std::string identifier_; + base::string16 name_; + base::string16 message_; + + content::PluginInstanceThrottler* throttler_; + + GURL keyframe_data_url_; + + DISALLOW_COPY_AND_ASSIGN(CefPluginPreroller); +}; + +#endif // CEF_LIBCEF_RENDERER_PLUGINS_PLUGIN_PREROLLER_H_ diff --git a/libcef/resources/cef_resources.grd b/libcef/resources/cef_resources.grd index e249835a2..3391b2258 100644 --- a/libcef/resources/cef_resources.grd +++ b/libcef/resources/cef_resources.grd @@ -20,6 +20,22 @@ + + + + + + + + + + + + + + + + diff --git a/libcef/resources/cef_strings.grd b/libcef/resources/cef_strings.grd index 98a5a9226..bbb8e8520 100644 --- a/libcef/resources/cef_strings.grd +++ b/libcef/resources/cef_strings.grd @@ -356,6 +356,52 @@ need to be translated for each locale.--> DirectWrite Font Cache Builder + + + + Hide this plugin + + + This plugin is not supported. + + + + Control-click to play $1Flash. + + + + + Right-click to play $1Flash. + + + + This plugin only works on the desktop. + + + $1Flash is out of date. + + + $1Java needs your permission to run. + + + $1Flash is not allowed. + + + + Run this plugin + + + Hide this plugin + + + + + Run This Plugin + + + Hide This Plugin + + diff --git a/libcef_dll/cpptoc/context_menu_handler_cpptoc.cc b/libcef_dll/cpptoc/context_menu_handler_cpptoc.cc index 7cedc854c..8e2e38127 100644 --- a/libcef_dll/cpptoc/context_menu_handler_cpptoc.cc +++ b/libcef_dll/cpptoc/context_menu_handler_cpptoc.cc @@ -15,6 +15,7 @@ #include "libcef_dll/ctocpp/context_menu_params_ctocpp.h" #include "libcef_dll/ctocpp/frame_ctocpp.h" #include "libcef_dll/ctocpp/menu_model_ctocpp.h" +#include "libcef_dll/ctocpp/run_context_menu_callback_ctocpp.h" namespace { @@ -55,6 +56,49 @@ void CEF_CALLBACK context_menu_handler_on_before_context_menu( CefMenuModelCToCpp::Wrap(model)); } +int CEF_CALLBACK context_menu_handler_run_context_menu( + struct _cef_context_menu_handler_t* self, cef_browser_t* browser, + struct _cef_frame_t* frame, struct _cef_context_menu_params_t* params, + struct _cef_menu_model_t* model, + cef_run_context_menu_callback_t* callback) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return 0; + // Verify param: browser; type: refptr_diff + DCHECK(browser); + if (!browser) + return 0; + // Verify param: frame; type: refptr_diff + DCHECK(frame); + if (!frame) + return 0; + // Verify param: params; type: refptr_diff + DCHECK(params); + if (!params) + return 0; + // Verify param: model; type: refptr_diff + DCHECK(model); + if (!model) + return 0; + // Verify param: callback; type: refptr_diff + DCHECK(callback); + if (!callback) + return 0; + + // Execute + bool _retval = CefContextMenuHandlerCppToC::Get(self)->RunContextMenu( + CefBrowserCToCpp::Wrap(browser), + CefFrameCToCpp::Wrap(frame), + CefContextMenuParamsCToCpp::Wrap(params), + CefMenuModelCToCpp::Wrap(model), + CefRunContextMenuCallbackCToCpp::Wrap(callback)); + + // Return type: bool + return _retval; +} + int CEF_CALLBACK context_menu_handler_on_context_menu_command( struct _cef_context_menu_handler_t* self, cef_browser_t* browser, struct _cef_frame_t* frame, struct _cef_context_menu_params_t* params, @@ -120,6 +164,7 @@ void CEF_CALLBACK context_menu_handler_on_context_menu_dismissed( CefContextMenuHandlerCppToC::CefContextMenuHandlerCppToC() { GetStruct()->on_before_context_menu = context_menu_handler_on_before_context_menu; + GetStruct()->run_context_menu = context_menu_handler_run_context_menu; GetStruct()->on_context_menu_command = context_menu_handler_on_context_menu_command; GetStruct()->on_context_menu_dismissed = diff --git a/libcef_dll/cpptoc/context_menu_params_cpptoc.cc b/libcef_dll/cpptoc/context_menu_params_cpptoc.cc index bcf92b0c0..0e9ba9cbb 100644 --- a/libcef_dll/cpptoc/context_menu_params_cpptoc.cc +++ b/libcef_dll/cpptoc/context_menu_params_cpptoc.cc @@ -308,6 +308,36 @@ cef_context_menu_edit_state_flags_t CEF_CALLBACK context_menu_params_get_edit_st return _retval; } +int CEF_CALLBACK context_menu_params_is_custom_menu( + struct _cef_context_menu_params_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return 0; + + // Execute + bool _retval = CefContextMenuParamsCppToC::Get(self)->IsCustomMenu(); + + // Return type: bool + return _retval; +} + +int CEF_CALLBACK context_menu_params_is_pepper_menu( + struct _cef_context_menu_params_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return 0; + + // Execute + bool _retval = CefContextMenuParamsCppToC::Get(self)->IsPepperMenu(); + + // Return type: bool + return _retval; +} + } // namespace @@ -336,6 +366,8 @@ CefContextMenuParamsCppToC::CefContextMenuParamsCppToC() { GetStruct()->is_spell_check_enabled = context_menu_params_is_spell_check_enabled; GetStruct()->get_edit_state_flags = context_menu_params_get_edit_state_flags; + GetStruct()->is_custom_menu = context_menu_params_is_custom_menu; + GetStruct()->is_pepper_menu = context_menu_params_is_pepper_menu; } template<> CefRefPtr CefCppToCOnBeforePluginLoad( + CefString(mime_type), + CefString(plugin_url), + CefString(top_origin_url), + CefWebPluginInfoCToCpp::Wrap(plugin_info), + plugin_policy); + + // Return type: bool + return _retval; +} + } // namespace @@ -41,6 +82,8 @@ cef_cookie_manager_t* CEF_CALLBACK request_context_handler_get_cookie_manager( CefRequestContextHandlerCppToC::CefRequestContextHandlerCppToC() { GetStruct()->get_cookie_manager = request_context_handler_get_cookie_manager; + GetStruct()->on_before_plugin_load = + request_context_handler_on_before_plugin_load; } template<> CefRefPtr CefCppToCOnBeforePluginLoad( - CefBrowserCToCpp::Wrap(browser), - CefString(url), - CefString(policy_url), - CefWebPluginInfoCToCpp::Wrap(info)); - - // Return type: bool - return _retval; -} - void CEF_CALLBACK request_handler_on_plugin_crashed( struct _cef_request_handler_t* self, cef_browser_t* browser, const cef_string_t* plugin_path) { @@ -495,7 +464,6 @@ CefRequestHandlerCppToC::CefRequestHandlerCppToC() { GetStruct()->on_quota_request = request_handler_on_quota_request; GetStruct()->on_protocol_execution = request_handler_on_protocol_execution; GetStruct()->on_certificate_error = request_handler_on_certificate_error; - GetStruct()->on_before_plugin_load = request_handler_on_before_plugin_load; GetStruct()->on_plugin_crashed = request_handler_on_plugin_crashed; GetStruct()->on_render_view_ready = request_handler_on_render_view_ready; GetStruct()->on_render_process_terminated = diff --git a/libcef_dll/cpptoc/resource_bundle_cpptoc.cc b/libcef_dll/cpptoc/resource_bundle_cpptoc.cc new file mode 100644 index 000000000..8ae074a17 --- /dev/null +++ b/libcef_dll/cpptoc/resource_bundle_cpptoc.cc @@ -0,0 +1,153 @@ +// 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. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool. If making changes by +// hand only do so within the body of existing method and function +// implementations. See the translator.README.txt file in the tools directory +// for more information. +// + +#include "libcef_dll/cpptoc/resource_bundle_cpptoc.h" + + +// GLOBAL FUNCTIONS - Body may be edited by hand. + +CEF_EXPORT cef_resource_bundle_t* cef_resource_bundle_get_global() { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + CefRefPtr _retval = CefResourceBundle::GetGlobal(); + + // Return type: refptr_same + return CefResourceBundleCppToC::Wrap(_retval); +} + + +namespace { + +// MEMBER FUNCTIONS - Body may be edited by hand. + +cef_string_userfree_t CEF_CALLBACK resource_bundle_get_localized_string( + struct _cef_resource_bundle_t* self, int string_id) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return NULL; + + // Execute + CefString _retval = CefResourceBundleCppToC::Get(self)->GetLocalizedString( + string_id); + + // Return type: string + return _retval.DetachToUserFree(); +} + +int CEF_CALLBACK resource_bundle_get_data_resource( + struct _cef_resource_bundle_t* self, int resource_id, void** data, + size_t* data_size) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return 0; + // Verify param: data; type: simple_byref + DCHECK(data); + if (!data) + return 0; + // Verify param: data_size; type: simple_byref + DCHECK(data_size); + if (!data_size) + return 0; + + // Translate param: data; type: simple_byref + void* dataVal = data?*data:NULL; + // Translate param: data_size; type: simple_byref + size_t data_sizeVal = data_size?*data_size:0; + + // Execute + bool _retval = CefResourceBundleCppToC::Get(self)->GetDataResource( + resource_id, + dataVal, + data_sizeVal); + + // Restore param: data; type: simple_byref + if (data) + *data = dataVal; + // Restore param: data_size; type: simple_byref + if (data_size) + *data_size = data_sizeVal; + + // Return type: bool + return _retval; +} + +int CEF_CALLBACK resource_bundle_get_data_resource_for_scale( + struct _cef_resource_bundle_t* self, int resource_id, + cef_scale_factor_t scale_factor, void** data, size_t* data_size) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return 0; + // Verify param: data; type: simple_byref + DCHECK(data); + if (!data) + return 0; + // Verify param: data_size; type: simple_byref + DCHECK(data_size); + if (!data_size) + return 0; + + // Translate param: data; type: simple_byref + void* dataVal = data?*data:NULL; + // Translate param: data_size; type: simple_byref + size_t data_sizeVal = data_size?*data_size:0; + + // Execute + bool _retval = CefResourceBundleCppToC::Get(self)->GetDataResourceForScale( + resource_id, + scale_factor, + dataVal, + data_sizeVal); + + // Restore param: data; type: simple_byref + if (data) + *data = dataVal; + // Restore param: data_size; type: simple_byref + if (data_size) + *data_size = data_sizeVal; + + // Return type: bool + return _retval; +} + +} // namespace + + +// CONSTRUCTOR - Do not edit by hand. + +CefResourceBundleCppToC::CefResourceBundleCppToC() { + GetStruct()->get_localized_string = resource_bundle_get_localized_string; + GetStruct()->get_data_resource = resource_bundle_get_data_resource; + GetStruct()->get_data_resource_for_scale = + resource_bundle_get_data_resource_for_scale; +} + +template<> CefRefPtr CefCppToC::UnwrapDerived( + CefWrapperType type, cef_resource_bundle_t* s) { + NOTREACHED() << "Unexpected class type: " << type; + return NULL; +} + +#ifndef NDEBUG +template<> base::AtomicRefCount CefCppToC::DebugObjCt = 0; +#endif + +template<> CefWrapperType CefCppToC::kWrapperType = WT_RESOURCE_BUNDLE; diff --git a/libcef_dll/cpptoc/resource_bundle_cpptoc.h b/libcef_dll/cpptoc/resource_bundle_cpptoc.h new file mode 100644 index 000000000..bad2ee437 --- /dev/null +++ b/libcef_dll/cpptoc/resource_bundle_cpptoc.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. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool. If making changes by +// hand only do so within the body of existing method and function +// implementations. See the translator.README.txt file in the tools directory +// for more information. +// + +#ifndef CEF_LIBCEF_DLL_CPPTOC_RESOURCE_BUNDLE_CPPTOC_H_ +#define CEF_LIBCEF_DLL_CPPTOC_RESOURCE_BUNDLE_CPPTOC_H_ +#pragma once + +#ifndef BUILDING_CEF_SHARED +#pragma message("Warning: "__FILE__" may be accessed DLL-side only") +#else // BUILDING_CEF_SHARED + +#include "include/cef_resource_bundle.h" +#include "include/capi/cef_resource_bundle_capi.h" +#include "libcef_dll/cpptoc/cpptoc.h" + +// Wrap a C++ class with a C structure. +// This class may be instantiated and accessed DLL-side only. +class CefResourceBundleCppToC + : public CefCppToC { + public: + CefResourceBundleCppToC(); +}; + +#endif // BUILDING_CEF_SHARED +#endif // CEF_LIBCEF_DLL_CPPTOC_RESOURCE_BUNDLE_CPPTOC_H_ diff --git a/libcef_dll/cpptoc/resource_bundle_handler_cpptoc.cc b/libcef_dll/cpptoc/resource_bundle_handler_cpptoc.cc index 946c36e3c..229910aa0 100644 --- a/libcef_dll/cpptoc/resource_bundle_handler_cpptoc.cc +++ b/libcef_dll/cpptoc/resource_bundle_handler_cpptoc.cc @@ -18,7 +18,7 @@ namespace { // MEMBER FUNCTIONS - Body may be edited by hand. int CEF_CALLBACK resource_bundle_handler_get_localized_string( - struct _cef_resource_bundle_handler_t* self, int message_id, + struct _cef_resource_bundle_handler_t* self, int string_id, cef_string_t* string) { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING @@ -35,7 +35,7 @@ int CEF_CALLBACK resource_bundle_handler_get_localized_string( // Execute bool _retval = CefResourceBundleHandlerCppToC::Get(self)->GetLocalizedString( - message_id, + string_id, stringStr); // Return type: bool @@ -81,6 +81,47 @@ int CEF_CALLBACK resource_bundle_handler_get_data_resource( return _retval; } +int CEF_CALLBACK resource_bundle_handler_get_data_resource_for_scale( + struct _cef_resource_bundle_handler_t* self, int resource_id, + cef_scale_factor_t scale_factor, void** data, size_t* data_size) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return 0; + // Verify param: data; type: simple_byref + DCHECK(data); + if (!data) + return 0; + // Verify param: data_size; type: simple_byref + DCHECK(data_size); + if (!data_size) + return 0; + + // Translate param: data; type: simple_byref + void* dataVal = data?*data:NULL; + // Translate param: data_size; type: simple_byref + size_t data_sizeVal = data_size?*data_size:0; + + // Execute + bool _retval = CefResourceBundleHandlerCppToC::Get( + self)->GetDataResourceForScale( + resource_id, + scale_factor, + dataVal, + data_sizeVal); + + // Restore param: data; type: simple_byref + if (data) + *data = dataVal; + // Restore param: data_size; type: simple_byref + if (data_size) + *data_size = data_sizeVal; + + // Return type: bool + return _retval; +} + } // namespace @@ -90,6 +131,8 @@ CefResourceBundleHandlerCppToC::CefResourceBundleHandlerCppToC() { GetStruct()->get_localized_string = resource_bundle_handler_get_localized_string; GetStruct()->get_data_resource = resource_bundle_handler_get_data_resource; + GetStruct()->get_data_resource_for_scale = + resource_bundle_handler_get_data_resource_for_scale; } template<> CefRefPtr CefCppToCContinue( + command_id, + event_flags); +} + +void CEF_CALLBACK run_context_menu_callback_cancel( + struct _cef_run_context_menu_callback_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return; + + // Execute + CefRunContextMenuCallbackCppToC::Get(self)->Cancel(); +} + +} // namespace + + +// CONSTRUCTOR - Do not edit by hand. + +CefRunContextMenuCallbackCppToC::CefRunContextMenuCallbackCppToC() { + GetStruct()->cont = run_context_menu_callback_cont; + GetStruct()->cancel = run_context_menu_callback_cancel; +} + +template<> CefRefPtr CefCppToC::UnwrapDerived( + CefWrapperType type, cef_run_context_menu_callback_t* s) { + NOTREACHED() << "Unexpected class type: " << type; + return NULL; +} + +#ifndef NDEBUG +template<> base::AtomicRefCount CefCppToC::DebugObjCt = + 0; +#endif + +template<> CefWrapperType CefCppToC::kWrapperType = + WT_RUN_CONTEXT_MENU_CALLBACK; diff --git a/libcef_dll/cpptoc/run_context_menu_callback_cpptoc.h b/libcef_dll/cpptoc/run_context_menu_callback_cpptoc.h new file mode 100644 index 000000000..465270b08 --- /dev/null +++ b/libcef_dll/cpptoc/run_context_menu_callback_cpptoc.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. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool. If making changes by +// hand only do so within the body of existing method and function +// implementations. See the translator.README.txt file in the tools directory +// for more information. +// + +#ifndef CEF_LIBCEF_DLL_CPPTOC_RUN_CONTEXT_MENU_CALLBACK_CPPTOC_H_ +#define CEF_LIBCEF_DLL_CPPTOC_RUN_CONTEXT_MENU_CALLBACK_CPPTOC_H_ +#pragma once + +#ifndef BUILDING_CEF_SHARED +#pragma message("Warning: "__FILE__" may be accessed DLL-side only") +#else // BUILDING_CEF_SHARED + +#include "include/cef_context_menu_handler.h" +#include "include/capi/cef_context_menu_handler_capi.h" +#include "libcef_dll/cpptoc/cpptoc.h" + +// Wrap a C++ class with a C structure. +// This class may be instantiated and accessed DLL-side only. +class CefRunContextMenuCallbackCppToC + : public CefCppToC { + public: + CefRunContextMenuCallbackCppToC(); +}; + +#endif // BUILDING_CEF_SHARED +#endif // CEF_LIBCEF_DLL_CPPTOC_RUN_CONTEXT_MENU_CALLBACK_CPPTOC_H_ diff --git a/libcef_dll/cpptoc/web_plugin_info_cpptoc.h b/libcef_dll/cpptoc/web_plugin_info_cpptoc.h index 72a04fbb5..7f1047c1e 100644 --- a/libcef_dll/cpptoc/web_plugin_info_cpptoc.h +++ b/libcef_dll/cpptoc/web_plugin_info_cpptoc.h @@ -20,6 +20,8 @@ #include "include/cef_web_plugin.h" #include "include/capi/cef_web_plugin_capi.h" +#include "include/cef_browser.h" +#include "include/capi/cef_browser_capi.h" #include "libcef_dll/cpptoc/cpptoc.h" // Wrap a C++ class with a C structure. diff --git a/libcef_dll/cpptoc/web_plugin_info_visitor_cpptoc.h b/libcef_dll/cpptoc/web_plugin_info_visitor_cpptoc.h index a488e4e3c..28ea294a3 100644 --- a/libcef_dll/cpptoc/web_plugin_info_visitor_cpptoc.h +++ b/libcef_dll/cpptoc/web_plugin_info_visitor_cpptoc.h @@ -20,6 +20,8 @@ #include "include/cef_web_plugin.h" #include "include/capi/cef_web_plugin_capi.h" +#include "include/cef_browser.h" +#include "include/capi/cef_browser_capi.h" #include "libcef_dll/cpptoc/cpptoc.h" // Wrap a C++ class with a C structure. diff --git a/libcef_dll/cpptoc/web_plugin_unstable_callback_cpptoc.h b/libcef_dll/cpptoc/web_plugin_unstable_callback_cpptoc.h index 9d38cd0f3..c89d2d777 100644 --- a/libcef_dll/cpptoc/web_plugin_unstable_callback_cpptoc.h +++ b/libcef_dll/cpptoc/web_plugin_unstable_callback_cpptoc.h @@ -20,6 +20,8 @@ #include "include/cef_web_plugin.h" #include "include/capi/cef_web_plugin_capi.h" +#include "include/cef_browser.h" +#include "include/capi/cef_browser_capi.h" #include "libcef_dll/cpptoc/cpptoc.h" // Wrap a C++ class with a C structure. diff --git a/libcef_dll/ctocpp/context_menu_handler_ctocpp.cc b/libcef_dll/ctocpp/context_menu_handler_ctocpp.cc index b6c52e1ae..2f5162b63 100644 --- a/libcef_dll/ctocpp/context_menu_handler_ctocpp.cc +++ b/libcef_dll/ctocpp/context_menu_handler_ctocpp.cc @@ -14,6 +14,7 @@ #include "libcef_dll/cpptoc/context_menu_params_cpptoc.h" #include "libcef_dll/cpptoc/frame_cpptoc.h" #include "libcef_dll/cpptoc/menu_model_cpptoc.h" +#include "libcef_dll/cpptoc/run_context_menu_callback_cpptoc.h" #include "libcef_dll/ctocpp/context_menu_handler_ctocpp.h" @@ -53,6 +54,49 @@ void CefContextMenuHandlerCToCpp::OnBeforeContextMenu( CefMenuModelCppToC::Wrap(model)); } +bool CefContextMenuHandlerCToCpp::RunContextMenu(CefRefPtr browser, + CefRefPtr frame, CefRefPtr params, + CefRefPtr model, + CefRefPtr callback) { + cef_context_menu_handler_t* _struct = GetStruct(); + if (CEF_MEMBER_MISSING(_struct, run_context_menu)) + return false; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Verify param: browser; type: refptr_diff + DCHECK(browser.get()); + if (!browser.get()) + return false; + // Verify param: frame; type: refptr_diff + DCHECK(frame.get()); + if (!frame.get()) + return false; + // Verify param: params; type: refptr_diff + DCHECK(params.get()); + if (!params.get()) + return false; + // Verify param: model; type: refptr_diff + DCHECK(model.get()); + if (!model.get()) + return false; + // Verify param: callback; type: refptr_diff + DCHECK(callback.get()); + if (!callback.get()) + return false; + + // Execute + int _retval = _struct->run_context_menu(_struct, + CefBrowserCppToC::Wrap(browser), + CefFrameCppToC::Wrap(frame), + CefContextMenuParamsCppToC::Wrap(params), + CefMenuModelCppToC::Wrap(model), + CefRunContextMenuCallbackCppToC::Wrap(callback)); + + // Return type: bool + return _retval?true:false; +} + bool CefContextMenuHandlerCToCpp::OnContextMenuCommand( CefRefPtr browser, CefRefPtr frame, CefRefPtr params, int command_id, diff --git a/libcef_dll/ctocpp/context_menu_handler_ctocpp.h b/libcef_dll/ctocpp/context_menu_handler_ctocpp.h index a231de9fa..fc7f275e3 100644 --- a/libcef_dll/ctocpp/context_menu_handler_ctocpp.h +++ b/libcef_dll/ctocpp/context_menu_handler_ctocpp.h @@ -34,6 +34,9 @@ class CefContextMenuHandlerCToCpp void OnBeforeContextMenu(CefRefPtr browser, CefRefPtr frame, CefRefPtr params, CefRefPtr model) override; + bool RunContextMenu(CefRefPtr browser, CefRefPtr frame, + CefRefPtr params, CefRefPtr model, + CefRefPtr callback) override; bool OnContextMenuCommand(CefRefPtr browser, CefRefPtr frame, CefRefPtr params, int command_id, EventFlags event_flags) override; diff --git a/libcef_dll/ctocpp/context_menu_params_ctocpp.cc b/libcef_dll/ctocpp/context_menu_params_ctocpp.cc index f1119cb2d..a240df8ca 100644 --- a/libcef_dll/ctocpp/context_menu_params_ctocpp.cc +++ b/libcef_dll/ctocpp/context_menu_params_ctocpp.cc @@ -303,6 +303,34 @@ CefContextMenuParams::EditStateFlags CefContextMenuParamsCToCpp::GetEditStateFla return _retval; } +bool CefContextMenuParamsCToCpp::IsCustomMenu() { + cef_context_menu_params_t* _struct = GetStruct(); + if (CEF_MEMBER_MISSING(_struct, is_custom_menu)) + return false; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + int _retval = _struct->is_custom_menu(_struct); + + // Return type: bool + return _retval?true:false; +} + +bool CefContextMenuParamsCToCpp::IsPepperMenu() { + cef_context_menu_params_t* _struct = GetStruct(); + if (CEF_MEMBER_MISSING(_struct, is_pepper_menu)) + return false; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + int _retval = _struct->is_pepper_menu(_struct); + + // Return type: bool + return _retval?true:false; +} + // CONSTRUCTOR - Do not edit by hand. diff --git a/libcef_dll/ctocpp/context_menu_params_ctocpp.h b/libcef_dll/ctocpp/context_menu_params_ctocpp.h index e9fdc8a65..1b0ad4f85 100644 --- a/libcef_dll/ctocpp/context_menu_params_ctocpp.h +++ b/libcef_dll/ctocpp/context_menu_params_ctocpp.h @@ -50,6 +50,8 @@ class CefContextMenuParamsCToCpp bool IsEditable() OVERRIDE; bool IsSpellCheckEnabled() OVERRIDE; EditStateFlags GetEditStateFlags() OVERRIDE; + bool IsCustomMenu() OVERRIDE; + bool IsPepperMenu() OVERRIDE; }; #endif // USING_CEF_SHARED diff --git a/libcef_dll/ctocpp/request_context_handler_ctocpp.cc b/libcef_dll/ctocpp/request_context_handler_ctocpp.cc index cd82c7911..c6f884665 100644 --- a/libcef_dll/ctocpp/request_context_handler_ctocpp.cc +++ b/libcef_dll/ctocpp/request_context_handler_ctocpp.cc @@ -11,6 +11,7 @@ // #include "libcef_dll/cpptoc/cookie_manager_cpptoc.h" +#include "libcef_dll/cpptoc/web_plugin_info_cpptoc.h" #include "libcef_dll/ctocpp/request_context_handler_ctocpp.h" @@ -30,6 +31,46 @@ CefRefPtr CefRequestContextHandlerCToCpp::GetCookieManager() { return CefCookieManagerCppToC::Unwrap(_retval); } +bool CefRequestContextHandlerCToCpp::OnBeforePluginLoad( + const CefString& mime_type, const CefString& plugin_url, + const CefString& top_origin_url, CefRefPtr plugin_info, + PluginPolicy* plugin_policy) { + cef_request_context_handler_t* _struct = GetStruct(); + if (CEF_MEMBER_MISSING(_struct, on_before_plugin_load)) + return false; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Verify param: mime_type; type: string_byref_const + DCHECK(!mime_type.empty()); + if (mime_type.empty()) + return false; + // Verify param: top_origin_url; type: string_byref_const + DCHECK(!top_origin_url.empty()); + if (top_origin_url.empty()) + return false; + // Verify param: plugin_info; type: refptr_diff + DCHECK(plugin_info.get()); + if (!plugin_info.get()) + return false; + // Verify param: plugin_policy; type: simple_byaddr + DCHECK(plugin_policy); + if (!plugin_policy) + return false; + // Unverified params: plugin_url + + // Execute + int _retval = _struct->on_before_plugin_load(_struct, + mime_type.GetStruct(), + plugin_url.GetStruct(), + top_origin_url.GetStruct(), + CefWebPluginInfoCppToC::Wrap(plugin_info), + plugin_policy); + + // Return type: bool + return _retval?true:false; +} + // CONSTRUCTOR - Do not edit by hand. diff --git a/libcef_dll/ctocpp/request_context_handler_ctocpp.h b/libcef_dll/ctocpp/request_context_handler_ctocpp.h index a8568270f..4e80f1c89 100644 --- a/libcef_dll/ctocpp/request_context_handler_ctocpp.h +++ b/libcef_dll/ctocpp/request_context_handler_ctocpp.h @@ -32,6 +32,10 @@ class CefRequestContextHandlerCToCpp // CefRequestContextHandler methods. CefRefPtr GetCookieManager() override; + bool OnBeforePluginLoad(const CefString& mime_type, + const CefString& plugin_url, const CefString& top_origin_url, + CefRefPtr plugin_info, + PluginPolicy* plugin_policy) override; }; #endif // BUILDING_CEF_SHARED diff --git a/libcef_dll/ctocpp/request_handler_ctocpp.cc b/libcef_dll/ctocpp/request_handler_ctocpp.cc index b9446e128..47ee37ded 100644 --- a/libcef_dll/ctocpp/request_handler_ctocpp.cc +++ b/libcef_dll/ctocpp/request_handler_ctocpp.cc @@ -17,7 +17,6 @@ #include "libcef_dll/cpptoc/request_callback_cpptoc.h" #include "libcef_dll/cpptoc/response_cpptoc.h" #include "libcef_dll/cpptoc/sslinfo_cpptoc.h" -#include "libcef_dll/cpptoc/web_plugin_info_cpptoc.h" #include "libcef_dll/ctocpp/request_handler_ctocpp.h" #include "libcef_dll/ctocpp/resource_handler_ctocpp.h" @@ -375,36 +374,6 @@ bool CefRequestHandlerCToCpp::OnCertificateError(CefRefPtr browser, return _retval?true:false; } -bool CefRequestHandlerCToCpp::OnBeforePluginLoad(CefRefPtr browser, - const CefString& url, const CefString& policy_url, - CefRefPtr info) { - cef_request_handler_t* _struct = GetStruct(); - if (CEF_MEMBER_MISSING(_struct, on_before_plugin_load)) - return false; - - // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING - - // Verify param: browser; type: refptr_diff - DCHECK(browser.get()); - if (!browser.get()) - return false; - // Verify param: info; type: refptr_diff - DCHECK(info.get()); - if (!info.get()) - return false; - // Unverified params: url, policy_url - - // Execute - int _retval = _struct->on_before_plugin_load(_struct, - CefBrowserCppToC::Wrap(browser), - url.GetStruct(), - policy_url.GetStruct(), - CefWebPluginInfoCppToC::Wrap(info)); - - // Return type: bool - return _retval?true:false; -} - void CefRequestHandlerCToCpp::OnPluginCrashed(CefRefPtr browser, const CefString& plugin_path) { cef_request_handler_t* _struct = GetStruct(); diff --git a/libcef_dll/ctocpp/request_handler_ctocpp.h b/libcef_dll/ctocpp/request_handler_ctocpp.h index 7fd6b32e5..eb78000c5 100644 --- a/libcef_dll/ctocpp/request_handler_ctocpp.h +++ b/libcef_dll/ctocpp/request_handler_ctocpp.h @@ -61,8 +61,6 @@ class CefRequestHandlerCToCpp cef_errorcode_t cert_error, const CefString& request_url, CefRefPtr ssl_info, CefRefPtr callback) override; - bool OnBeforePluginLoad(CefRefPtr browser, const CefString& url, - const CefString& policy_url, CefRefPtr info) override; void OnPluginCrashed(CefRefPtr browser, const CefString& plugin_path) override; void OnRenderViewReady(CefRefPtr browser) override; diff --git a/libcef_dll/ctocpp/resource_bundle_ctocpp.cc b/libcef_dll/ctocpp/resource_bundle_ctocpp.cc new file mode 100644 index 000000000..f050682c4 --- /dev/null +++ b/libcef_dll/ctocpp/resource_bundle_ctocpp.cc @@ -0,0 +1,104 @@ +// 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. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool. If making changes by +// hand only do so within the body of existing method and function +// implementations. See the translator.README.txt file in the tools directory +// for more information. +// + +#include "libcef_dll/ctocpp/resource_bundle_ctocpp.h" + + +// STATIC METHODS - Body may be edited by hand. + +CefRefPtr CefResourceBundle::GetGlobal() { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + cef_resource_bundle_t* _retval = cef_resource_bundle_get_global(); + + // Return type: refptr_same + return CefResourceBundleCToCpp::Wrap(_retval); +} + + +// VIRTUAL METHODS - Body may be edited by hand. + +CefString CefResourceBundleCToCpp::GetLocalizedString(int string_id) { + cef_resource_bundle_t* _struct = GetStruct(); + if (CEF_MEMBER_MISSING(_struct, get_localized_string)) + return CefString(); + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + cef_string_userfree_t _retval = _struct->get_localized_string(_struct, + string_id); + + // Return type: string + CefString _retvalStr; + _retvalStr.AttachToUserFree(_retval); + return _retvalStr; +} + +bool CefResourceBundleCToCpp::GetDataResource(int resource_id, void*& data, + size_t& data_size) { + cef_resource_bundle_t* _struct = GetStruct(); + if (CEF_MEMBER_MISSING(_struct, get_data_resource)) + return false; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + int _retval = _struct->get_data_resource(_struct, + resource_id, + &data, + &data_size); + + // Return type: bool + return _retval?true:false; +} + +bool CefResourceBundleCToCpp::GetDataResourceForScale(int resource_id, + ScaleFactor scale_factor, void*& data, size_t& data_size) { + cef_resource_bundle_t* _struct = GetStruct(); + if (CEF_MEMBER_MISSING(_struct, get_data_resource_for_scale)) + return false; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + int _retval = _struct->get_data_resource_for_scale(_struct, + resource_id, + scale_factor, + &data, + &data_size); + + // Return type: bool + return _retval?true:false; +} + + +// CONSTRUCTOR - Do not edit by hand. + +CefResourceBundleCToCpp::CefResourceBundleCToCpp() { +} + +template<> cef_resource_bundle_t* CefCToCpp::UnwrapDerived( + CefWrapperType type, CefResourceBundle* c) { + NOTREACHED() << "Unexpected class type: " << type; + return NULL; +} + +#ifndef NDEBUG +template<> base::AtomicRefCount CefCToCpp::DebugObjCt = 0; +#endif + +template<> CefWrapperType CefCToCpp::kWrapperType = WT_RESOURCE_BUNDLE; diff --git a/libcef_dll/ctocpp/resource_bundle_ctocpp.h b/libcef_dll/ctocpp/resource_bundle_ctocpp.h new file mode 100644 index 000000000..e7cf0cb4a --- /dev/null +++ b/libcef_dll/ctocpp/resource_bundle_ctocpp.h @@ -0,0 +1,42 @@ +// 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. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool. If making changes by +// hand only do so within the body of existing method and function +// implementations. See the translator.README.txt file in the tools directory +// for more information. +// + +#ifndef CEF_LIBCEF_DLL_CTOCPP_RESOURCE_BUNDLE_CTOCPP_H_ +#define CEF_LIBCEF_DLL_CTOCPP_RESOURCE_BUNDLE_CTOCPP_H_ +#pragma once + +#ifndef USING_CEF_SHARED +#pragma message("Warning: "__FILE__" may be accessed wrapper-side only") +#else // USING_CEF_SHARED + +#include "include/cef_resource_bundle.h" +#include "include/capi/cef_resource_bundle_capi.h" +#include "libcef_dll/ctocpp/ctocpp.h" + +// Wrap a C structure with a C++ class. +// This class may be instantiated and accessed wrapper-side only. +class CefResourceBundleCToCpp + : public CefCToCpp { + public: + CefResourceBundleCToCpp(); + + // CefResourceBundle methods. + CefString GetLocalizedString(int string_id) OVERRIDE; + bool GetDataResource(int resource_id, void*& data, + size_t& data_size) OVERRIDE; + bool GetDataResourceForScale(int resource_id, ScaleFactor scale_factor, + void*& data, size_t& data_size) OVERRIDE; +}; + +#endif // USING_CEF_SHARED +#endif // CEF_LIBCEF_DLL_CTOCPP_RESOURCE_BUNDLE_CTOCPP_H_ diff --git a/libcef_dll/ctocpp/resource_bundle_handler_ctocpp.cc b/libcef_dll/ctocpp/resource_bundle_handler_ctocpp.cc index b40133f26..445245349 100644 --- a/libcef_dll/ctocpp/resource_bundle_handler_ctocpp.cc +++ b/libcef_dll/ctocpp/resource_bundle_handler_ctocpp.cc @@ -15,7 +15,7 @@ // VIRTUAL METHODS - Body may be edited by hand. -bool CefResourceBundleHandlerCToCpp::GetLocalizedString(int message_id, +bool CefResourceBundleHandlerCToCpp::GetLocalizedString(int string_id, CefString& string) { cef_resource_bundle_handler_t* _struct = GetStruct(); if (CEF_MEMBER_MISSING(_struct, get_localized_string)) @@ -25,7 +25,7 @@ bool CefResourceBundleHandlerCToCpp::GetLocalizedString(int message_id, // Execute int _retval = _struct->get_localized_string(_struct, - message_id, + string_id, string.GetWritableStruct()); // Return type: bool @@ -50,6 +50,25 @@ bool CefResourceBundleHandlerCToCpp::GetDataResource(int resource_id, return _retval?true:false; } +bool CefResourceBundleHandlerCToCpp::GetDataResourceForScale(int resource_id, + ScaleFactor scale_factor, void*& data, size_t& data_size) { + cef_resource_bundle_handler_t* _struct = GetStruct(); + if (CEF_MEMBER_MISSING(_struct, get_data_resource_for_scale)) + return false; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + int _retval = _struct->get_data_resource_for_scale(_struct, + resource_id, + scale_factor, + &data, + &data_size); + + // Return type: bool + return _retval?true:false; +} + // CONSTRUCTOR - Do not edit by hand. diff --git a/libcef_dll/ctocpp/resource_bundle_handler_ctocpp.h b/libcef_dll/ctocpp/resource_bundle_handler_ctocpp.h index aeafdea18..947330e28 100644 --- a/libcef_dll/ctocpp/resource_bundle_handler_ctocpp.h +++ b/libcef_dll/ctocpp/resource_bundle_handler_ctocpp.h @@ -31,9 +31,11 @@ class CefResourceBundleHandlerCToCpp CefResourceBundleHandlerCToCpp(); // CefResourceBundleHandler methods. - bool GetLocalizedString(int message_id, CefString& string) override; + bool GetLocalizedString(int string_id, CefString& string) override; bool GetDataResource(int resource_id, void*& data, size_t& data_size) override; + bool GetDataResourceForScale(int resource_id, ScaleFactor scale_factor, + void*& data, size_t& data_size) override; }; #endif // BUILDING_CEF_SHARED diff --git a/libcef_dll/ctocpp/run_context_menu_callback_ctocpp.cc b/libcef_dll/ctocpp/run_context_menu_callback_ctocpp.cc new file mode 100644 index 000000000..1a534c6f5 --- /dev/null +++ b/libcef_dll/ctocpp/run_context_menu_callback_ctocpp.cc @@ -0,0 +1,64 @@ +// 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. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool. If making changes by +// hand only do so within the body of existing method and function +// implementations. See the translator.README.txt file in the tools directory +// for more information. +// + +#include "libcef_dll/ctocpp/run_context_menu_callback_ctocpp.h" + + +// VIRTUAL METHODS - Body may be edited by hand. + +void CefRunContextMenuCallbackCToCpp::Continue(int command_id, + EventFlags event_flags) { + cef_run_context_menu_callback_t* _struct = GetStruct(); + if (CEF_MEMBER_MISSING(_struct, cont)) + return; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + _struct->cont(_struct, + command_id, + event_flags); +} + +void CefRunContextMenuCallbackCToCpp::Cancel() { + cef_run_context_menu_callback_t* _struct = GetStruct(); + if (CEF_MEMBER_MISSING(_struct, cancel)) + return; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + _struct->cancel(_struct); +} + + +// CONSTRUCTOR - Do not edit by hand. + +CefRunContextMenuCallbackCToCpp::CefRunContextMenuCallbackCToCpp() { +} + +template<> cef_run_context_menu_callback_t* CefCToCpp::UnwrapDerived( + CefWrapperType type, CefRunContextMenuCallback* c) { + NOTREACHED() << "Unexpected class type: " << type; + return NULL; +} + +#ifndef NDEBUG +template<> base::AtomicRefCount CefCToCpp::DebugObjCt = + 0; +#endif + +template<> CefWrapperType CefCToCpp::kWrapperType = + WT_RUN_CONTEXT_MENU_CALLBACK; diff --git a/libcef_dll/ctocpp/run_context_menu_callback_ctocpp.h b/libcef_dll/ctocpp/run_context_menu_callback_ctocpp.h new file mode 100644 index 000000000..fd44bcf44 --- /dev/null +++ b/libcef_dll/ctocpp/run_context_menu_callback_ctocpp.h @@ -0,0 +1,39 @@ +// 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. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool. If making changes by +// hand only do so within the body of existing method and function +// implementations. See the translator.README.txt file in the tools directory +// for more information. +// + +#ifndef CEF_LIBCEF_DLL_CTOCPP_RUN_CONTEXT_MENU_CALLBACK_CTOCPP_H_ +#define CEF_LIBCEF_DLL_CTOCPP_RUN_CONTEXT_MENU_CALLBACK_CTOCPP_H_ +#pragma once + +#ifndef USING_CEF_SHARED +#pragma message("Warning: "__FILE__" may be accessed wrapper-side only") +#else // USING_CEF_SHARED + +#include "include/cef_context_menu_handler.h" +#include "include/capi/cef_context_menu_handler_capi.h" +#include "libcef_dll/ctocpp/ctocpp.h" + +// Wrap a C structure with a C++ class. +// This class may be instantiated and accessed wrapper-side only. +class CefRunContextMenuCallbackCToCpp + : public CefCToCpp { + public: + CefRunContextMenuCallbackCToCpp(); + + // CefRunContextMenuCallback methods. + void Continue(int command_id, EventFlags event_flags) OVERRIDE; + void Cancel() OVERRIDE; +}; + +#endif // USING_CEF_SHARED +#endif // CEF_LIBCEF_DLL_CTOCPP_RUN_CONTEXT_MENU_CALLBACK_CTOCPP_H_ diff --git a/libcef_dll/ctocpp/web_plugin_info_ctocpp.h b/libcef_dll/ctocpp/web_plugin_info_ctocpp.h index a1ff1f94c..afcc46285 100644 --- a/libcef_dll/ctocpp/web_plugin_info_ctocpp.h +++ b/libcef_dll/ctocpp/web_plugin_info_ctocpp.h @@ -20,6 +20,8 @@ #include "include/cef_web_plugin.h" #include "include/capi/cef_web_plugin_capi.h" +#include "include/cef_browser.h" +#include "include/capi/cef_browser_capi.h" #include "libcef_dll/ctocpp/ctocpp.h" // Wrap a C structure with a C++ class. diff --git a/libcef_dll/ctocpp/web_plugin_info_visitor_ctocpp.h b/libcef_dll/ctocpp/web_plugin_info_visitor_ctocpp.h index 83a6fd074..f266dd9ec 100644 --- a/libcef_dll/ctocpp/web_plugin_info_visitor_ctocpp.h +++ b/libcef_dll/ctocpp/web_plugin_info_visitor_ctocpp.h @@ -20,6 +20,8 @@ #include "include/cef_web_plugin.h" #include "include/capi/cef_web_plugin_capi.h" +#include "include/cef_browser.h" +#include "include/capi/cef_browser_capi.h" #include "libcef_dll/ctocpp/ctocpp.h" // Wrap a C structure with a C++ class. diff --git a/libcef_dll/ctocpp/web_plugin_unstable_callback_ctocpp.h b/libcef_dll/ctocpp/web_plugin_unstable_callback_ctocpp.h index 767ad1c95..f223bfbae 100644 --- a/libcef_dll/ctocpp/web_plugin_unstable_callback_ctocpp.h +++ b/libcef_dll/ctocpp/web_plugin_unstable_callback_ctocpp.h @@ -20,6 +20,8 @@ #include "include/cef_web_plugin.h" #include "include/capi/cef_web_plugin_capi.h" +#include "include/cef_browser.h" +#include "include/capi/cef_browser_capi.h" #include "libcef_dll/ctocpp/ctocpp.h" // Wrap a C structure with a C++ class. diff --git a/libcef_dll/libcef_dll.cc b/libcef_dll/libcef_dll.cc index 852591ad2..0b826f900 100644 --- a/libcef_dll/libcef_dll.cc +++ b/libcef_dll/libcef_dll.cc @@ -58,6 +58,7 @@ #include "libcef_dll/cpptoc/print_settings_cpptoc.h" #include "libcef_dll/cpptoc/process_message_cpptoc.h" #include "libcef_dll/cpptoc/request_callback_cpptoc.h" +#include "libcef_dll/cpptoc/run_context_menu_callback_cpptoc.h" #include "libcef_dll/cpptoc/sslcert_principal_cpptoc.h" #include "libcef_dll/cpptoc/sslinfo_cpptoc.h" #include "libcef_dll/cpptoc/scheme_registrar_cpptoc.h" @@ -248,6 +249,8 @@ CEF_EXPORT void cef_shutdown() { DCHECK(base::AtomicRefCountIsZero( &CefResourceBundleHandlerCToCpp::DebugObjCt)); DCHECK(base::AtomicRefCountIsZero(&CefResourceHandlerCToCpp::DebugObjCt)); + DCHECK(base::AtomicRefCountIsZero( + &CefRunContextMenuCallbackCppToC::DebugObjCt)); DCHECK(base::AtomicRefCountIsZero( &CefRunFileDialogCallbackCToCpp::DebugObjCt)); DCHECK(base::AtomicRefCountIsZero(&CefSSLCertPrincipalCppToC::DebugObjCt)); diff --git a/libcef_dll/wrapper/libcef_dll_wrapper.cc b/libcef_dll/wrapper/libcef_dll_wrapper.cc index c2dfb6ccf..a005e93b8 100644 --- a/libcef_dll/wrapper/libcef_dll_wrapper.cc +++ b/libcef_dll/wrapper/libcef_dll_wrapper.cc @@ -99,6 +99,7 @@ #include "libcef_dll/ctocpp/print_settings_ctocpp.h" #include "libcef_dll/ctocpp/process_message_ctocpp.h" #include "libcef_dll/ctocpp/request_callback_ctocpp.h" +#include "libcef_dll/ctocpp/run_context_menu_callback_ctocpp.h" #include "libcef_dll/ctocpp/sslcert_principal_ctocpp.h" #include "libcef_dll/ctocpp/sslinfo_ctocpp.h" #include "libcef_dll/ctocpp/scheme_registrar_ctocpp.h" @@ -240,6 +241,8 @@ CEF_GLOBAL void CefShutdown() { DCHECK(base::AtomicRefCountIsZero( &CefResourceBundleHandlerCppToC::DebugObjCt)); DCHECK(base::AtomicRefCountIsZero(&CefResourceHandlerCppToC::DebugObjCt)); + DCHECK(base::AtomicRefCountIsZero( + &CefRunContextMenuCallbackCToCpp::DebugObjCt)); DCHECK(base::AtomicRefCountIsZero( &CefRunFileDialogCallbackCppToC::DebugObjCt)); DCHECK(base::AtomicRefCountIsZero(&CefSSLCertPrincipalCToCpp::DebugObjCt)); diff --git a/libcef_dll/wrapper_types.h b/libcef_dll/wrapper_types.h index 25f3fef3c..e33cf750b 100644 --- a/libcef_dll/wrapper_types.h +++ b/libcef_dll/wrapper_types.h @@ -76,9 +76,11 @@ enum CefWrapperType { WT_REQUEST_CONTEXT, WT_REQUEST_CONTEXT_HANDLER, WT_REQUEST_HANDLER, + WT_RESOURCE_BUNDLE, WT_RESOURCE_BUNDLE_HANDLER, WT_RESOURCE_HANDLER, WT_RESPONSE, + WT_RUN_CONTEXT_MENU_CALLBACK, WT_RUN_FILE_DIALOG_CALLBACK, WT_SSLCERT_PRINCIPAL, WT_SSLINFO, diff --git a/tests/cefclient/browser/client_app_browser.cc b/tests/cefclient/browser/client_app_browser.cc index 98a3557b6..958137180 100644 --- a/tests/cefclient/browser/client_app_browser.cc +++ b/tests/cefclient/browser/client_app_browser.cc @@ -11,6 +11,7 @@ namespace client { ClientAppBrowser::ClientAppBrowser() { + CreateDelegates(delegates_); } void ClientAppBrowser::OnBeforeCommandLineProcessing( @@ -46,12 +47,14 @@ void ClientAppBrowser::OnBeforeCommandLineProcessing( // See https://bitbucket.org/chromiumembedded/cef/issues/1368 for details. command_line->AppendSwitch("enable-begin-frame-scheduling"); } + + DelegateSet::iterator it = delegates_.begin(); + for (; it != delegates_.end(); ++it) + (*it)->OnBeforeCommandLineProcessing(this, command_line); } } void ClientAppBrowser::OnContextInitialized() { - CreateDelegates(delegates_); - // Register cookieable schemes with the global cookie manager. CefRefPtr manager = CefCookieManager::GetGlobalManager(NULL); diff --git a/tests/cefclient/browser/client_app_browser.h b/tests/cefclient/browser/client_app_browser.h index 18a4041a1..0d2521361 100644 --- a/tests/cefclient/browser/client_app_browser.h +++ b/tests/cefclient/browser/client_app_browser.h @@ -21,7 +21,11 @@ class ClientAppBrowser : public ClientApp, // constructor. See CefBrowserProcessHandler for documentation. class Delegate : public virtual CefBase { public: - virtual void OnContextInitialized(CefRefPtr app) {} + virtual void OnBeforeCommandLineProcessing( + CefRefPtr app, + CefRefPtr command_line) {} + + virtual void OnContextInitialized(CefRefPtr app) {} virtual void OnBeforeChildProcessLaunch( CefRefPtr app, diff --git a/tests/cefclient/browser/root_window_manager.cc b/tests/cefclient/browser/root_window_manager.cc index 8c9d3ee44..b4745c6cc 100644 --- a/tests/cefclient/browser/root_window_manager.cc +++ b/tests/cefclient/browser/root_window_manager.cc @@ -15,6 +15,32 @@ namespace client { +namespace { + +class ClientRequestContextHandler : public CefRequestContextHandler { + public: + ClientRequestContextHandler() {} + + bool OnBeforePluginLoad(const CefString& mime_type, + const CefString& plugin_url, + const CefString& top_origin_url, + CefRefPtr plugin_info, + PluginPolicy* plugin_policy) OVERRIDE { + // Always allow the PDF plugin to load. + if (*plugin_policy != PLUGIN_POLICY_ALLOW && + mime_type == "application/pdf") { + *plugin_policy = PLUGIN_POLICY_ALLOW; + return true; + } + return false; + } + + private: + IMPLEMENT_REFCOUNTING(ClientRequestContextHandler); +}; + +} // namespace + RootWindowManager::RootWindowManager(bool terminate_when_all_windows_closed) : terminate_when_all_windows_closed_(terminate_when_all_windows_closed) { CefRefPtr command_line = @@ -128,11 +154,17 @@ CefRefPtr RootWindowManager::GetRequestContext( CefString(&settings.cache_path) = ss.str(); } - return CefRequestContext::CreateContext(settings, NULL); + return CefRequestContext::CreateContext(settings, + new ClientRequestContextHandler); } // All browsers will share the global request context. - return NULL; + if (!shared_request_context_.get()) { + shared_request_context_ = + CefRequestContext::CreateContext(CefRequestContext::GetGlobalContext(), + new ClientRequestContextHandler); + } + return shared_request_context_; } void RootWindowManager::OnTest(RootWindow* root_window, int test_id) { diff --git a/tests/cefclient/browser/root_window_manager.h b/tests/cefclient/browser/root_window_manager.h index 1d207b508..d2abdd994 100644 --- a/tests/cefclient/browser/root_window_manager.h +++ b/tests/cefclient/browser/root_window_manager.h @@ -80,6 +80,8 @@ class RootWindowManager : public RootWindow::Delegate { // Singleton window used as the temporary parent for popup browsers. TempWindow temp_window_; + CefRefPtr shared_request_context_; + DISALLOW_COPY_AND_ASSIGN(RootWindowManager); }; diff --git a/tests/cefclient/renderer/client_app_renderer.cc b/tests/cefclient/renderer/client_app_renderer.cc index 096e81adc..2b723d4aa 100644 --- a/tests/cefclient/renderer/client_app_renderer.cc +++ b/tests/cefclient/renderer/client_app_renderer.cc @@ -9,12 +9,11 @@ namespace client { ClientAppRenderer::ClientAppRenderer() { + CreateDelegates(delegates_); } void ClientAppRenderer::OnRenderThreadCreated( CefRefPtr extra_info) { - CreateDelegates(delegates_); - DelegateSet::iterator it = delegates_.begin(); for (; it != delegates_.end(); ++it) (*it)->OnRenderThreadCreated(this, extra_info); diff --git a/tests/unittests/client_app_delegates.cc b/tests/unittests/client_app_delegates.cc index 216f36913..27219ecfa 100644 --- a/tests/unittests/client_app_delegates.cc +++ b/tests/unittests/client_app_delegates.cc @@ -19,6 +19,11 @@ void CreateBrowserDelegates(ClientAppBrowser::DelegateSet& delegates) { ClientAppBrowser::DelegateSet& delegates); CreateNavigationBrowserTests(delegates); + // Bring in the plugin tests. + extern void CreatePluginBrowserTests( + ClientAppBrowser::DelegateSet& delegates); + CreatePluginBrowserTests(delegates); + // Bring in the RequestHandler tests. extern void CreateRequestHandlerBrowserTests( ClientAppBrowser::DelegateSet& delegates); diff --git a/tests/unittests/cookie_unittest.cc b/tests/unittests/cookie_unittest.cc index 4c5eb80f9..a23c0cea0 100644 --- a/tests/unittests/cookie_unittest.cc +++ b/tests/unittests/cookie_unittest.cc @@ -900,6 +900,8 @@ class CookieTestJSHandler : public TestHandler { TrackCallback got_load_end2_; TrackCallback got_cookie1_; TrackCallback got_cookie2_; + + IMPLEMENT_REFCOUNTING(CookieTestJSHandler); }; } // namespace @@ -1186,6 +1188,8 @@ class CookieTestSchemeHandler : public TestHandler { TrackCallback got_cookie1_; TrackCallback got_cookie2_; TrackCallback got_cookie3_; + + IMPLEMENT_REFCOUNTING(CookieTestSchemeHandler); }; } // namespace diff --git a/tests/unittests/dialog_unittest.cc b/tests/unittests/dialog_unittest.cc index 36ea45082..c16b1f9ae 100644 --- a/tests/unittests/dialog_unittest.cc +++ b/tests/unittests/dialog_unittest.cc @@ -145,6 +145,8 @@ class DialogTestHandler : public TestHandler { TrackCallback got_onfiledialog_; TrackCallback got_onfiledialogdismissed_; + + IMPLEMENT_REFCOUNTING(DialogTestHandler); }; } // namespace diff --git a/tests/unittests/display_unittest.cc b/tests/unittests/display_unittest.cc index adca4c6ef..606030069 100644 --- a/tests/unittests/display_unittest.cc +++ b/tests/unittests/display_unittest.cc @@ -104,6 +104,8 @@ class TitleTestHandler : public TestHandler { int step_; TrackCallback got_title_[5]; + + IMPLEMENT_REFCOUNTING(TitleTestHandler); }; } // namespace diff --git a/tests/unittests/dom_unittest.cc b/tests/unittests/dom_unittest.cc index 2a21a8a06..0fe376006 100644 --- a/tests/unittests/dom_unittest.cc +++ b/tests/unittests/dom_unittest.cc @@ -309,6 +309,8 @@ class TestDOMHandler : public TestHandler { DOMTestType test_type_; TrackCallback got_message_; TrackCallback got_success_; + + IMPLEMENT_REFCOUNTING(TestDOMHandler); }; } // namespace diff --git a/tests/unittests/download_unittest.cc b/tests/unittests/download_unittest.cc index 958e4df99..eedbf3b72 100644 --- a/tests/unittests/download_unittest.cc +++ b/tests/unittests/download_unittest.cc @@ -256,6 +256,8 @@ class DownloadTestHandler : public TestHandler { TrackCallback got_on_before_download_; TrackCallback got_on_download_updated_; TrackCallback got_full_path_; + + IMPLEMENT_REFCOUNTING(DownloadTestHandler); }; } // namespace diff --git a/tests/unittests/draggable_regions_unittest.cc b/tests/unittests/draggable_regions_unittest.cc index 6e217cf7a..a6c2a75dc 100644 --- a/tests/unittests/draggable_regions_unittest.cc +++ b/tests/unittests/draggable_regions_unittest.cc @@ -158,6 +158,8 @@ class DraggableRegionsTestHandler : public TestHandler { } step_; TrackCallback did_call_on_draggable_regions_changed_; + + IMPLEMENT_REFCOUNTING(DraggableRegionsTestHandler); }; } // namespace diff --git a/tests/unittests/frame_unittest.cc b/tests/unittests/frame_unittest.cc index b4f1caf95..e4d0ac574 100644 --- a/tests/unittests/frame_unittest.cc +++ b/tests/unittests/frame_unittest.cc @@ -557,6 +557,8 @@ class FrameNavTestHandler : public TestHandler { TrackCallback got_destroyed_; scoped_ptr factory_; scoped_ptr expectations_; + + IMPLEMENT_REFCOUNTING(FrameNavTestHandler); }; // Helper for defining frame tests. diff --git a/tests/unittests/geolocation_unittest.cc b/tests/unittests/geolocation_unittest.cc index 43f09b859..f2b1ab3be 100644 --- a/tests/unittests/geolocation_unittest.cc +++ b/tests/unittests/geolocation_unittest.cc @@ -140,6 +140,8 @@ class GeolocationTestHandler : public TestHandler { TrackCallback got_allow_; TrackCallback got_cancel_; TrackCallback got_deny_; + + IMPLEMENT_REFCOUNTING(GeolocationTestHandler); }; } // namespace diff --git a/tests/unittests/jsdialog_unittest.cc b/tests/unittests/jsdialog_unittest.cc index e615b3e1a..85727bef1 100644 --- a/tests/unittests/jsdialog_unittest.cc +++ b/tests/unittests/jsdialog_unittest.cc @@ -175,6 +175,8 @@ class JSDialogTestHandler : public TestHandler { TrackCallback got_onbeforeunloaddialog_; TrackCallback got_onresetdialogstate_; TrackCallback got_onloadend_; + + IMPLEMENT_REFCOUNTING(JSDialogTestHandler); }; } // namespace diff --git a/tests/unittests/life_span_unittest.cc b/tests/unittests/life_span_unittest.cc index 95d3d9473..31c96b566 100644 --- a/tests/unittests/life_span_unittest.cc +++ b/tests/unittests/life_span_unittest.cc @@ -168,6 +168,8 @@ class LifeSpanTestHandler : public RoutingTestHandler { // Forces the window to close (bypasses test conditions). bool executing_delay_close_; + + IMPLEMENT_REFCOUNTING(LifeSpanTestHandler); }; } // namespace diff --git a/tests/unittests/message_router_unittest.cc b/tests/unittests/message_router_unittest.cc index 6dc1de072..e76e7b2dc 100644 --- a/tests/unittests/message_router_unittest.cc +++ b/tests/unittests/message_router_unittest.cc @@ -297,6 +297,8 @@ class MRTestHandler : public TestHandler { private: CefRefPtr message_router_; + + IMPLEMENT_REFCOUNTING(MRTestHandler); }; diff --git a/tests/unittests/navigation_unittest.cc b/tests/unittests/navigation_unittest.cc index 3c6777dee..c120f511e 100644 --- a/tests/unittests/navigation_unittest.cc +++ b/tests/unittests/navigation_unittest.cc @@ -565,6 +565,8 @@ class HistoryNavTestHandler : public TestHandler { TrackCallback got_correct_load_end_url_[NAV_LIST_SIZE()]; TrackCallback got_correct_can_go_back2_[NAV_LIST_SIZE()]; TrackCallback got_correct_can_go_forward2_[NAV_LIST_SIZE()]; + + IMPLEMENT_REFCOUNTING(HistoryNavTestHandler); }; } // namespace @@ -825,6 +827,8 @@ class RedirectTestHandler : public TestHandler { TrackCallback got_nav2_redirect_; TrackCallback got_nav3_redirect_; TrackCallback got_invalid_redirect_; + + IMPLEMENT_REFCOUNTING(RedirectTestHandler); }; } // namespace @@ -1427,6 +1431,8 @@ class OrderNavTestHandler : public TestHandler { OrderNavLoadState state_popup_; bool got_message_; + + IMPLEMENT_REFCOUNTING(OrderNavTestHandler); }; } // namespace @@ -1886,6 +1892,8 @@ class LoadNavTestHandler : public TestHandler { TrackCallback got_load_start_; TrackCallback got_load_end_; TrackCallback got_message_; + + IMPLEMENT_REFCOUNTING(LoadNavTestHandler); }; } // namespace @@ -2111,6 +2119,8 @@ class PopupNavTestHandler : public TestHandler { TrackCallback got_on_before_popup_; TrackCallback got_popup_load_end_; + + IMPLEMENT_REFCOUNTING(PopupNavTestHandler); }; } // namespace @@ -2283,6 +2293,8 @@ class BrowseNavTestHandler : public TestHandler { TrackCallback got_load_error_; TrackCallback got_loading_state_changed_start_; TrackCallback got_loading_state_changed_end_; + + IMPLEMENT_REFCOUNTING(BrowseNavTestHandler); }; } // namespace diff --git a/tests/unittests/plugin_unittest.cc b/tests/unittests/plugin_unittest.cc new file mode 100644 index 000000000..1578563d3 --- /dev/null +++ b/tests/unittests/plugin_unittest.cc @@ -0,0 +1,593 @@ +// 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 this first to avoid type conflicts with CEF headers. +#include "tests/unittests/chromium_includes.h" + +#include "include/base/cef_bind.h" +#include "include/cef_pack_resources.h" +#include "include/cef_resource_bundle.h" +#include "include/wrapper/cef_closure_task.h" +#include "include/wrapper/cef_stream_resource_handler.h" +#include "tests/cefclient/browser/client_app_browser.h" +#include "tests/cefclient/browser/resource_util.h" +#include "tests/unittests/routing_test_handler.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +std::string GetDataResourceAsString(int resource_id) { + void* data; + size_t data_size; + if (CefResourceBundle::GetGlobal()->GetDataResource(resource_id, data, + data_size)) { + return std::string(static_cast(data), data_size); + } + return std::string(); +} + +// Browser-side app delegate. +class PluginBrowserTest : public client::ClientAppBrowser::Delegate { + public: + PluginBrowserTest() {} + + void OnBeforeCommandLineProcessing( + CefRefPtr app, + CefRefPtr command_line) override { + // Enables testing of the plugin placeholder. + // See LoadablePluginPlaceholder::DidFinishLoadingCallback. + command_line->AppendSwitch("enable-plugin-placeholder-testing"); + + // Allow all plugin loading by default. + command_line->AppendSwitchWithValue("plugin-policy", "allow"); + } + + private: + IMPLEMENT_REFCOUNTING(PluginBrowserTest); +}; + +const char kPdfHtmlUrl[] = "http://tests/pdf.html"; +const char kPdfDirectUrl[] = "http://tests/pdf.pdf"; + +// Delay waiting for iframe tests to load the PDF file. +#if defined(OS_WIN) || defined(OS_MACOSX) +const int64 kPdfLoadDelayMs = 2000; +#else +const int64 kPdfLoadDelayMs = 5000; +#endif + +// Browser-side test handler. +class PluginTestHandler : public RoutingTestHandler, + public CefContextMenuHandler { + public: + enum Mode { + // No specified context or handler (implicitly uses the global context). + GLOBAL_DEFAULT, + + // Global context with no handler. + GLOBAL_NO_HANDLER, + + // Global context with handler that allows plugin load. + GLOBAL_ALLOW, + + // Global context with handler that blocks plugin load. Then, load the + // plugin via the context menu. + GLOBAL_BLOCK_LOAD, + + // Global context with handler that blocks plugin load. Then, hide the + // plugin via the context menu. + GLOBAL_BLOCK_HIDE, + + // Global context with handler that disables plugin load. Then, hide the + // plugin via the context menu. + GLOBAL_DISABLE_HIDE, + + // Custom context with no handler. + CUSTOM_NO_HANDLER, + + // Custom context with handler that allows plugin load. + CUSTOM_ALLOW, + + // Custom context with handler that blocks plugin load. Then, load the + // plugin via the context menu. + CUSTOM_BLOCK_LOAD, + + // Custom context with handler that blocks plugin load. Then, hide the + // plugin via the context menu. + CUSTOM_BLOCK_HIDE, + + // Custom context with handler that disables plugin load. Then, hide the + // plugin via the context menu. + CUSTOM_DISABLE_HIDE, + }; + + class RequestContextHandler : public CefRequestContextHandler { + public: + explicit RequestContextHandler(PluginTestHandler* handler) + : handler_(handler) {} + + bool OnBeforePluginLoad(const CefString& mime_type, + const CefString& plugin_url, + const CefString& top_origin_url, + CefRefPtr plugin_info, + PluginPolicy* plugin_policy) override { + const std::string& mime_type_str = mime_type; + if (mime_type_str == "application/pdf") { + if (!handler_->got_on_before_plugin_load_pdf1_) + handler_->got_on_before_plugin_load_pdf1_.yes(); + else if (!handler_->got_on_before_plugin_load_pdf2_) + handler_->got_on_before_plugin_load_pdf2_.yes(); + else + NOTREACHED(); + } else { + NOTREACHED(); + } + + if (handler_->HasAllow()) { + *plugin_policy = PLUGIN_POLICY_ALLOW; + return true; + } else if (handler_->HasBlock()) { + *plugin_policy = PLUGIN_POLICY_BLOCK; + return true; + } else if (handler_->HasDisable()) { + *plugin_policy = PLUGIN_POLICY_DISABLE; + return true; + } + return false; + } + + void Detach() { + handler_ = NULL; + } + + private: + PluginTestHandler* handler_; + + IMPLEMENT_REFCOUNTING(RequestContextHandler); + }; + + PluginTestHandler(Mode mode, + const std::string& url) + : mode_(mode), + url_(url) { + } + + // Has a specified RequestContext but not necessarily a custom handler. + bool HasRequestContext() const { + return mode_ != GLOBAL_DEFAULT; + } + + // Has a specified RequestContext and custom handler. + bool HasRequestContextHandler() const { + return mode_ != GLOBAL_DEFAULT && + mode_ != GLOBAL_NO_HANDLER && + mode_ != CUSTOM_NO_HANDLER; + } + + // Using the global request context, either directly or with a custom handler. + bool HasGlobalRequestContext() const { + return mode_ >= GLOBAL_DEFAULT && mode_ <= GLOBAL_DISABLE_HIDE; + } + + // Should allow the plugin load via the custom handler. + bool HasAllow() const { + return mode_ == GLOBAL_ALLOW || mode_ == CUSTOM_ALLOW; + } + + // Should block the plugin load via the custom handler. + bool HasBlock() const { + return mode_ == GLOBAL_BLOCK_LOAD || + mode_ == GLOBAL_BLOCK_HIDE || + mode_ == CUSTOM_BLOCK_LOAD || + mode_ == CUSTOM_BLOCK_HIDE; + } + + // Should disable the plugin load via the custom handler. + bool HasDisable() const { + return mode_ == GLOBAL_DISABLE_HIDE || mode_ == CUSTOM_DISABLE_HIDE; + } + + // Should load the plugin via the context menu. + bool HasContextLoad() const { + return mode_ == GLOBAL_BLOCK_LOAD || mode_ == CUSTOM_BLOCK_LOAD; + } + + // Should hide the plugin via the context menu. + bool HasContextHide() const { + return mode_ == GLOBAL_BLOCK_HIDE || + mode_ == GLOBAL_DISABLE_HIDE || + mode_ == CUSTOM_BLOCK_HIDE || + mode_ == CUSTOM_DISABLE_HIDE; + } + + std::string GetPluginNode() const { + return "document.getElementsByTagName('embed')[0]"; + } + + void WaitForPlaceholderLoad(CefRefPtr frame) const { + // Waits for the placeholder to load. + // See LoadablePluginPlaceholder::DidFinishLoadingCallback and + // chrome/browser/plugins/plugin_power_saver_browsertest.cc. + const std::string& code = + "var plugin = " + GetPluginNode() +";" + "if (plugin === undefined ||" + " (plugin.nodeName !== 'OBJECT' && plugin.nodeName !== 'EMBED')) {" + " window.testQuery({request:'placeholder_error'});" + "} else {" + " function handleEvent(event) {" + " if (event.data === 'placeholderLoaded') {" + " window.testQuery({request:'placeholder_ready'});" + " plugin.removeEventListener('message', handleEvent);" + " }" + " }" + " plugin.addEventListener('message', handleEvent);" + " if (plugin.hasAttribute('placeholderLoaded')) {" + " window.testQuery({request:'placeholder_ready'});" + " plugin.removeEventListener('message', handleEvent);" + " }" + "}"; + frame->ExecuteJavaScript(code, frame->GetURL(), 0); + } + + void WaitForPlaceholderHide(CefRefPtr frame) const { + // Waits for the placeholder to be hidden (style set to display:none). + // See PluginPlaceholderBase::HidePlugin. + const std::string& code = + "var plugin = " + GetPluginNode() +";" + "var observer = new MutationObserver(function(mutations) {" + " mutations.forEach(function(mutationRecord) {" + " window.testQuery({request:'placeholder_hidden'});" + " observer.disconnect();" + " });" + "});" + "observer.observe(plugin, " + " { attributes : true, attributeFilter : ['style'] });"; + frame->ExecuteJavaScript(code, frame->GetURL(), 0); + } + + void WaitForPluginLoad(CefRefPtr frame) { + if (url_ == kPdfHtmlUrl) { + // PDFScriptingAPI does not work with iframes (the LoadCallback will + // never be executed). Use a timeout instead. + if (got_context_menu_dismissed_) { + // After context menu display. Destroy the test. + CefPostDelayedTask(TID_UI, + base::Bind(&PluginTestHandler::DestroyTest, this), + kPdfLoadDelayMs); + } else { + // Trigger the context menu. + CefPostDelayedTask(TID_UI, + base::Bind(&PluginTestHandler::TriggerContextMenu, this, + frame->GetBrowser()), + kPdfLoadDelayMs); + } + return; + } + + // Wait for the PDF file to load. + // See chrome/browser/pdf/pdf_extension_test_util.cc. + const std::string& scripting_api_js = + GetDataResourceAsString(IDR_PDF_PDF_SCRIPTING_API_JS); + EXPECT_TRUE(!scripting_api_js.empty()); + frame->ExecuteJavaScript(scripting_api_js, frame->GetURL(), 0); + + const std::string& code = + "var scriptingAPI = new PDFScriptingAPI(window, "+ GetPluginNode() +");" + "scriptingAPI.setLoadCallback(function(success) {" + " window.testQuery({request:'plugin_ready'});" + "});"; + frame->ExecuteJavaScript(code, frame->GetURL(), 0); + } + + CefRefPtr GetContextMenuHandler() override { + return this; + } + + void RunTest() override { + CefRefPtr request_context; + + if (HasRequestContext()) { + if (HasRequestContextHandler()) + context_handler_ = new RequestContextHandler(this); + + if (HasGlobalRequestContext()) { + // Use the global request context. + request_context = CefRequestContext::CreateContext( + CefRequestContext::GetGlobalContext(), context_handler_.get()); + } else { + // Create the request context that will use an in-memory cache. + CefRequestContextSettings settings; + request_context = CefRequestContext::CreateContext( + settings, context_handler_.get()); + } + } + + // Create the browser. + CreateBrowser(url_, request_context); + + // Time out the test after a reasonable period of time. + SetTestTimeout(5000 + kPdfLoadDelayMs); + } + + CefRefPtr GetResourceHandler( + CefRefPtr browser, + CefRefPtr frame, + CefRefPtr request) override { + const std::string& url = request->GetURL(); + if (url == kPdfHtmlUrl) { + CefRefPtr stream = + client::GetBinaryResourceReader("pdf.html"); + return new CefStreamResourceHandler("text/html", stream); + } else if (url == kPdfDirectUrl) { + CefRefPtr stream = + client::GetBinaryResourceReader("pdf.pdf"); + return new CefStreamResourceHandler("application/pdf", stream); + } + + NOTREACHED(); + return NULL; + } + + void OnLoadEnd(CefRefPtr browser, + CefRefPtr frame, + int httpStatusCode) override { + bool is_pdf1 = false; + const std::string& url = frame->GetURL(); + if (url == kPdfHtmlUrl) { + if (!got_on_load_end_html_) + got_on_load_end_html_.yes(); + else + NOTREACHED(); + } else if (url == kPdfDirectUrl) { + if (!got_on_load_end_pdf1_) { + got_on_load_end_pdf1_.yes(); + is_pdf1 = true; + } else if (!got_on_load_end_pdf2_) { + got_on_load_end_pdf2_.yes(); + } else { + NOTREACHED(); + } + } else { + NOTREACHED(); + } + + if (HasBlock() || HasDisable()) { + if (is_pdf1) { + // Wait for the plugin placeholder for the first PDF file to load. The + // test will continue from OnQuery. + WaitForPlaceholderLoad(frame); + } + } else if (is_pdf1) { + // Wait for the first PDF file to load. + WaitForPluginLoad(frame); + } + } + + bool OnQuery(CefRefPtr browser, + CefRefPtr frame, + int64 query_id, + const CefString& request, + bool persistent, + CefRefPtr callback) override { + if (request == "placeholder_ready") { + EXPECT_FALSE(got_placeholder_ready_); + got_placeholder_ready_.yes(); + + // The plugin placeholder has loaded. + CefPostTask(TID_UI, + base::Bind(&PluginTestHandler::TriggerContextMenu, this, browser)); + } else if (request == "placeholder_hidden") { + EXPECT_TRUE(got_placeholder_ready_); + EXPECT_FALSE(got_placeholder_hidden_); + got_placeholder_hidden_.yes(); + + // The plugin placeholder has been hidden. + CefPostTask(TID_UI, + base::Bind(&PluginTestHandler::DestroyTest, this)); + } else if (request == "plugin_ready") { + EXPECT_FALSE(got_plugin_ready_); + got_plugin_ready_.yes(); + + // The plugin has loaded the PDF file. + if (got_context_menu_dismissed_) { + // After context menu display. Destroy the test. + CefPostTask(TID_UI, + base::Bind(&PluginTestHandler::DestroyTest, this)); + } else { + // Trigger the context menu. + CefPostTask(TID_UI, + base::Bind(&PluginTestHandler::TriggerContextMenu, this, browser)); + } + } else { + NOTREACHED(); + } + + return true; + } + + void TriggerContextMenu(CefRefPtr browser) { + CefMouseEvent mouse_event; + + // Somewhere in the first plugin. + mouse_event.x = 100; + mouse_event.y = 100; + + // Send right-click mouse down and mouse up to tigger context menu. + browser->GetHost()->SendMouseClickEvent(mouse_event, MBT_RIGHT, false, 0); + browser->GetHost()->SendMouseClickEvent(mouse_event, MBT_RIGHT, true, 0); + } + + bool RunContextMenu(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr params, + CefRefPtr model, + CefRefPtr callback) override { + EXPECT_FALSE(got_run_context_menu_); + got_run_context_menu_.yes(); + + if (HasContextLoad() || HasContextHide()) { + // Should have 4 elements -- plugin name, separator, run, hide. + EXPECT_EQ(4, model->GetCount()); + + int command_id; + if (HasContextLoad()) { + // Execute the run command. + command_id = model->GetCommandIdAt(2); + } else { + // Wait for the plugin to be hidden. + WaitForPlaceholderHide(frame); + + // Execute the hide command. + command_id = model->GetCommandIdAt(3); + } + + EXPECT_GE(command_id, MENU_ID_CUSTOM_FIRST); + EXPECT_LE(command_id, MENU_ID_CUSTOM_LAST); + + callback->Continue(command_id, static_cast(0)); + } else { + // Do nothing with the context menu. + callback->Cancel(); + } + return true; + } + + void OnContextMenuDismissed(CefRefPtr browser, + CefRefPtr frame) { + EXPECT_FALSE(got_context_menu_dismissed_); + got_context_menu_dismissed_.yes(); + + if (HasContextHide()) { + // Nothing to do here. The test will continue from OnQuery. + return; + } + + if (HasContextLoad()) { + // Wait for the PDF plugin to load. + WaitForPluginLoad(frame); + return; + } + + CefPostTask(TID_UI, base::Bind(&PluginTestHandler::DestroyTest, this)); + } + + void DestroyTest() override { + if (context_handler_.get()) { + context_handler_->Detach(); + context_handler_ = NULL; + } + + if (HasBlock() || HasDisable()) + EXPECT_TRUE(got_placeholder_ready_); + else + EXPECT_FALSE(got_placeholder_ready_); + + if (HasContextHide()) { + EXPECT_TRUE(got_placeholder_hidden_); + EXPECT_FALSE(got_plugin_ready_); + } else { + EXPECT_FALSE(got_placeholder_hidden_); + + if (url_ == kPdfDirectUrl) + EXPECT_TRUE(got_plugin_ready_); + else + EXPECT_FALSE(got_plugin_ready_); + } + + EXPECT_TRUE(got_run_context_menu_); + EXPECT_TRUE(got_context_menu_dismissed_); + + if (url_ == kPdfHtmlUrl) { + // The HTML file will load the PDF twice in iframes. + EXPECT_TRUE(got_on_load_end_html_); + EXPECT_TRUE(got_on_load_end_pdf1_); + EXPECT_TRUE(got_on_load_end_pdf2_); + + if (HasRequestContextHandler()) { + EXPECT_TRUE(got_on_before_plugin_load_pdf1_); + EXPECT_TRUE(got_on_before_plugin_load_pdf2_); + } + } else if (url_ == kPdfDirectUrl) { + // Load the PDF file directly. + EXPECT_FALSE(got_on_load_end_html_); + EXPECT_TRUE(got_on_load_end_pdf1_); + EXPECT_FALSE(got_on_load_end_pdf2_); + + if (HasRequestContextHandler()) { + EXPECT_TRUE(got_on_before_plugin_load_pdf1_); + EXPECT_FALSE(got_on_before_plugin_load_pdf2_); + } + } else { + NOTREACHED(); + } + + if (!HasRequestContextHandler()) { + EXPECT_FALSE(got_on_before_plugin_load_pdf1_); + EXPECT_FALSE(got_on_before_plugin_load_pdf2_); + } + + TestHandler::DestroyTest(); + } + + const Mode mode_; + const std::string url_; + + TrackCallback got_on_before_plugin_load_pdf1_; + TrackCallback got_on_before_plugin_load_pdf2_; + TrackCallback got_on_load_end_html_; + TrackCallback got_on_load_end_pdf1_; + TrackCallback got_on_load_end_pdf2_; + TrackCallback got_placeholder_ready_; + TrackCallback got_placeholder_hidden_; + TrackCallback got_plugin_ready_; + TrackCallback got_run_context_menu_; + TrackCallback got_context_menu_dismissed_; + + CefRefPtr context_handler_; + + IMPLEMENT_REFCOUNTING(PluginTestHandler); +}; + +} // namespace + +#define RUN_TEST(name, type, url) \ + TEST(PluginTest, name) { \ + CefRefPtr handler = \ + new PluginTestHandler(PluginTestHandler::type, url); \ + handler->ExecuteTest(); \ + ReleaseAndWaitForDestructor(handler); \ + } + +RUN_TEST(GlobalDefaultPdfDirect, GLOBAL_DEFAULT, kPdfDirectUrl); +RUN_TEST(GlobalDefaultPdfHtml, GLOBAL_DEFAULT, kPdfHtmlUrl); + +RUN_TEST(GlobalNoHandlerPdfDirect, GLOBAL_NO_HANDLER, kPdfDirectUrl); +RUN_TEST(GlobalNoHandlerPdfHtml, GLOBAL_NO_HANDLER, kPdfHtmlUrl); +RUN_TEST(GlobalAllowPdfDirect, GLOBAL_ALLOW, kPdfDirectUrl); +RUN_TEST(GlobalAllowPdfHtml, GLOBAL_ALLOW, kPdfHtmlUrl); +RUN_TEST(GlobalBlockThenLoadPdfDirect, GLOBAL_BLOCK_LOAD, kPdfDirectUrl); +RUN_TEST(GlobalBlockThenLoadPdfHtml, GLOBAL_BLOCK_LOAD, kPdfHtmlUrl); +RUN_TEST(GlobalBlockThenHidePdfDirect, GLOBAL_BLOCK_HIDE, kPdfDirectUrl); +RUN_TEST(GlobalBlockThenHidePdfHtml, GLOBAL_BLOCK_HIDE, kPdfHtmlUrl); +RUN_TEST(GlobalDisableThenHidePdfDirect, GLOBAL_DISABLE_HIDE, kPdfDirectUrl); +RUN_TEST(GlobalDisableThenHidePdfHtml, GLOBAL_DISABLE_HIDE, kPdfHtmlUrl); + +RUN_TEST(CustomNoHandlerPdfDirect, CUSTOM_NO_HANDLER, kPdfDirectUrl); +RUN_TEST(CustomNoHandlerPdfHtml, CUSTOM_NO_HANDLER, kPdfHtmlUrl); +RUN_TEST(CustomAllowPdfDirect, CUSTOM_ALLOW, kPdfDirectUrl); +RUN_TEST(CustomAllowPdfHtml, CUSTOM_ALLOW, kPdfHtmlUrl); +RUN_TEST(CustomBlockThenLoadPdfDirect, CUSTOM_BLOCK_LOAD, kPdfDirectUrl); +RUN_TEST(CustomBlockThenLoadPdfHtml, CUSTOM_BLOCK_LOAD, kPdfHtmlUrl); +RUN_TEST(CustomBlockThenHidePdfDirect, CUSTOM_BLOCK_HIDE, kPdfDirectUrl); +RUN_TEST(CustomBlockThenHidePdfHtml, CUSTOM_BLOCK_HIDE, kPdfHtmlUrl); +RUN_TEST(CustomDisableThenHidePdfDirect, CUSTOM_DISABLE_HIDE, kPdfDirectUrl); +RUN_TEST(CustomDisableThenHidePdfHtml, CUSTOM_DISABLE_HIDE, kPdfHtmlUrl); + + +// Entry point for creating plugin browser test objects. +// Called from client_app_delegates.cc. +void CreatePluginBrowserTests( + client::ClientAppBrowser::DelegateSet& delegates) { + delegates.insert(new PluginBrowserTest); +} diff --git a/tests/unittests/process_message_unittest.cc b/tests/unittests/process_message_unittest.cc index 9e0f7192f..861305c79 100644 --- a/tests/unittests/process_message_unittest.cc +++ b/tests/unittests/process_message_unittest.cc @@ -116,6 +116,8 @@ class SendRecvTestHandler : public TestHandler { CefRefPtr message_; TrackCallback got_message_; + + IMPLEMENT_REFCOUNTING(SendRecvTestHandler); }; } // namespace diff --git a/tests/unittests/request_context_unittest.cc b/tests/unittests/request_context_unittest.cc index 5a23e67f4..513b4979a 100644 --- a/tests/unittests/request_context_unittest.cc +++ b/tests/unittests/request_context_unittest.cc @@ -346,6 +346,8 @@ class CookieTestHandler : public TestHandler { TrackCallback got_get_cookie_manager_; TrackCallback got_cookie_; + + IMPLEMENT_REFCOUNTING(CookieTestHandler); }; } // namespace @@ -587,6 +589,8 @@ class PopupTestHandler : public TestHandler { TrackCallback got_load_end2_; TrackCallback got_cookie1_; TrackCallback got_cookie2_; + + IMPLEMENT_REFCOUNTING(PopupTestHandler); }; } // namespace diff --git a/tests/unittests/request_handler_unittest.cc b/tests/unittests/request_handler_unittest.cc index 6f0729868..1e8c74048 100644 --- a/tests/unittests/request_handler_unittest.cc +++ b/tests/unittests/request_handler_unittest.cc @@ -367,6 +367,8 @@ class NetNotifyTestHandler : public TestHandler { TrackCallback got_process_message2_; TrackCallback got_before_browse2_will_delay_; TrackCallback got_before_browse2_delayed_; + + IMPLEMENT_REFCOUNTING(NetNotifyTestHandler); }; // Renderer side. @@ -897,6 +899,8 @@ class ResourceResponseTest : public TestHandler { uint64 main_request_id_; uint64 sub_request_id_; scoped_ptr resource_test_; + + IMPLEMENT_REFCOUNTING(ResourceResponseTest); }; } // namespace @@ -1050,6 +1054,8 @@ class BeforeResourceLoadTest : public TestHandler { TrackCallback got_before_resource_load2_; TrackCallback got_load_end_; TrackCallback got_load_error_; + + IMPLEMENT_REFCOUNTING(BeforeResourceLoadTest); }; } // namespace diff --git a/tests/unittests/request_unittest.cc b/tests/unittests/request_unittest.cc index 414ace081..08b0e0ca7 100644 --- a/tests/unittests/request_unittest.cc +++ b/tests/unittests/request_unittest.cc @@ -201,6 +201,8 @@ class RequestSendRecvTestHandler : public TestHandler { TrackCallback got_before_resource_load_; TrackCallback got_resource_handler_; + + IMPLEMENT_REFCOUNTING(RequestSendRecvTestHandler); }; } // namespace @@ -537,6 +539,8 @@ class TypeTestHandler : public TestHandler { bool completed_browser_side_; bool completed_render_side_; bool destroyed_; + + IMPLEMENT_REFCOUNTING(TypeTestHandler); }; } // namespace diff --git a/tests/unittests/resource_manager_unittest.cc b/tests/unittests/resource_manager_unittest.cc index b68a8defb..425727751 100644 --- a/tests/unittests/resource_manager_unittest.cc +++ b/tests/unittests/resource_manager_unittest.cc @@ -158,6 +158,8 @@ class ResourceManagerTestHandler : public RoutingTestHandler { State* state_; size_t current_url_; + + IMPLEMENT_REFCOUNTING(ResourceManagerTestHandler); }; } // namespace diff --git a/tests/unittests/scheme_handler_unittest.cc b/tests/unittests/scheme_handler_unittest.cc index 9ba5dd61b..58eb7cd3f 100644 --- a/tests/unittests/scheme_handler_unittest.cc +++ b/tests/unittests/scheme_handler_unittest.cc @@ -173,6 +173,8 @@ class TestSchemeHandler : public TestHandler { protected: TestResults* test_results_; + + IMPLEMENT_REFCOUNTING(TestSchemeHandler); }; class ClientSchemeHandler : public CefResourceHandler { diff --git a/tests/unittests/stream_resource_handler_unittest.cc b/tests/unittests/stream_resource_handler_unittest.cc index d46956328..42c3a2306 100644 --- a/tests/unittests/stream_resource_handler_unittest.cc +++ b/tests/unittests/stream_resource_handler_unittest.cc @@ -170,6 +170,8 @@ class ReadTestHandler : public RoutingTestHandler { TrackCallback got_resource_handler_; TrackCallback got_on_query_; TrackCallback got_on_loading_state_change_done_; + + IMPLEMENT_REFCOUNTING(ReadTestHandler); }; } // namespace diff --git a/tests/unittests/test_handler.h b/tests/unittests/test_handler.h index f2ad37fe0..7d53861eb 100644 --- a/tests/unittests/test_handler.h +++ b/tests/unittests/test_handler.h @@ -288,9 +288,6 @@ class TestHandler : public CefClient, // Used to track the number of currently existing browser windows. static int browser_count_; - // Include the default reference counting implementation. - IMPLEMENT_REFCOUNTING(TestHandler); - DISALLOW_COPY_AND_ASSIGN(TestHandler); }; diff --git a/tests/unittests/urlrequest_unittest.cc b/tests/unittests/urlrequest_unittest.cc index 375f6e4b0..c77a45621 100644 --- a/tests/unittests/urlrequest_unittest.cc +++ b/tests/unittests/urlrequest_unittest.cc @@ -1147,6 +1147,8 @@ class RequestTestHandler : public TestHandler, // Only used when the test runs in the render process. TrackCallback got_message_; TrackCallback got_success_; + + IMPLEMENT_REFCOUNTING(RequestTestHandler); }; } // namespace diff --git a/tests/unittests/v8_unittest.cc b/tests/unittests/v8_unittest.cc index 64828e2c0..705283634 100644 --- a/tests/unittests/v8_unittest.cc +++ b/tests/unittests/v8_unittest.cc @@ -2094,6 +2094,8 @@ class V8TestHandler : public TestHandler { const char* test_url_; TrackCallback got_message_; TrackCallback got_success_; + + IMPLEMENT_REFCOUNTING(V8TestHandler); }; } // namespace diff --git a/tools/cef_parser.py b/tools/cef_parser.py index 753d03d2b..e462d82bc 100644 --- a/tools/cef_parser.py +++ b/tools/cef_parser.py @@ -397,6 +397,7 @@ _simpletypes = { 'char* const': ['char* const', 'NULL'], 'cef_color_t': ['cef_color_t', '0'], 'cef_json_parser_error_t': ['cef_json_parser_error_t', 'JSON_NO_ERROR'], + 'cef_plugin_policy_t': ['cef_plugin_policy_t', 'PLUGIN_POLICY_ALLOW'], 'CefCursorHandle' : ['cef_cursor_handle_t', 'kNullCursorHandle'], 'CefEventHandle' : ['cef_event_handle_t', 'kNullEventHandle'], 'CefWindowHandle' : ['cef_window_handle_t', 'kNullWindowHandle'],