Add CefFrameHandler callbacks for tracking CefFrame lifespan (see issue #2421)

See the new cef_frame_handler.h for complete usage documentation.

This change includes the following related enhancements:
- The newly added CefBrowser::IsValid method will return false (in the browser
  process) after CefLifeSpanHandler::OnBeforeClose is called.
- CefBrowser::GetMainFrame will return a valid object (in the browser process)
  until after CefLifeSpanHandler::OnBeforeClose is called.
- The main frame object will change during cross-origin navigation or
  re-navigation after renderer process termination. During that time,
  GetMainFrame will return the new/pending frame (in the browser process) and
  any messages that arrive for the new/pending frame will be correctly
  attributed in OnProcessMessageReceived.
- Commands to be executed in the renderer process that may fail during early
  frame initialization (ExecuteJavaScript, LoadRequest, etc.) will now be
  queued until after the JavaScript context for the frame has been created.
- Logging has been added for any commands that are dropped because they arrived
  after frame detachment.
This commit is contained in:
Marshall Greenblatt 2021-05-20 21:42:58 -04:00
parent 5ddd26e483
commit e411b513be
42 changed files with 3031 additions and 247 deletions

View File

@ -8,7 +8,7 @@
# by hand. See the translator.README.txt file in the tools directory for
# more information.
#
# $hash=f1877c7a493342351e284cb6c14e6f223461facb$
# $hash=d723a9f6637cec523b158a6750d3a64698b407c3$
#
{
@ -40,6 +40,7 @@
'include/cef_find_handler.h',
'include/cef_focus_handler.h',
'include/cef_frame.h',
'include/cef_frame_handler.h',
'include/cef_image.h',
'include/cef_jsdialog_handler.h',
'include/cef_keyboard_handler.h',
@ -137,6 +138,7 @@
'include/capi/cef_find_handler_capi.h',
'include/capi/cef_focus_handler_capi.h',
'include/capi/cef_frame_capi.h',
'include/capi/cef_frame_handler_capi.h',
'include/capi/cef_image_capi.h',
'include/capi/cef_jsdialog_handler_capi.h',
'include/capi/cef_keyboard_handler_capi.h',
@ -300,6 +302,8 @@
'libcef_dll/ctocpp/focus_handler_ctocpp.h',
'libcef_dll/cpptoc/frame_cpptoc.cc',
'libcef_dll/cpptoc/frame_cpptoc.h',
'libcef_dll/ctocpp/frame_handler_ctocpp.cc',
'libcef_dll/ctocpp/frame_handler_ctocpp.h',
'libcef_dll/cpptoc/get_extension_resource_callback_cpptoc.cc',
'libcef_dll/cpptoc/get_extension_resource_callback_cpptoc.h',
'libcef_dll/cpptoc/image_cpptoc.cc',
@ -610,6 +614,8 @@
'libcef_dll/cpptoc/focus_handler_cpptoc.h',
'libcef_dll/ctocpp/frame_ctocpp.cc',
'libcef_dll/ctocpp/frame_ctocpp.h',
'libcef_dll/cpptoc/frame_handler_cpptoc.cc',
'libcef_dll/cpptoc/frame_handler_cpptoc.h',
'libcef_dll/ctocpp/get_extension_resource_callback_ctocpp.cc',
'libcef_dll/ctocpp/get_extension_resource_callback_ctocpp.h',
'libcef_dll/ctocpp/image_ctocpp.cc',

View File

@ -471,6 +471,7 @@
'tests/ceftests/extensions/extension_test_handler.h',
'tests/ceftests/extensions/view_unittest.cc',
'tests/ceftests/file_util_unittest.cc',
'tests/ceftests/frame_handler_unittest.cc',
'tests/ceftests/frame_unittest.cc',
'tests/ceftests/image_unittest.cc',
'tests/ceftests/image_util.cc',

View File

@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=09b6ebd4116e983b4af634f1efa17b326a3fc517$
// $hash=bb01bd8418e5fb715a7a6bd53e962e11a0d04993$
//
#ifndef CEF_INCLUDE_CAPI_CEF_BROWSER_CAPI_H_
@ -57,10 +57,10 @@ struct _cef_browser_host_t;
struct _cef_client_t;
///
// Structure used to represent a browser window. When used in the browser
// process the functions of this structure may be called on any thread unless
// otherwise indicated in the comments. When used in the render process the
// functions of this structure may only be called on the main thread.
// Structure used to represent a browser. When used in the browser process the
// functions of this structure may be called on any thread unless otherwise
// indicated in the comments. When used in the render process the functions of
// this structure may only be called on the main thread.
///
typedef struct _cef_browser_t {
///
@ -68,6 +68,12 @@ typedef struct _cef_browser_t {
///
cef_base_ref_counted_t base;
///
// True if this object is currently valid. This will return false (0) after
// cef_life_span_handler_t::OnBeforeClose is called.
///
int(CEF_CALLBACK* is_valid)(struct _cef_browser_t* self);
///
// Returns the browser host object. This function can only be called in the
// browser process.
@ -129,7 +135,7 @@ typedef struct _cef_browser_t {
struct _cef_browser_t* that);
///
// Returns true (1) if the window is a popup window.
// Returns true (1) if the browser is a popup.
///
int(CEF_CALLBACK* is_popup)(struct _cef_browser_t* self);
@ -139,13 +145,17 @@ typedef struct _cef_browser_t {
int(CEF_CALLBACK* has_document)(struct _cef_browser_t* self);
///
// Returns the main (top-level) frame for the browser window.
// Returns the main (top-level) frame for the browser. In the browser process
// this will return a valid object until after
// cef_life_span_handler_t::OnBeforeClose is called. The main frame object
// will change during cross-origin navigation or re-navigation after renderer
// process termination (due to crashes, etc).
///
struct _cef_frame_t*(CEF_CALLBACK* get_main_frame)(
struct _cef_browser_t* self);
///
// Returns the focused frame for the browser window.
// Returns the focused frame for the browser.
///
struct _cef_frame_t*(CEF_CALLBACK* get_focused_frame)(
struct _cef_browser_t* self);
@ -274,10 +284,10 @@ typedef struct _cef_download_image_callback_t {
} cef_download_image_callback_t;
///
// Structure used to represent the browser process aspects of a browser window.
// The functions of this structure can only be called in the browser process.
// They may be called on any thread in that process unless otherwise indicated
// in the comments.
// Structure used to represent the browser process aspects of a browser. The
// functions of this structure can only be called in the browser process. They
// may be called on any thread in that process unless otherwise indicated in the
// comments.
///
typedef struct _cef_browser_host_t {
///
@ -306,11 +316,12 @@ typedef struct _cef_browser_host_t {
///
// Helper for closing a browser. Call this function from the top-level window
// close handler. Internally this calls CloseBrowser(false (0)) if the close
// has not yet been initiated. This function returns false (0) while the close
// is pending and true (1) after the close has completed. See close_browser()
// and cef_life_span_handler_t::do_close() documentation for additional usage
// information. This function must be called on the browser process UI thread.
// close handler (if any). Internally this calls CloseBrowser(false (0)) if
// the close has not yet been initiated. This function returns false (0) while
// the close is pending and true (1) after the close has completed. See
// close_browser() and cef_life_span_handler_t::do_close() documentation for
// additional usage information. This function must be called on the browser
// process UI thread.
///
int(CEF_CALLBACK* try_close_browser)(struct _cef_browser_host_t* self);
@ -320,18 +331,19 @@ typedef struct _cef_browser_host_t {
void(CEF_CALLBACK* set_focus)(struct _cef_browser_host_t* self, int focus);
///
// Retrieve the window handle for this browser. If this browser is wrapped in
// a cef_browser_view_t this function should be called on the browser process
// UI thread and it will return the handle for the top-level native window.
// Retrieve the window handle (if any) for this browser. If this browser is
// wrapped in a cef_browser_view_t this function should be called on the
// browser process UI thread and it will return the handle for the top-level
// native window.
///
cef_window_handle_t(CEF_CALLBACK* get_window_handle)(
struct _cef_browser_host_t* self);
///
// Retrieve the window handle of the browser that opened this browser. Will
// return NULL for non-popup windows or if this browser is wrapped in a
// cef_browser_view_t. This function can be used in combination with custom
// handling of modal windows.
// Retrieve the window handle (if any) of the browser that opened this
// browser. Will return NULL for non-popup browsers or if this browser is
// wrapped in a cef_browser_view_t. This function can be used in combination
// with custom handling of modal windows.
///
cef_window_handle_t(CEF_CALLBACK* get_opener_window_handle)(
struct _cef_browser_host_t* self);
@ -909,9 +921,9 @@ typedef struct _cef_browser_host_t {
} cef_browser_host_t;
///
// Create a new browser window using the window parameters specified by
// |windowInfo|. All values will be copied internally and the actual window will
// be created on the UI thread. If |request_context| is NULL the global request
// Create a new browser using the window parameters specified by |windowInfo|.
// All values will be copied internally and the actual window (if any) will be
// created on the UI thread. If |request_context| is NULL the global request
// context will be used. This function can be called on any browser process
// thread and will not block. The optional |extra_info| parameter provides an
// opportunity to specify extra information specific to the created browser that
@ -927,11 +939,11 @@ CEF_EXPORT int cef_browser_host_create_browser(
struct _cef_request_context_t* request_context);
///
// Create a new browser window using the window parameters specified by
// |windowInfo|. If |request_context| is NULL the global request context will be
// used. This function can only be called on the browser process UI thread. The
// optional |extra_info| parameter provides an opportunity to specify extra
// information specific to the created browser that will be passed to
// Create a new browser using the window parameters specified by |windowInfo|.
// If |request_context| is NULL the global request context will be used. This
// function can only be called on the browser process UI thread. The optional
// |extra_info| parameter provides an opportunity to specify extra information
// specific to the created browser that will be passed to
// cef_render_process_handler_t::on_browser_created() in the render process.
///
CEF_EXPORT cef_browser_t* cef_browser_host_create_browser_sync(

View File

@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=547d03e9514a30b62d5aa11834deab87052dd6bd$
// $hash=845a1d1dda63a06f4ae33ed39acfd2599b46a885$
//
#ifndef CEF_INCLUDE_CAPI_CEF_CLIENT_CAPI_H_
@ -49,6 +49,7 @@
#include "include/capi/cef_drag_handler_capi.h"
#include "include/capi/cef_find_handler_capi.h"
#include "include/capi/cef_focus_handler_capi.h"
#include "include/capi/cef_frame_handler_capi.h"
#include "include/capi/cef_jsdialog_handler_capi.h"
#include "include/capi/cef_keyboard_handler_capi.h"
#include "include/capi/cef_life_span_handler_capi.h"
@ -122,6 +123,14 @@ typedef struct _cef_client_t {
struct _cef_focus_handler_t*(CEF_CALLBACK* get_focus_handler)(
struct _cef_client_t* self);
///
// Return the handler for events related to cef_frame_t lifespan. This
// function will be called once during cef_browser_t creation and the result
// will be cached for performance reasons.
///
struct _cef_frame_handler_t*(CEF_CALLBACK* get_frame_handler)(
struct _cef_client_t* self);
///
// Return the handler for JavaScript dialogs. If no handler is provided the
// default implementation will be used.

View File

@ -0,0 +1,191 @@
// Copyright (c) 2021 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.
//
// $hash=503984bf98aa52ff67ce52f26a560bbb1d4439bc$
//
#ifndef CEF_INCLUDE_CAPI_CEF_FRAME_HANDLER_CAPI_H_
#define CEF_INCLUDE_CAPI_CEF_FRAME_HANDLER_CAPI_H_
#pragma once
#include "include/capi/cef_base_capi.h"
#include "include/capi/cef_browser_capi.h"
#include "include/capi/cef_frame_capi.h"
#ifdef __cplusplus
extern "C" {
#endif
///
// Implement this structure to handle events related to cef_frame_t life span.
// The order of callbacks is:
//
// (1) During initial cef_browser_host_t creation and navigation of the main
// frame: - cef_frame_handler_t::OnFrameCreated => The initial main frame object
// has been
// created. Any commands will be queued until the frame is attached.
// - cef_frame_handler_t::OnMainFrameChanged => The initial main frame object
// has
// been assigned to the browser.
// - cef_life_span_handler_t::OnAfterCreated => The browser is now valid and can
// be
// used.
// - cef_frame_handler_t::OnFrameAttached => The initial main frame object is
// now
// connected to its peer in the renderer process. Commands can be routed.
//
// (2) During further cef_browser_host_t navigation/loading of the main frame
// and/or sub-frames: - cef_frame_handler_t::OnFrameCreated => A new main frame
// or sub-frame object has
// been created. Any commands will be queued until the frame is attached.
// - cef_frame_handler_t::OnFrameAttached => A new main frame or sub-frame
// object is
// now connected to its peer in the renderer process. Commands can be routed.
// - cef_frame_handler_t::OnFrameDetached => An existing main frame or sub-frame
// object has lost its connection to the renderer process. If multiple objects
// are detached at the same time then notifications will be sent for any
// sub-frame objects before the main frame object. Commands can no longer be
// routed and will be discarded.
// - cef_frame_handler_t::OnMainFrameChanged => A new main frame object has been
// assigned to the browser. This will only occur with cross-origin navigation
// or re-navigation after renderer process termination (due to crashes, etc).
//
// (3) During final cef_browser_host_t destruction of the main frame: -
// cef_frame_handler_t::OnFrameDetached => Any sub-frame objects have lost their
// connection to the renderer process. Commands can no longer be routed and
// will be discarded.
// - cef_life_span_handler_t::OnBeforeClose => The browser has been destroyed. -
// cef_frame_handler_t::OnFrameDetached => The main frame object have lost its
// connection to the renderer process. Notifications will be sent for any
// sub-frame objects before the main frame object. Commands can no longer be
// routed and will be discarded.
// - cef_frame_handler_t::OnMainFrameChanged => The final main frame object has
// been
// removed from the browser.
//
// Cross-origin navigation and/or loading receives special handling.
//
// When the main frame navigates to a different origin the OnMainFrameChanged
// callback (2) will be executed with the old and new main frame objects.
//
// When a new sub-frame is loaded in, or an existing sub-frame is navigated to,
// a different origin from the parent frame, a temporary sub-frame object will
// first be created in the parent's renderer process. That temporary sub-frame
// will then be discarded after the real cross-origin sub-frame is created in
// the new/target renderer process. The client will receive cross-origin
// navigation callbacks (2) for the transition from the temporary sub-frame to
// the real sub-frame. The temporary sub-frame will not recieve or execute
// commands during this transitional period (any sent commands will be
// discarded).
//
// When a new popup browser is created in a different origin from the parent
// browser, a temporary main frame object for the popup will first be created in
// the parent's renderer process. That temporary main frame will then be
// discarded after the real cross-origin main frame is created in the new/target
// renderer process. The client will recieve creation and initial navigation
// callbacks (1) for the temporary main frame, followed by cross-origin
// navigation callbacks (2) for the transition from the temporary main frame to
// the real main frame. The temporary main frame may receive and execute
// commands during this transitional period (any sent commands may be executed,
// but the behavior is potentially undesirable since they execute in the parent
// browser's renderer process and not the new/target renderer process).
//
// Callbacks will not be executed for placeholders that may be created during
// pre-commit navigation for sub-frames that do not yet exist in the renderer
// process. Placeholders will have cef_frame_t::get_identifier() == -4.
//
// The functions of this structure will be called on the UI thread unless
// otherwise indicated.
///
typedef struct _cef_frame_handler_t {
///
// Base structure.
///
cef_base_ref_counted_t base;
///
// Called when a new frame is created. This will be the first notification
// that references |frame|. Any commands that require transport to the
// associated renderer process (LoadRequest, SendProcessMessage, GetSource,
// etc.) will be queued until OnFrameAttached is called for |frame|.
///
void(CEF_CALLBACK* on_frame_created)(struct _cef_frame_handler_t* self,
struct _cef_browser_t* browser,
struct _cef_frame_t* frame);
///
// Called when a frame can begin routing commands to/from the associated
// renderer process. Any commands that were queued have now been dispatched.
///
void(CEF_CALLBACK* on_frame_attached)(struct _cef_frame_handler_t* self,
struct _cef_browser_t* browser,
struct _cef_frame_t* frame);
///
// Called when a frame loses its connection to the renderer process and will
// be destroyed. Any pending or future commands will be discarded and
// cef_frame_t::is_valid() will now return false (0) for |frame|. If called
// after cef_life_span_handler_t::on_before_close() during browser destruction
// then cef_browser_t::is_valid() will return false (0) for |browser|.
///
void(CEF_CALLBACK* on_frame_detached)(struct _cef_frame_handler_t* self,
struct _cef_browser_t* browser,
struct _cef_frame_t* frame);
///
// Called when the main frame changes due to (a) initial browser creation, (b)
// final browser destruction, (c) cross-origin navigation or (d) re-navigation
// after renderer process termination (due to crashes, etc). |old_frame| will
// be NULL and |new_frame| will be non-NULL when a main frame is assigned to
// |browser| for the first time. |old_frame| will be non-NULL and |new_frame|
// will be NULL and when a main frame is removed from |browser| for the last
// time. Both |old_frame| and |new_frame| will be non-NULL for cross-origin
// navigations or re-navigation after renderer process termination. This
// function will be called after on_frame_created() for |new_frame| and/or
// after on_frame_detached() for |old_frame|. If called after
// cef_life_span_handler_t::on_before_close() during browser destruction then
// cef_browser_t::is_valid() will return false (0) for |browser|.
///
void(CEF_CALLBACK* on_main_frame_changed)(struct _cef_frame_handler_t* self,
struct _cef_browser_t* browser,
struct _cef_frame_t* old_frame,
struct _cef_frame_t* new_frame);
} cef_frame_handler_t;
#ifdef __cplusplus
}
#endif
#endif // CEF_INCLUDE_CAPI_CEF_FRAME_HANDLER_CAPI_H_

View File

@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=d7521ac4f73dabd876344400a165d15954c770b0$
// $hash=e44bb89a337942c82bfa246275b4b033821b2782$
//
#ifndef CEF_INCLUDE_CAPI_CEF_LIFE_SPAN_HANDLER_CAPI_H_
@ -101,8 +101,10 @@ typedef struct _cef_life_span_handler_t {
int* no_javascript_access);
///
// Called after a new browser is created. This callback will be the first
// notification that references |browser|.
// Called after a new browser is created. It is now safe to begin performing
// actions with |browser|. cef_frame_handler_t callbacks related to initial
// main frame creation will arrive before this callback. See
// cef_frame_handler_t documentation for additional usage information.
///
void(CEF_CALLBACK* on_after_created)(struct _cef_life_span_handler_t* self,
struct _cef_browser_t* browser);
@ -202,13 +204,14 @@ typedef struct _cef_life_span_handler_t {
///
// Called just before a browser is destroyed. Release all references to the
// browser object and do not attempt to execute any functions on the browser
// object (other than GetIdentifier or IsSame) after this callback returns.
// This callback will be the last notification that references |browser| on
// the UI thread. Any in-progress network requests associated with |browser|
// will be aborted when the browser is destroyed, and
// object (other than IsValid, GetIdentifier or IsSame) after this callback
// returns. cef_frame_handler_t callbacks related to final main frame
// destruction will arrive after this callback and cef_browser_t::IsValid will
// return false (0) at that time. Any in-progress network requests associated
// with |browser| will be aborted when the browser is destroyed, and
// cef_resource_request_handler_t callbacks related to those requests may
// still arrive on the IO thread after this function is called. See do_close()
// documentation for additional usage information.
// still arrive on the IO thread after this callback. See cef_frame_handler_t
// and do_close() documentation for additional usage information.
///
void(CEF_CALLBACK* on_before_close)(struct _cef_life_span_handler_t* self,
struct _cef_browser_t* browser);

View File

@ -42,13 +42,13 @@
// way that may cause binary incompatibility with other builds. The universal
// hash value will change if any platform is affected whereas the platform hash
// values will change only if that particular platform is affected.
#define CEF_API_HASH_UNIVERSAL "b2f96ef79b0a316e88dae7c885675ab4e012a1fd"
#define CEF_API_HASH_UNIVERSAL "7fb6a7510f39c359767b3a893c9ebfb5fb5973d7"
#if defined(OS_WIN)
#define CEF_API_HASH_PLATFORM "a6f28bd2c6d7248655ede7f2ad0eb01c3b53bbb5"
#define CEF_API_HASH_PLATFORM "0a848e5b676ddc931dbb5b174a64eb7be7f7dfbf"
#elif defined(OS_MAC)
#define CEF_API_HASH_PLATFORM "3398ee95844446efa42cc366fb08c37f739b7fbd"
#define CEF_API_HASH_PLATFORM "4c666fab20ab43dddf2f7ac6543197a1fecee389"
#elif defined(OS_LINUX)
#define CEF_API_HASH_PLATFORM "00a4ab72830b926411b311f5985e31e8146cedba"
#define CEF_API_HASH_PLATFORM "5f756efd08c6e10629fe1f81e9266c7af71aa5ce"
#endif
#ifdef __cplusplus

View File

@ -52,14 +52,21 @@ class CefBrowserHost;
class CefClient;
///
// Class used to represent a browser window. When used in the browser process
// the methods of this class may be called on any thread unless otherwise
// indicated in the comments. When used in the render process the methods of
// this class may only be called on the main thread.
// Class used to represent a browser. When used in the browser process the
// methods of this class may be called on any thread unless otherwise indicated
// in the comments. When used in the render process the methods of this class
// may only be called on the main thread.
///
/*--cef(source=library)--*/
class CefBrowser : public virtual CefBaseRefCounted {
public:
///
// True if this object is currently valid. This will return false after
// CefLifeSpanHandler::OnBeforeClose is called.
///
/*--cef()--*/
virtual bool IsValid() = 0;
///
// Returns the browser host object. This method can only be called in the
// browser process.
@ -130,7 +137,7 @@ class CefBrowser : public virtual CefBaseRefCounted {
virtual bool IsSame(CefRefPtr<CefBrowser> that) = 0;
///
// Returns true if the window is a popup window.
// Returns true if the browser is a popup.
///
/*--cef()--*/
virtual bool IsPopup() = 0;
@ -142,13 +149,17 @@ class CefBrowser : public virtual CefBaseRefCounted {
virtual bool HasDocument() = 0;
///
// Returns the main (top-level) frame for the browser window.
// Returns the main (top-level) frame for the browser. In the browser process
// this will return a valid object until after
// CefLifeSpanHandler::OnBeforeClose is called. The main frame object will
// change during cross-origin navigation or re-navigation after renderer
// process termination (due to crashes, etc).
///
/*--cef()--*/
virtual CefRefPtr<CefFrame> GetMainFrame() = 0;
///
// Returns the focused frame for the browser window.
// Returns the focused frame for the browser.
///
/*--cef()--*/
virtual CefRefPtr<CefFrame> GetFocusedFrame() = 0;
@ -261,10 +272,9 @@ class CefDownloadImageCallback : public virtual CefBaseRefCounted {
};
///
// Class used to represent the browser process aspects of a browser window. The
// methods of this class can only be called in the browser process. They may be
// called on any thread in that process unless otherwise indicated in the
// comments.
// Class used to represent the browser process aspects of a browser. The methods
// of this class can only be called in the browser process. They may be called
// on any thread in that process unless otherwise indicated in the comments.
///
/*--cef(source=library)--*/
class CefBrowserHost : public virtual CefBaseRefCounted {
@ -275,14 +285,14 @@ class CefBrowserHost : public virtual CefBaseRefCounted {
typedef cef_paint_element_type_t PaintElementType;
///
// Create a new browser window using the window parameters specified by
// |windowInfo|. All values will be copied internally and the actual window
// will be created on the UI thread. If |request_context| is empty the
// global request context will be used. This method can be called on any
// browser process thread and will not block. The optional |extra_info|
// parameter provides an opportunity to specify extra information specific
// to the created browser that will be passed to
// CefRenderProcessHandler::OnBrowserCreated() in the render process.
// Create a new browser using the window parameters specified by |windowInfo|.
// All values will be copied internally and the actual window (if any) will be
// created on the UI thread. If |request_context| is empty the global request
// context will be used. This method can be called on any browser process
// thread and will not block. The optional |extra_info| parameter provides an
// opportunity to specify extra information specific to the created browser
// that will be passed to CefRenderProcessHandler::OnBrowserCreated() in the
// render process.
///
/*--cef(optional_param=client,optional_param=url,
optional_param=request_context,optional_param=extra_info)--*/
@ -294,13 +304,12 @@ class CefBrowserHost : public virtual CefBaseRefCounted {
CefRefPtr<CefRequestContext> request_context);
///
// Create a new browser window using the window parameters specified by
// |windowInfo|. If |request_context| is empty the global request context
// will be used. This method can only be called on the browser process UI
// thread. The optional |extra_info| parameter provides an opportunity to
// specify extra information specific to the created browser that will be
// passed to CefRenderProcessHandler::OnBrowserCreated() in the render
// process.
// Create a new browser using the window parameters specified by |windowInfo|.
// If |request_context| is empty the global request context will be used. This
// method can only be called on the browser process UI thread. The optional
// |extra_info| parameter provides an opportunity to specify extra information
// specific to the created browser that will be passed to
// CefRenderProcessHandler::OnBrowserCreated() in the render process.
///
/*--cef(optional_param=client,optional_param=url,
optional_param=request_context,optional_param=extra_info)--*/
@ -333,9 +342,9 @@ class CefBrowserHost : public virtual CefBaseRefCounted {
///
// Helper for closing a browser. Call this method from the top-level window
// close handler. Internally this calls CloseBrowser(false) if the close has
// not yet been initiated. This method returns false while the close is
// pending and true after the close has completed. See CloseBrowser() and
// close handler (if any). Internally this calls CloseBrowser(false) if the
// close has not yet been initiated. This method returns false while the close
// is pending and true after the close has completed. See CloseBrowser() and
// CefLifeSpanHandler::DoClose() documentation for additional usage
// information. This method must be called on the browser process UI thread.
///
@ -349,18 +358,19 @@ class CefBrowserHost : public virtual CefBaseRefCounted {
virtual void SetFocus(bool focus) = 0;
///
// Retrieve the window handle for this browser. If this browser is wrapped in
// a CefBrowserView this method should be called on the browser process UI
// thread and it will return the handle for the top-level native window.
// Retrieve the window handle (if any) for this browser. If this browser is
// wrapped in a CefBrowserView this method should be called on the browser
// process UI thread and it will return the handle for the top-level native
// window.
///
/*--cef()--*/
virtual CefWindowHandle GetWindowHandle() = 0;
///
// Retrieve the window handle of the browser that opened this browser. Will
// return NULL for non-popup windows or if this browser is wrapped in a
// CefBrowserView. This method can be used in combination with custom handling
// of modal windows.
// Retrieve the window handle (if any) of the browser that opened this
// browser. Will return NULL for non-popup browsers or if this browser is
// wrapped in a CefBrowserView. This method can be used in combination with
// custom handling of modal windows.
///
/*--cef()--*/
virtual CefWindowHandle GetOpenerWindowHandle() = 0;

View File

@ -47,6 +47,7 @@
#include "include/cef_drag_handler.h"
#include "include/cef_find_handler.h"
#include "include/cef_focus_handler.h"
#include "include/cef_frame_handler.h"
#include "include/cef_jsdialog_handler.h"
#include "include/cef_keyboard_handler.h"
#include "include/cef_life_span_handler.h"
@ -115,6 +116,14 @@ class CefClient : public virtual CefBaseRefCounted {
/*--cef()--*/
virtual CefRefPtr<CefFocusHandler> GetFocusHandler() { return nullptr; }
///
// Return the handler for events related to CefFrame lifespan. This method
// will be called once during CefBrowser creation and the result will be
// cached for performance reasons.
///
/*--cef()--*/
virtual CefRefPtr<CefFrameHandler> GetFrameHandler() { return nullptr; }
///
// Return the handler for JavaScript dialogs. If no handler is provided the
// default implementation will be used.

172
include/cef_frame_handler.h Normal file
View File

@ -0,0 +1,172 @@
// Copyright (c) 2021 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_FRAME_HANDLER_H_
#define CEF_INCLUDE_CEF_FRAME_HANDLER_H_
#pragma once
#include "include/cef_base.h"
#include "include/cef_browser.h"
#include "include/cef_frame.h"
///
// Implement this interface to handle events related to CefFrame life span. The
// order of callbacks is:
//
// (1) During initial CefBrowserHost creation and navigation of the main frame:
// - CefFrameHandler::OnFrameCreated => The initial main frame object has been
// created. Any commands will be queued until the frame is attached.
// - CefFrameHandler::OnMainFrameChanged => The initial main frame object has
// been assigned to the browser.
// - CefLifeSpanHandler::OnAfterCreated => The browser is now valid and can be
// used.
// - CefFrameHandler::OnFrameAttached => The initial main frame object is now
// connected to its peer in the renderer process. Commands can be routed.
//
// (2) During further CefBrowserHost navigation/loading of the main frame and/or
// sub-frames:
// - CefFrameHandler::OnFrameCreated => A new main frame or sub-frame object has
// been created. Any commands will be queued until the frame is attached.
// - CefFrameHandler::OnFrameAttached => A new main frame or sub-frame object is
// now connected to its peer in the renderer process. Commands can be routed.
// - CefFrameHandler::OnFrameDetached => An existing main frame or sub-frame
// object has lost its connection to the renderer process. If multiple objects
// are detached at the same time then notifications will be sent for any
// sub-frame objects before the main frame object. Commands can no longer be
// routed and will be discarded.
// - CefFrameHandler::OnMainFrameChanged => A new main frame object has been
// assigned to the browser. This will only occur with cross-origin navigation
// or re-navigation after renderer process termination (due to crashes, etc).
//
// (3) During final CefBrowserHost destruction of the main frame:
// - CefFrameHandler::OnFrameDetached => Any sub-frame objects have lost their
// connection to the renderer process. Commands can no longer be routed and
// will be discarded.
// - CefLifeSpanHandler::OnBeforeClose => The browser has been destroyed.
// - CefFrameHandler::OnFrameDetached => The main frame object have lost its
// connection to the renderer process. Notifications will be sent for any
// sub-frame objects before the main frame object. Commands can no longer be
// routed and will be discarded.
// - CefFrameHandler::OnMainFrameChanged => The final main frame object has been
// removed from the browser.
//
// Cross-origin navigation and/or loading receives special handling.
//
// When the main frame navigates to a different origin the OnMainFrameChanged
// callback (2) will be executed with the old and new main frame objects.
//
// When a new sub-frame is loaded in, or an existing sub-frame is navigated to,
// a different origin from the parent frame, a temporary sub-frame object will
// first be created in the parent's renderer process. That temporary sub-frame
// will then be discarded after the real cross-origin sub-frame is created in
// the new/target renderer process. The client will receive cross-origin
// navigation callbacks (2) for the transition from the temporary sub-frame to
// the real sub-frame. The temporary sub-frame will not recieve or execute
// commands during this transitional period (any sent commands will be
// discarded).
//
// When a new popup browser is created in a different origin from the parent
// browser, a temporary main frame object for the popup will first be created in
// the parent's renderer process. That temporary main frame will then be
// discarded after the real cross-origin main frame is created in the new/target
// renderer process. The client will recieve creation and initial navigation
// callbacks (1) for the temporary main frame, followed by cross-origin
// navigation callbacks (2) for the transition from the temporary main frame to
// the real main frame. The temporary main frame may receive and execute
// commands during this transitional period (any sent commands may be executed,
// but the behavior is potentially undesirable since they execute in the parent
// browser's renderer process and not the new/target renderer process).
//
// Callbacks will not be executed for placeholders that may be created during
// pre-commit navigation for sub-frames that do not yet exist in the renderer
// process. Placeholders will have CefFrame::GetIdentifier() == -4.
//
// The methods of this class will be called on the UI thread unless otherwise
// indicated.
///
/*--cef(source=client)--*/
class CefFrameHandler : public virtual CefBaseRefCounted {
public:
///
// Called when a new frame is created. This will be the first notification
// that references |frame|. Any commands that require transport to the
// associated renderer process (LoadRequest, SendProcessMessage, GetSource,
// etc.) will be queued until OnFrameAttached is called for |frame|.
///
/*--cef()--*/
virtual void OnFrameCreated(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame) {}
///
// Called when a frame can begin routing commands to/from the associated
// renderer process. Any commands that were queued have now been dispatched.
///
/*--cef()--*/
virtual void OnFrameAttached(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame) {}
///
// Called when a frame loses its connection to the renderer process and will
// be destroyed. Any pending or future commands will be discarded and
// CefFrame::IsValid() will now return false for |frame|. If called after
// CefLifeSpanHandler::OnBeforeClose() during browser destruction then
// CefBrowser::IsValid() will return false for |browser|.
///
/*--cef()--*/
virtual void OnFrameDetached(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame) {}
///
// Called when the main frame changes due to (a) initial browser creation, (b)
// final browser destruction, (c) cross-origin navigation or (d) re-navigation
// after renderer process termination (due to crashes, etc). |old_frame| will
// be NULL and |new_frame| will be non-NULL when a main frame is assigned to
// |browser| for the first time. |old_frame| will be non-NULL and |new_frame|
// will be NULL and when a main frame is removed from |browser| for the last
// time. Both |old_frame| and |new_frame| will be non-NULL for cross-origin
// navigations or re-navigation after renderer process termination. This
// method will be called after OnFrameCreated() for |new_frame| and/or after
// OnFrameDetached() for |old_frame|. If called after
// CefLifeSpanHandler::OnBeforeClose() during browser destruction then
// CefBrowser::IsValid() will return false for |browser|.
///
/*--cef(optional_param=old_frame,optional_param=new_frame)--*/
virtual void OnMainFrameChanged(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> old_frame,
CefRefPtr<CefFrame> new_frame) {}
};
#endif // CEF_INCLUDE_CEF_FRAME_HANDLER_H_

View File

@ -95,8 +95,10 @@ class CefLifeSpanHandler : public virtual CefBaseRefCounted {
}
///
// Called after a new browser is created. This callback will be the first
// notification that references |browser|.
// Called after a new browser is created. It is now safe to begin performing
// actions with |browser|. CefFrameHandler callbacks related to initial main
// frame creation will arrive before this callback. See CefFrameHandler
// documentation for additional usage information.
///
/*--cef()--*/
virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) {}
@ -195,13 +197,14 @@ class CefLifeSpanHandler : public virtual CefBaseRefCounted {
///
// Called just before a browser is destroyed. Release all references to the
// browser object and do not attempt to execute any methods on the browser
// object (other than GetIdentifier or IsSame) after this callback returns.
// This callback will be the last notification that references |browser| on
// the UI thread. Any in-progress network requests associated with |browser|
// object (other than IsValid, GetIdentifier or IsSame) after this callback
// returns. CefFrameHandler callbacks related to final main frame destruction
// will arrive after this callback and CefBrowser::IsValid will return false
// at that time. Any in-progress network requests associated with |browser|
// will be aborted when the browser is destroyed, and
// CefResourceRequestHandler callbacks related to those requests may still
// arrive on the IO thread after this method is called. See DoClose()
// documentation for additional usage information.
// arrive on the IO thread after this callback. See CefFrameHandler and
// DoClose() documentation for additional usage information.
///
/*--cef()--*/
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) {}

View File

@ -46,7 +46,7 @@
// The below classes implement support for routing aynchronous messages between
// JavaScript running in the renderer process and C++ running in the browser
// process. An application interacts with the router by passing it data from
// standard CEF C++ callbacks (OnBeforeBrowse, OnProcessMessageRecieved,
// standard CEF C++ callbacks (OnBeforeBrowse, OnProcessMessageReceived,
// OnContextCreated, etc). The renderer-side router supports generic JavaScript
// callback registration and execution while the browser-side router supports
// application-specific logic via one or more application-provided Handler

View File

@ -35,7 +35,9 @@ void CefBrowserFrame::RegisterBrowserInterfaceBindersForFrame(
void CefBrowserFrame::SendMessage(const std::string& name,
base::Value arguments) {
if (auto host = GetFrameHost()) {
// Always associate with the newly created RFH, which may be speculative when
// navigating cross-origin.
if (auto host = GetFrameHost(/*prefer_speculative=*/true)) {
host->SendMessage(name, std::move(arguments));
}
}

View File

@ -497,6 +497,10 @@ void CefBrowserHostBase::SendMouseWheelEvent(const CefMouseEvent& event,
}
}
bool CefBrowserHostBase::IsValid() {
return browser_info_->browser() == this;
}
CefRefPtr<CefBrowserHost> CefBrowserHostBase::GetHost() {
return this;
}

View File

@ -183,6 +183,7 @@ class CefBrowserHostBase : public CefBrowserHost,
CefRefPtr<CefNavigationEntry> GetVisibleNavigationEntry() override;
// CefBrowser methods:
bool IsValid() override;
CefRefPtr<CefBrowserHost> GetHost() override;
bool CanGoBack() override;
void GoBack() override;

View File

@ -15,10 +15,12 @@
#include "ipc/ipc_message.h"
CefBrowserInfo::FrameInfo::~FrameInfo() {
if (frame_ && !is_main_frame_) {
// Disassociate sub-frames from the browser.
frame_->Detach();
#if DCHECK_IS_ON()
if (frame_ && !IsCurrentMainFrame()) {
// Should already be Detached.
DCHECK(!frame_->GetRenderFrameHost());
}
#endif
}
CefBrowserInfo::CefBrowserInfo(int browser_id,
@ -32,7 +34,9 @@ CefBrowserInfo::CefBrowserInfo(int browser_id,
DCHECK_GT(browser_id, 0);
}
CefBrowserInfo::~CefBrowserInfo() {}
CefBrowserInfo::~CefBrowserInfo() {
DCHECK(frame_info_set_.empty());
}
CefRefPtr<CefBrowserHostBase> CefBrowserInfo::browser() const {
base::AutoLock lock_scope(lock_);
@ -40,11 +44,29 @@ CefRefPtr<CefBrowserHostBase> CefBrowserInfo::browser() const {
}
void CefBrowserInfo::SetBrowser(CefRefPtr<CefBrowserHostBase> browser) {
base::AutoLock lock_scope(lock_);
NotificationStateLock lock_scope(this);
if (browser) {
DCHECK(!browser_);
// Cache the associated frame handler.
if (auto client = browser->GetClient()) {
frame_handler_ = client->GetFrameHandler();
}
} else {
DCHECK(browser_);
}
auto old_browser = browser_;
browser_ = browser;
if (!browser) {
RemoveAllFrames();
if (!browser_) {
RemoveAllFrames(old_browser);
// Any future calls to MaybeExecuteFrameNotification will now fail.
// NotificationStateLock already took a reference for the delivery of any
// notifications that are currently queued due to RemoveAllFrames.
frame_handler_ = nullptr;
}
}
@ -68,7 +90,7 @@ void CefBrowserInfo::MaybeCreateFrame(content::RenderFrameHost* host,
->render_manager()
->current_frame_host() != host);
base::AutoLock lock_scope(lock_);
NotificationStateLock lock_scope(this);
DCHECK(browser_);
const auto it = frame_id_map_.find(frame_id);
@ -87,9 +109,7 @@ void CefBrowserInfo::MaybeCreateFrame(content::RenderFrameHost* host,
// Upgrade the frame info from speculative to non-speculative.
if (info->is_main_frame_) {
// Set the main frame object.
if (main_frame_)
main_frame_->Detach();
main_frame_ = info->frame_;
SetMainFrame(browser_, info->frame_);
}
info->is_speculative_ = false;
MaybeUpdateFrameTreeNodeIdMap(info);
@ -107,17 +127,13 @@ void CefBrowserInfo::MaybeCreateFrame(content::RenderFrameHost* host,
// Guest views don't get their own CefBrowser or CefFrame objects.
if (!is_guest_view) {
if (is_main_frame && main_frame_ && !is_speculative) {
// Update the existing main frame object.
main_frame_->SetRenderFrameHost(host);
frame_info->frame_ = main_frame_;
} else {
// Create a new frame object.
frame_info->frame_ = new CefFrameHostImpl(this, host);
if (is_main_frame && !is_speculative) {
main_frame_ = frame_info->frame_;
}
// Create a new frame object.
frame_info->frame_ = new CefFrameHostImpl(this, host);
MaybeNotifyFrameCreated(frame_info->frame_);
if (is_main_frame && !is_speculative) {
SetMainFrame(browser_, frame_info->frame_);
}
#if DCHECK_IS_ON()
// Check that the frame info hasn't changed unexpectedly.
DCHECK_EQ(frame_id, frame_info->frame_->GetIdentifier());
@ -140,7 +156,7 @@ void CefBrowserInfo::MaybeCreateFrame(content::RenderFrameHost* host,
void CefBrowserInfo::RemoveFrame(content::RenderFrameHost* host) {
CEF_REQUIRE_UIT();
base::AutoLock lock_scope(lock_);
NotificationStateLock lock_scope(this);
const auto frame_id = CefFrameHostImpl::MakeFrameId(host);
@ -170,19 +186,25 @@ void CefBrowserInfo::RemoveFrame(content::RenderFrameHost* host) {
// And finally delete the frame info.
{
auto it2 = frame_info_set_.find(frame_info);
// Explicitly Detach everything but the current main frame.
const auto& frame_info = *it2;
if (frame_info->frame_ && !frame_info->IsCurrentMainFrame()) {
frame_info->frame_->Detach();
MaybeNotifyFrameDetached(browser_, frame_info->frame_);
}
frame_info_set_.erase(it2);
}
}
CefRefPtr<CefFrameHostImpl> CefBrowserInfo::GetMainFrame() {
base::AutoLock lock_scope(lock_);
DCHECK(browser_);
if (!main_frame_) {
// Create a temporary object that will eventually be updated with real
// routing information.
main_frame_ =
new CefFrameHostImpl(this, true, CefFrameHostImpl::kInvalidFrameId);
}
NotificationStateLock lock_scope(this);
// Early exit if called post-destruction.
if (!browser_)
return nullptr;
CHECK(main_frame_);
return main_frame_;
}
@ -191,7 +213,8 @@ CefRefPtr<CefFrameHostImpl> CefBrowserInfo::CreateTempSubFrame(
CefRefPtr<CefFrameHostImpl> parent = GetFrameForId(parent_frame_id);
if (!parent)
parent = GetMainFrame();
return new CefFrameHostImpl(this, false, parent->GetIdentifier());
// Intentionally not notifying for temporary frames.
return new CefFrameHostImpl(this, parent->GetIdentifier());
}
CefRefPtr<CefFrameHostImpl> CefBrowserInfo::GetFrameForHost(
@ -328,6 +351,30 @@ bool CefBrowserInfo::IsNavigationLocked(base::OnceClosure pending_action) {
return false;
}
void CefBrowserInfo::MaybeExecuteFrameNotification(
FrameNotifyOnceAction pending_action) {
CefRefPtr<CefFrameHandler> frame_handler;
{
base::AutoLock lock_scope_(notification_lock_);
if (!frame_handler_) {
// No notifications will be executed.
return;
}
if (notification_state_lock_) {
// Queue the notification until the lock is released.
notification_state_lock_->queue_.push(std::move(pending_action));
return;
}
frame_handler = frame_handler_;
}
// Execute immediately if not locked.
std::move(pending_action).Run(frame_handler);
}
void CefBrowserInfo::MaybeUpdateFrameTreeNodeIdMap(FrameInfo* info) {
lock_.AssertAcquired();
@ -381,24 +428,150 @@ CefRefPtr<CefFrameHostImpl> CefBrowserInfo::GetFrameForFrameTreeNodeInternal(
return nullptr;
}
void CefBrowserInfo::RemoveAllFrames() {
// Passing in |browser| here because |browser_| may already be cleared.
void CefBrowserInfo::SetMainFrame(CefRefPtr<CefBrowserHostBase> browser,
CefRefPtr<CefFrameHostImpl> frame) {
lock_.AssertAcquired();
DCHECK(browser);
DCHECK(!frame || frame->IsMain());
CefRefPtr<CefFrameHostImpl> old_frame;
if (main_frame_) {
old_frame = main_frame_;
old_frame->Detach();
MaybeNotifyFrameDetached(browser, old_frame);
}
main_frame_ = frame;
MaybeNotifyMainFrameChanged(browser, old_frame, main_frame_);
}
void CefBrowserInfo::MaybeNotifyFrameCreated(
CefRefPtr<CefFrameHostImpl> frame) {
CEF_REQUIRE_UIT();
// Never notify for temporary objects.
DCHECK(!frame->is_temporary());
MaybeExecuteFrameNotification(base::BindOnce(
[](scoped_refptr<CefBrowserInfo> self, CefRefPtr<CefFrameHostImpl> frame,
CefRefPtr<CefFrameHandler> handler) {
if (auto browser = self->browser()) {
handler->OnFrameCreated(browser, frame);
}
},
scoped_refptr<CefBrowserInfo>(this), frame));
}
// Passing in |browser| here because |browser_| may already be cleared.
void CefBrowserInfo::MaybeNotifyFrameDetached(
CefRefPtr<CefBrowserHostBase> browser,
CefRefPtr<CefFrameHostImpl> frame) {
CEF_REQUIRE_UIT();
// Never notify for temporary objects.
DCHECK(!frame->is_temporary());
MaybeExecuteFrameNotification(base::BindOnce(
[](CefRefPtr<CefBrowserHostBase> browser,
CefRefPtr<CefFrameHostImpl> frame,
CefRefPtr<CefFrameHandler> handler) {
handler->OnFrameDetached(browser, frame);
},
browser, frame));
}
// Passing in |browser| here because |browser_| may already be cleared.
void CefBrowserInfo::MaybeNotifyMainFrameChanged(
CefRefPtr<CefBrowserHostBase> browser,
CefRefPtr<CefFrameHostImpl> old_frame,
CefRefPtr<CefFrameHostImpl> new_frame) {
CEF_REQUIRE_UIT();
// Never notify for temporary objects.
DCHECK(!old_frame || !old_frame->is_temporary());
DCHECK(!new_frame || !new_frame->is_temporary());
MaybeExecuteFrameNotification(base::BindOnce(
[](CefRefPtr<CefBrowserHostBase> browser,
CefRefPtr<CefFrameHostImpl> old_frame,
CefRefPtr<CefFrameHostImpl> new_frame,
CefRefPtr<CefFrameHandler> handler) {
handler->OnMainFrameChanged(browser, old_frame, new_frame);
},
browser, old_frame, new_frame));
}
void CefBrowserInfo::RemoveAllFrames(
CefRefPtr<CefBrowserHostBase> old_browser) {
lock_.AssertAcquired();
// Make sure any callbacks will see the correct state (e.g. like
// CefBrowser::GetMainFrame returning nullptr and CefBrowser::IsValid
// returning false).
DCHECK(!browser_);
DCHECK(old_browser);
// Clear the lookup maps.
frame_id_map_.clear();
frame_tree_node_id_map_.clear();
// Explicitly Detach main frames.
// Explicitly Detach everything but the current main frame.
for (auto& info : frame_info_set_) {
if (info->frame_ && info->is_main_frame_)
if (info->frame_ && !info->IsCurrentMainFrame()) {
info->frame_->Detach();
MaybeNotifyFrameDetached(old_browser, info->frame_);
}
}
if (main_frame_) {
main_frame_->Detach();
main_frame_ = nullptr;
}
if (main_frame_)
SetMainFrame(old_browser, nullptr);
// And finally delete the frame info.
frame_info_set_.clear();
}
CefBrowserInfo::NotificationStateLock::NotificationStateLock(
CefBrowserInfo* browser_info)
: browser_info_(browser_info) {
// Take the navigation state lock.
{
base::AutoLock lock_scope_(browser_info_->notification_lock_);
CHECK(!browser_info_->notification_state_lock_);
browser_info_->notification_state_lock_ = this;
// We may need this on destruction, and the original might be cleared.
frame_handler_ = browser_info_->frame_handler_;
}
// Take the browser info state lock.
browser_info_lock_scope_.reset(new base::AutoLock(browser_info_->lock_));
}
CefBrowserInfo::NotificationStateLock::~NotificationStateLock() {
// Unlock in reverse order.
browser_info_lock_scope_.reset();
{
base::AutoLock lock_scope_(browser_info_->notification_lock_);
CHECK_EQ(this, browser_info_->notification_state_lock_);
browser_info_->notification_state_lock_ = nullptr;
}
if (!queue_.empty()) {
DCHECK(frame_handler_);
scoped_refptr<NavigationLock> nav_lock;
if (CEF_CURRENTLY_ON_UIT()) {
// Don't navigate while inside callbacks.
nav_lock = browser_info_->CreateNavigationLock();
}
// Empty the queue of pending actions. Any of these actions might result in
// the acquisition of a new NotificationStateLock.
while (!queue_.empty()) {
std::move(queue_.front()).Run(frame_handler_);
queue_.pop();
}
}
}

View File

@ -6,6 +6,7 @@
#define CEF_LIBCEF_BROWSER_BROWSER_INFO_H_
#pragma once
#include <queue>
#include <set>
#include <unordered_map>
@ -24,6 +25,7 @@ class RenderFrameHost;
}
class CefBrowserHostBase;
class CefFrameHandler;
class CefFrameHostImpl;
// CefBrowserInfo is used to associate a browser ID and render view/process
@ -149,6 +151,16 @@ class CefBrowserInfo : public base::RefCountedThreadSafe<CefBrowserInfo> {
// thread.
bool IsNavigationLocked(base::OnceClosure pending_action);
using FrameNotifyOnceAction =
base::OnceCallback<void(CefRefPtr<CefFrameHandler>)>;
// Specifies a CefFrameHandler notification action whose execution may need
// to be blocked on release of a potentially held NotificationStateLock. If no
// CefFrameHandler exists then the action will be discarded without executing.
// If the NotificationStateLock is not currently held then the action will be
// executed immediately.
void MaybeExecuteFrameNotification(FrameNotifyOnceAction pending_action);
private:
friend class base::RefCountedThreadSafe<CefBrowserInfo>;
@ -157,6 +169,10 @@ class CefBrowserInfo : public base::RefCountedThreadSafe<CefBrowserInfo> {
struct FrameInfo {
~FrameInfo();
inline bool IsCurrentMainFrame() const {
return frame_ && is_main_frame_ && !is_speculative_;
}
content::RenderFrameHost* host_;
int64_t frame_id_; // Combination of render_process_id + render_routing_id.
int frame_tree_node_id_;
@ -172,7 +188,17 @@ class CefBrowserInfo : public base::RefCountedThreadSafe<CefBrowserInfo> {
int frame_tree_node_id,
bool* is_guest_view = nullptr) const;
void RemoveAllFrames();
void SetMainFrame(CefRefPtr<CefBrowserHostBase> browser,
CefRefPtr<CefFrameHostImpl> frame);
void MaybeNotifyFrameCreated(CefRefPtr<CefFrameHostImpl> frame);
void MaybeNotifyFrameDetached(CefRefPtr<CefBrowserHostBase> browser,
CefRefPtr<CefFrameHostImpl> frame);
void MaybeNotifyMainFrameChanged(CefRefPtr<CefBrowserHostBase> browser,
CefRefPtr<CefFrameHostImpl> old_frame,
CefRefPtr<CefFrameHostImpl> new_frame);
void RemoveAllFrames(CefRefPtr<CefBrowserHostBase> old_browser);
int browser_id_;
bool is_popup_;
@ -183,6 +209,29 @@ class CefBrowserInfo : public base::RefCountedThreadSafe<CefBrowserInfo> {
// Only accessed on the UI thread.
base::WeakPtr<NavigationLock> navigation_lock_;
// Used instead of |base::AutoLock(lock_)| in situations that might generate
// CefFrameHandler notifications. Any notifications passed to
// MaybeExecuteFrameNotification() will be queued until the lock is released,
// and then executed in order.
class NotificationStateLock final {
public:
explicit NotificationStateLock(CefBrowserInfo* browser_info);
~NotificationStateLock();
protected:
friend class CefBrowserInfo;
CefBrowserInfo* const browser_info_;
CefRefPtr<CefFrameHandler> frame_handler_;
std::unique_ptr<base::AutoLock> browser_info_lock_scope_;
std::queue<FrameNotifyOnceAction> queue_;
};
mutable base::Lock notification_lock_;
// These members must be protected by |notification_lock_|.
NotificationStateLock* notification_state_lock_ = nullptr;
CefRefPtr<CefFrameHandler> frame_handler_;
mutable base::Lock lock_;
// The below members must be protected by |lock_|.

View File

@ -49,9 +49,8 @@ void ViewTextCallback(CefRefPtr<CefFrameHostImpl> frame,
} // namespace
CefFrameHostImpl::CefFrameHostImpl(scoped_refptr<CefBrowserInfo> browser_info,
bool is_main_frame,
int64_t parent_frame_id)
: is_main_frame_(is_main_frame),
: is_main_frame_(false),
frame_id_(kInvalidFrameId),
browser_info_(browser_info),
is_focused_(is_main_frame_), // The main frame always starts focused.
@ -69,32 +68,22 @@ CefFrameHostImpl::CefFrameHostImpl(scoped_refptr<CefBrowserInfo> browser_info,
CefFrameHostImpl::CefFrameHostImpl(scoped_refptr<CefBrowserInfo> browser_info,
content::RenderFrameHost* render_frame_host)
: is_main_frame_(render_frame_host->GetParent() == nullptr),
frame_id_(MakeFrameId(render_frame_host)),
browser_info_(browser_info),
is_focused_(is_main_frame_), // The main frame always starts focused.
url_(render_frame_host->GetLastCommittedURL().spec()),
name_(render_frame_host->GetFrameName()),
parent_frame_id_(is_main_frame_
? kInvalidFrameId
: MakeFrameId(render_frame_host->GetParent())) {
: MakeFrameId(render_frame_host->GetParent())),
render_frame_host_(render_frame_host) {
DCHECK(browser_info_);
SetRenderFrameHost(render_frame_host);
}
CefFrameHostImpl::~CefFrameHostImpl() {}
void CefFrameHostImpl::SetRenderFrameHost(content::RenderFrameHost* host) {
CEF_REQUIRE_UIT();
base::AutoLock lock_scope(state_lock_);
// We should not be detached.
CHECK(browser_info_);
render_frame_.reset();
is_attached_ = false;
render_frame_host_ = host;
frame_id_ = MakeFrameId(host);
url_ = host->GetLastCommittedURL().spec();
name_ = host->GetFrameName();
CefFrameHostImpl::~CefFrameHostImpl() {
// Should have been Detached.
DCHECK(!browser_info_);
DCHECK(!render_frame_host_);
}
bool CefFrameHostImpl::IsValid() {
@ -252,12 +241,14 @@ void CefFrameHostImpl::SendProcessMessage(
auto argument_list =
static_cast<CefProcessMessageImpl*>(message.get())->TakeArgumentList();
SendToRenderFrame(base::BindOnce(
[](const CefString& name, base::ListValue argument_list,
const RenderFrameType& render_frame) {
render_frame->SendMessage(name, std::move(argument_list));
},
message->GetName(), std::move(argument_list)));
SendToRenderFrame(__FUNCTION__,
base::BindOnce(
[](const CefString& name, base::ListValue argument_list,
const RenderFrameType& render_frame) {
render_frame->SendMessage(name,
std::move(argument_list));
},
message->GetName(), std::move(argument_list)));
}
void CefFrameHostImpl::SetFocused(bool focused) {
@ -290,21 +281,23 @@ void CefFrameHostImpl::RefreshAttributes() {
}
void CefFrameHostImpl::NotifyMoveOrResizeStarted() {
SendToRenderFrame(base::BindOnce([](const RenderFrameType& render_frame) {
render_frame->MoveOrResizeStarted();
}));
SendToRenderFrame(__FUNCTION__,
base::BindOnce([](const RenderFrameType& render_frame) {
render_frame->MoveOrResizeStarted();
}));
}
void CefFrameHostImpl::LoadRequest(cef::mojom::RequestParamsPtr params) {
if (!url_util::FixupGURL(params->url))
return;
SendToRenderFrame(base::BindOnce(
[](cef::mojom::RequestParamsPtr params,
const RenderFrameType& render_frame) {
render_frame->LoadRequest(std::move(params));
},
std::move(params)));
SendToRenderFrame(__FUNCTION__,
base::BindOnce(
[](cef::mojom::RequestParamsPtr params,
const RenderFrameType& render_frame) {
render_frame->LoadRequest(std::move(params));
},
std::move(params)));
auto browser = GetBrowserHostBase();
if (browser)
@ -346,11 +339,12 @@ void CefFrameHostImpl::LoadURLWithExtras(const std::string& url,
void CefFrameHostImpl::SendCommand(const std::string& command) {
DCHECK(!command.empty());
SendToRenderFrame(base::BindOnce(
[](const std::string& command, const RenderFrameType& render_frame) {
render_frame->SendCommand(command);
},
command));
SendToRenderFrame(__FUNCTION__, base::BindOnce(
[](const std::string& command,
const RenderFrameType& render_frame) {
render_frame->SendCommand(command);
},
command));
}
void CefFrameHostImpl::SendCommandWithResponse(
@ -358,15 +352,17 @@ void CefFrameHostImpl::SendCommandWithResponse(
cef::mojom::RenderFrame::SendCommandWithResponseCallback
response_callback) {
DCHECK(!command.empty());
SendToRenderFrame(base::BindOnce(
[](const std::string& command,
cef::mojom::RenderFrame::SendCommandWithResponseCallback
response_callback,
const RenderFrameType& render_frame) {
render_frame->SendCommandWithResponse(command,
std::move(response_callback));
},
command, std::move(response_callback)));
SendToRenderFrame(
__FUNCTION__,
base::BindOnce(
[](const std::string& command,
cef::mojom::RenderFrame::SendCommandWithResponseCallback
response_callback,
const RenderFrameType& render_frame) {
render_frame->SendCommandWithResponse(command,
std::move(response_callback));
},
command, std::move(response_callback)));
}
void CefFrameHostImpl::SendJavaScript(const std::u16string& jsCode,
@ -381,12 +377,14 @@ void CefFrameHostImpl::SendJavaScript(const std::u16string& jsCode,
startLine = 1;
}
SendToRenderFrame(base::BindOnce(
[](const std::u16string& jsCode, const std::string& scriptUrl,
int startLine, const RenderFrameType& render_frame) {
render_frame->SendJavaScript(jsCode, scriptUrl, startLine);
},
jsCode, scriptUrl, startLine));
SendToRenderFrame(
__FUNCTION__,
base::BindOnce(
[](const std::u16string& jsCode, const std::string& scriptUrl,
int startLine, const RenderFrameType& render_frame) {
render_frame->SendJavaScript(jsCode, scriptUrl, startLine);
},
jsCode, scriptUrl, startLine));
}
void CefFrameHostImpl::MaybeSendDidStopLoading() {
@ -402,9 +400,10 @@ void CefFrameHostImpl::MaybeSendDidStopLoading() {
return;
}
SendToRenderFrame(base::BindOnce([](const RenderFrameType& render_frame) {
render_frame->DidStopLoading();
}));
SendToRenderFrame(__FUNCTION__,
base::BindOnce([](const RenderFrameType& render_frame) {
render_frame->DidStopLoading();
}));
}
void CefFrameHostImpl::ExecuteJavaScriptWithUserGestureForTests(
@ -431,8 +430,14 @@ content::RenderFrameHost* CefFrameHostImpl::GetRenderFrameHost() const {
void CefFrameHostImpl::Detach() {
CEF_REQUIRE_UIT();
// Should not be called for temporary frames.
DCHECK(!is_temporary());
{
base::AutoLock lock_scope(state_lock_);
// Should be called only once.
DCHECK(browser_info_);
browser_info_ = nullptr;
}
@ -443,6 +448,7 @@ void CefFrameHostImpl::Detach() {
render_frame_.reset();
render_frame_host_ = nullptr;
is_attached_ = false;
}
// static
@ -475,10 +481,14 @@ int64 CefFrameHostImpl::GetFrameId() const {
return is_main_frame_ ? kMainFrameId : frame_id_;
}
CefRefPtr<CefBrowserHostBase> CefFrameHostImpl::GetBrowserHostBase() const {
scoped_refptr<CefBrowserInfo> CefFrameHostImpl::GetBrowserInfo() const {
base::AutoLock lock_scope(state_lock_);
if (browser_info_)
return browser_info_->browser();
return browser_info_;
}
CefRefPtr<CefBrowserHostBase> CefFrameHostImpl::GetBrowserHostBase() const {
if (auto browser_info = GetBrowserInfo())
return browser_info->browser();
return nullptr;
}
@ -496,23 +506,32 @@ CefFrameHostImpl::GetRenderFrame() {
return render_frame_;
}
void CefFrameHostImpl::SendToRenderFrame(RenderFrameAction action) {
void CefFrameHostImpl::SendToRenderFrame(const std::string& function_name,
RenderFrameAction action) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT, base::BindOnce(&CefFrameHostImpl::SendToRenderFrame,
this, std::move(action)));
CEF_POST_TASK(CEF_UIT,
base::BindOnce(&CefFrameHostImpl::SendToRenderFrame, this,
function_name, std::move(action)));
return;
}
if (!render_frame_host_) {
// Either we're a placeholder frame without a renderer representation, or
// we've been detached.
if (is_temporary()) {
LOG(WARNING) << function_name
<< " sent to temporary subframe will be ignored.";
return;
} else if (!render_frame_host_) {
// We've been detached.
LOG(WARNING) << function_name << " sent to detached "
<< (is_main_frame_ ? "main" : "sub") << "frame "
<< frame_util::GetFrameDebugString(frame_id_)
<< " will be ignored";
return;
}
if (!is_attached_) {
// Queue actions until we're notified by the renderer that it's ready to
// handle them.
queued_actions_.push(std::move(action));
queued_actions_.push(std::make_pair(function_name, std::move(action)));
return;
}
@ -538,6 +557,8 @@ void CefFrameHostImpl::SendMessage(const std::string& name,
}
void CefFrameHostImpl::FrameAttached() {
CEF_REQUIRE_UIT();
DCHECK(!is_attached_);
if (!is_attached_) {
is_attached_ = true;
@ -545,10 +566,19 @@ void CefFrameHostImpl::FrameAttached() {
auto& render_frame = GetRenderFrame();
while (!queued_actions_.empty()) {
if (render_frame) {
std::move(queued_actions_.front()).Run(render_frame);
std::move(queued_actions_.front().second).Run(render_frame);
}
queued_actions_.pop();
}
GetBrowserInfo()->MaybeExecuteFrameNotification(base::BindOnce(
[](CefRefPtr<CefFrameHostImpl> self,
CefRefPtr<CefFrameHandler> handler) {
if (auto browser = self->GetBrowserHostBase()) {
handler->OnFrameAttached(browser, self);
}
},
CefRefPtr<CefFrameHostImpl>(this)));
}
}

View File

@ -32,20 +32,14 @@ class CefBrowserHostBase;
// or retrieved via CefBrowerInfo.
class CefFrameHostImpl : public CefFrame, public cef::mojom::BrowserFrame {
public:
// Create a temporary frame.
// Create a temporary sub-frame.
CefFrameHostImpl(scoped_refptr<CefBrowserInfo> browser_info,
bool is_main_frame,
int64_t parent_frame_id);
// Create a frame backed by a RFH and owned by CefBrowserInfo.
CefFrameHostImpl(scoped_refptr<CefBrowserInfo> browser_info,
content::RenderFrameHost* render_frame_host);
// Update an existing main frame object on creation or for same-origin
// navigations. A new CefFrameHostImpl will be created for cross-origin
// navigations.
void SetRenderFrameHost(content::RenderFrameHost* host);
~CefFrameHostImpl() override;
// CefFrame methods
@ -80,6 +74,8 @@ class CefFrameHostImpl : public CefFrame, public cef::mojom::BrowserFrame {
void SendProcessMessage(CefProcessId target_process,
CefRefPtr<CefProcessMessage> message) override;
bool is_temporary() const { return frame_id_ == kInvalidFrameId; }
void SetFocused(bool focused);
void RefreshAttributes();
@ -147,6 +143,7 @@ class CefFrameHostImpl : public CefFrame, public cef::mojom::BrowserFrame {
private:
int64 GetFrameId() const;
scoped_refptr<CefBrowserInfo> GetBrowserInfo() const;
CefRefPtr<CefBrowserHostBase> GetBrowserHostBase() const;
// Returns the remote RenderFrame object.
@ -156,7 +153,8 @@ class CefFrameHostImpl : public CefFrame, public cef::mojom::BrowserFrame {
// Send an action to the remote RenderFrame. This will queue the action if the
// remote frame is not yet attached.
using RenderFrameAction = base::OnceCallback<void(const RenderFrameType&)>;
void SendToRenderFrame(RenderFrameAction action);
void SendToRenderFrame(const std::string& function_name,
RenderFrameAction action);
const bool is_main_frame_;
@ -175,7 +173,7 @@ class CefFrameHostImpl : public CefFrame, public cef::mojom::BrowserFrame {
bool is_attached_ = false;
std::queue<RenderFrameAction> queued_actions_;
std::queue<std::pair<std::string, RenderFrameAction>> queued_actions_;
mojo::Remote<cef::mojom::RenderFrame> render_frame_;

View File

@ -4,6 +4,9 @@
#include "libcef/common/frame_util.h"
#include <limits>
#include <sstream>
namespace frame_util {
int64_t MakeFrameId(int32_t render_process_id, int32_t render_routing_id) {
@ -11,4 +14,13 @@ int64_t MakeFrameId(int32_t render_process_id, int32_t render_routing_id) {
static_cast<uint64_t>(render_routing_id);
}
std::string GetFrameDebugString(int64_t frame_id) {
uint32_t process_id = frame_id >> 32;
uint32_t routing_id = std::numeric_limits<uint32_t>::max() & frame_id;
std::stringstream ss;
ss << frame_id << " [" << process_id << "," << routing_id << "]";
return ss.str();
}
} // namespace frame_util

View File

@ -13,6 +13,9 @@ namespace frame_util {
// and |render_routing_id|.
int64_t MakeFrameId(int32_t render_process_id, int32_t render_routing_id);
// Returns a human-readable version of |frame_id|.
std::string GetFrameDebugString(int64_t frame_id);
} // namespace frame_util
#endif // CEF_LIBCEF_COMMON_FRAME_UTIL_H_

View File

@ -48,6 +48,11 @@ CefRefPtr<CefBrowserImpl> CefBrowserImpl::GetBrowserForMainFrame(
// CefBrowser methods.
// -----------------------------------------------------------------------------
bool CefBrowserImpl::IsValid() {
CEF_REQUIRE_RT_RETURN(false);
return !!GetWebView();
}
CefRefPtr<CefBrowserHost> CefBrowserImpl::GetHost() {
NOTREACHED() << "GetHost cannot be called from the render process";
return nullptr;

View File

@ -44,6 +44,7 @@ class CefBrowserImpl : public CefBrowser, public blink::WebViewObserver {
blink::WebFrame* frame);
// CefBrowser methods.
bool IsValid() override;
CefRefPtr<CefBrowserHost> GetHost() override;
bool CanGoBack() override;
void GoBack() override;

View File

@ -18,6 +18,7 @@
#endif
#include "libcef/common/app_manager.h"
#include "libcef/common/frame_util.h"
#include "libcef/common/net/http_header_utils.h"
#include "libcef/common/process_message_impl.h"
#include "libcef/common/request_impl.h"
@ -360,6 +361,17 @@ void CefFrameImpl::OnDraggableRegionsChanged() {
}
}
void CefFrameImpl::OnContextCreated() {
context_created_ = true;
CHECK(frame_);
while (!queued_actions_.empty()) {
auto& action = queued_actions_.front();
std::move(action.second).Run(frame_);
queued_actions_.pop();
}
}
void CefFrameImpl::OnDetached() {
// Called when this frame has been detached from the view. This *will* be
// called for child frames when a parent frame is detached.
@ -374,6 +386,33 @@ void CefFrameImpl::OnDetached() {
browser_ = nullptr;
frame_ = nullptr;
url_loader_factory_.reset();
// In case we're destroyed without the context being created.
while (!queued_actions_.empty()) {
auto& action = queued_actions_.front();
LOG(WARNING) << action.first << " sent to detached frame "
<< frame_util::GetFrameDebugString(frame_id_)
<< " will be ignored";
queued_actions_.pop();
}
}
void CefFrameImpl::ExecuteOnLocalFrame(const std::string& function_name,
LocalFrameAction action) {
CEF_REQUIRE_RT_RETURN_VOID();
if (!context_created_) {
queued_actions_.push(std::make_pair(function_name, std::move(action)));
return;
}
if (frame_) {
std::move(action).Run(frame_);
} else {
LOG(WARNING) << function_name << " sent to detached frame "
<< frame_util::GetFrameDebugString(frame_id_)
<< " will be ignored";
}
}
const mojo::Remote<cef::mojom::BrowserFrame>& CefFrameImpl::GetBrowserFrame() {
@ -407,45 +446,63 @@ void CefFrameImpl::SendMessage(const std::string& name, base::Value arguments) {
}
void CefFrameImpl::SendCommand(const std::string& command) {
CEF_REQUIRE_RT_RETURN_VOID();
if (frame_) {
frame_->ExecuteCommand(blink::WebString::FromUTF8(command));
}
ExecuteOnLocalFrame(
__FUNCTION__,
base::BindOnce(
[](const std::string& command, blink::WebLocalFrame* frame) {
frame->ExecuteCommand(blink::WebString::FromUTF8(command));
},
command));
}
void CefFrameImpl::SendCommandWithResponse(
const std::string& command,
cef::mojom::RenderFrame::SendCommandWithResponseCallback callback) {
blink::WebString response;
ExecuteOnLocalFrame(
__FUNCTION__,
base::BindOnce(
[](const std::string& command,
cef::mojom::RenderFrame::SendCommandWithResponseCallback callback,
blink::WebLocalFrame* frame) {
blink::WebString response;
if (frame_) {
if (base::LowerCaseEqualsASCII(command, "getsource")) {
response = blink_glue::DumpDocumentMarkup(frame_);
} else if (base::LowerCaseEqualsASCII(command, "gettext")) {
response = blink_glue::DumpDocumentText(frame_);
}
}
if (base::LowerCaseEqualsASCII(command, "getsource")) {
response = blink_glue::DumpDocumentMarkup(frame);
} else if (base::LowerCaseEqualsASCII(command, "gettext")) {
response = blink_glue::DumpDocumentText(frame);
}
std::move(callback).Run(string_util::CreateSharedMemoryRegion(response));
std::move(callback).Run(
string_util::CreateSharedMemoryRegion(response));
},
command, std::move(callback)));
}
void CefFrameImpl::SendJavaScript(const std::u16string& jsCode,
const std::string& scriptUrl,
int32_t startLine) {
CEF_REQUIRE_RT_RETURN_VOID();
if (frame_) {
frame_->ExecuteScript(blink::WebScriptSource(
blink::WebString::FromUTF16(jsCode), GURL(scriptUrl), startLine));
}
ExecuteOnLocalFrame(
__FUNCTION__,
base::BindOnce(
[](const std::u16string& jsCode, const std::string& scriptUrl,
int32_t startLine, blink::WebLocalFrame* frame) {
frame->ExecuteScript(
blink::WebScriptSource(blink::WebString::FromUTF16(jsCode),
GURL(scriptUrl), startLine));
},
jsCode, scriptUrl, startLine));
}
void CefFrameImpl::LoadRequest(cef::mojom::RequestParamsPtr params) {
CEF_REQUIRE_RT_RETURN_VOID();
if (frame_) {
blink::WebURLRequest request;
CefRequestImpl::Get(params, request);
blink_glue::StartNavigation(frame_, request);
}
ExecuteOnLocalFrame(
__FUNCTION__,
base::BindOnce(
[](cef::mojom::RequestParamsPtr params, blink::WebLocalFrame* frame) {
blink::WebURLRequest request;
CefRequestImpl::Get(params, request);
blink_glue::StartNavigation(frame, request);
},
std::move(params)));
}
void CefFrameImpl::DidStopLoading() {

View File

@ -83,11 +83,19 @@ class CefFrameImpl : public CefFrame, public cef::mojom::RenderFrame {
void OnAttached(service_manager::BinderRegistry* registry);
void OnDidFinishLoad();
void OnDraggableRegionsChanged();
void OnContextCreated();
void OnDetached();
blink::WebLocalFrame* web_frame() const { return frame_; }
private:
// Execute an action on the associated WebLocalFrame. This will queue the
// action if the JavaScript context is not yet created.
using LocalFrameAction =
base::OnceCallback<void(blink::WebLocalFrame* frame)>;
void ExecuteOnLocalFrame(const std::string& function_name,
LocalFrameAction action);
// Returns the remote BrowserFrame object.
const mojo::Remote<cef::mojom::BrowserFrame>& GetBrowserFrame();
@ -112,6 +120,9 @@ class CefFrameImpl : public CefFrame, public cef::mojom::RenderFrame {
blink::WebLocalFrame* frame_;
const int64 frame_id_;
bool context_created_ = false;
std::queue<std::pair<std::string, LocalFrameAction>> queued_actions_;
std::unique_ptr<blink::WebURLLoaderFactory> url_loader_factory_;
mojo::ReceiverSet<cef::mojom::RenderFrame> receivers_;

View File

@ -140,6 +140,9 @@ void CefRenderFrameObserver::DidCreateScriptContext(
CefRefPtr<CefV8Context> contextPtr(new CefV8ContextImpl(isolate, context));
handler->OnContextCreated(browserPtr.get(), framePtr.get(), contextPtr);
// Do this last, in case the client callback modified the window object.
framePtr->OnContextCreated();
}
void CefRenderFrameObserver::WillReleaseScriptContext(

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=b573d2840558cbf17908a16d3e92c3196c84b1c7$
// $hash=f2b6ec1af9292dc180975a7566296b019c25772f$
//
#include "libcef_dll/cpptoc/browser_cpptoc.h"
@ -23,6 +23,22 @@ namespace {
// MEMBER FUNCTIONS - Body may be edited by hand.
int CEF_CALLBACK browser_is_valid(struct _cef_browser_t* self) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Execute
bool _retval = CefBrowserCppToC::Get(self)->IsValid();
// Return type: bool
return _retval;
}
struct _cef_browser_host_t* CEF_CALLBACK
browser_get_host(struct _cef_browser_t* self) {
shutdown_checker::AssertNotShutdown();
@ -378,6 +394,7 @@ void CEF_CALLBACK browser_get_frame_names(struct _cef_browser_t* self,
// CONSTRUCTOR - Do not edit by hand.
CefBrowserCppToC::CefBrowserCppToC() {
GetStruct()->is_valid = browser_is_valid;
GetStruct()->get_host = browser_get_host;
GetStruct()->can_go_back = browser_can_go_back;
GetStruct()->go_back = browser_go_back;

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=bdbe1ed03a5ab0ca22668417c329555a3b0d9cea$
// $hash=69e482e4a20c97d54dc21f892f9e70e3d5d80f47$
//
#include "libcef_dll/cpptoc/client_cpptoc.h"
@ -21,6 +21,7 @@
#include "libcef_dll/cpptoc/drag_handler_cpptoc.h"
#include "libcef_dll/cpptoc/find_handler_cpptoc.h"
#include "libcef_dll/cpptoc/focus_handler_cpptoc.h"
#include "libcef_dll/cpptoc/frame_handler_cpptoc.h"
#include "libcef_dll/cpptoc/jsdialog_handler_cpptoc.h"
#include "libcef_dll/cpptoc/keyboard_handler_cpptoc.h"
#include "libcef_dll/cpptoc/life_span_handler_cpptoc.h"
@ -164,6 +165,22 @@ client_get_focus_handler(struct _cef_client_t* self) {
return CefFocusHandlerCppToC::Wrap(_retval);
}
struct _cef_frame_handler_t* CEF_CALLBACK
client_get_frame_handler(struct _cef_client_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return NULL;
// Execute
CefRefPtr<CefFrameHandler> _retval =
CefClientCppToC::Get(self)->GetFrameHandler();
// Return type: refptr_same
return CefFrameHandlerCppToC::Wrap(_retval);
}
struct _cef_jsdialog_handler_t* CEF_CALLBACK
client_get_jsdialog_handler(struct _cef_client_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
@ -322,6 +339,7 @@ CefClientCppToC::CefClientCppToC() {
GetStruct()->get_drag_handler = client_get_drag_handler;
GetStruct()->get_find_handler = client_get_find_handler;
GetStruct()->get_focus_handler = client_get_focus_handler;
GetStruct()->get_frame_handler = client_get_frame_handler;
GetStruct()->get_jsdialog_handler = client_get_jsdialog_handler;
GetStruct()->get_keyboard_handler = client_get_keyboard_handler;
GetStruct()->get_life_span_handler = client_get_life_span_handler;

View File

@ -0,0 +1,154 @@
// Copyright (c) 2021 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.
//
// $hash=4d483792f68dc51dbc52722820a15795c4a1baad$
//
#include "libcef_dll/cpptoc/frame_handler_cpptoc.h"
#include "libcef_dll/ctocpp/browser_ctocpp.h"
#include "libcef_dll/ctocpp/frame_ctocpp.h"
#include "libcef_dll/shutdown_checker.h"
namespace {
// MEMBER FUNCTIONS - Body may be edited by hand.
void CEF_CALLBACK
frame_handler_on_frame_created(struct _cef_frame_handler_t* self,
cef_browser_t* browser,
cef_frame_t* frame) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return;
// Verify param: frame; type: refptr_diff
DCHECK(frame);
if (!frame)
return;
// Execute
CefFrameHandlerCppToC::Get(self)->OnFrameCreated(
CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame));
}
void CEF_CALLBACK
frame_handler_on_frame_attached(struct _cef_frame_handler_t* self,
cef_browser_t* browser,
cef_frame_t* frame) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return;
// Verify param: frame; type: refptr_diff
DCHECK(frame);
if (!frame)
return;
// Execute
CefFrameHandlerCppToC::Get(self)->OnFrameAttached(
CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame));
}
void CEF_CALLBACK
frame_handler_on_frame_detached(struct _cef_frame_handler_t* self,
cef_browser_t* browser,
cef_frame_t* frame) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return;
// Verify param: frame; type: refptr_diff
DCHECK(frame);
if (!frame)
return;
// Execute
CefFrameHandlerCppToC::Get(self)->OnFrameDetached(
CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame));
}
void CEF_CALLBACK
frame_handler_on_main_frame_changed(struct _cef_frame_handler_t* self,
cef_browser_t* browser,
cef_frame_t* old_frame,
cef_frame_t* new_frame) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return;
// Unverified params: old_frame, new_frame
// Execute
CefFrameHandlerCppToC::Get(self)->OnMainFrameChanged(
CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(old_frame),
CefFrameCToCpp::Wrap(new_frame));
}
} // namespace
// CONSTRUCTOR - Do not edit by hand.
CefFrameHandlerCppToC::CefFrameHandlerCppToC() {
GetStruct()->on_frame_created = frame_handler_on_frame_created;
GetStruct()->on_frame_attached = frame_handler_on_frame_attached;
GetStruct()->on_frame_detached = frame_handler_on_frame_detached;
GetStruct()->on_main_frame_changed = frame_handler_on_main_frame_changed;
}
// DESTRUCTOR - Do not edit by hand.
CefFrameHandlerCppToC::~CefFrameHandlerCppToC() {
shutdown_checker::AssertNotShutdown();
}
template <>
CefRefPtr<CefFrameHandler> CefCppToCRefCounted<
CefFrameHandlerCppToC,
CefFrameHandler,
cef_frame_handler_t>::UnwrapDerived(CefWrapperType type,
cef_frame_handler_t* s) {
NOTREACHED() << "Unexpected class type: " << type;
return nullptr;
}
template <>
CefWrapperType CefCppToCRefCounted<CefFrameHandlerCppToC,
CefFrameHandler,
cef_frame_handler_t>::kWrapperType =
WT_FRAME_HANDLER;

View File

@ -0,0 +1,37 @@
// Copyright (c) 2021 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.
//
// $hash=b0c9c0566d85a387088c99a5497069bd1945f3b1$
//
#ifndef CEF_LIBCEF_DLL_CPPTOC_FRAME_HANDLER_CPPTOC_H_
#define CEF_LIBCEF_DLL_CPPTOC_FRAME_HANDLER_CPPTOC_H_
#pragma once
#if !defined(WRAPPING_CEF_SHARED)
#error This file can be included wrapper-side only
#endif
#include "include/capi/cef_frame_handler_capi.h"
#include "include/cef_frame_handler.h"
#include "libcef_dll/cpptoc/cpptoc_ref_counted.h"
// Wrap a C++ class with a C structure.
// This class may be instantiated and accessed wrapper-side only.
class CefFrameHandlerCppToC : public CefCppToCRefCounted<CefFrameHandlerCppToC,
CefFrameHandler,
cef_frame_handler_t> {
public:
CefFrameHandlerCppToC();
virtual ~CefFrameHandlerCppToC();
};
#endif // CEF_LIBCEF_DLL_CPPTOC_FRAME_HANDLER_CPPTOC_H_

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=7d80a2edec79db9cb7be6bc23a1103a9f55c66c1$
// $hash=48329460e314f041d387c854c47608fc04759d1c$
//
#include "libcef_dll/ctocpp/browser_ctocpp.h"
@ -21,6 +21,22 @@
// VIRTUAL METHODS - Body may be edited by hand.
NO_SANITIZE("cfi-icall") bool CefBrowserCToCpp::IsValid() {
shutdown_checker::AssertNotShutdown();
cef_browser_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, is_valid))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
int _retval = _struct->is_valid(_struct);
// Return type: bool
return _retval ? true : false;
}
NO_SANITIZE("cfi-icall") CefRefPtr<CefBrowserHost> CefBrowserCToCpp::GetHost() {
shutdown_checker::AssertNotShutdown();

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=0413031a4d40137ab08d1bd99af0216e88ebf6ea$
// $hash=b87b59400a1b0693d9f4ac37546c7d0ce5190ff7$
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_BROWSER_CTOCPP_H_
@ -36,6 +36,7 @@ class CefBrowserCToCpp
virtual ~CefBrowserCToCpp();
// CefBrowser methods.
bool IsValid() OVERRIDE;
CefRefPtr<CefBrowserHost> GetHost() OVERRIDE;
bool CanGoBack() OVERRIDE;
void GoBack() OVERRIDE;

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=19d21957d8b7f66de8c88b9085abb2a08718582d$
// $hash=9997fe1021600e4056a440521ead6e50354d08d6$
//
#include "libcef_dll/ctocpp/client_ctocpp.h"
@ -24,6 +24,7 @@
#include "libcef_dll/ctocpp/drag_handler_ctocpp.h"
#include "libcef_dll/ctocpp/find_handler_ctocpp.h"
#include "libcef_dll/ctocpp/focus_handler_ctocpp.h"
#include "libcef_dll/ctocpp/frame_handler_ctocpp.h"
#include "libcef_dll/ctocpp/jsdialog_handler_ctocpp.h"
#include "libcef_dll/ctocpp/keyboard_handler_ctocpp.h"
#include "libcef_dll/ctocpp/life_span_handler_ctocpp.h"
@ -155,6 +156,21 @@ CefRefPtr<CefFocusHandler> CefClientCToCpp::GetFocusHandler() {
return CefFocusHandlerCToCpp::Wrap(_retval);
}
NO_SANITIZE("cfi-icall")
CefRefPtr<CefFrameHandler> CefClientCToCpp::GetFrameHandler() {
cef_client_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, get_frame_handler))
return nullptr;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
cef_frame_handler_t* _retval = _struct->get_frame_handler(_struct);
// Return type: refptr_same
return CefFrameHandlerCToCpp::Wrap(_retval);
}
NO_SANITIZE("cfi-icall")
CefRefPtr<CefJSDialogHandler> CefClientCToCpp::GetJSDialogHandler() {
cef_client_t* _struct = GetStruct();

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=a640d4535140448a46340432470dbd1ef4f90b69$
// $hash=f40d1d693874952f5e05132f3a05029ea66e4451$
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_CLIENT_CTOCPP_H_
@ -41,6 +41,7 @@ class CefClientCToCpp
CefRefPtr<CefDragHandler> GetDragHandler() override;
CefRefPtr<CefFindHandler> GetFindHandler() override;
CefRefPtr<CefFocusHandler> GetFocusHandler() override;
CefRefPtr<CefFrameHandler> GetFrameHandler() override;
CefRefPtr<CefJSDialogHandler> GetJSDialogHandler() override;
CefRefPtr<CefKeyboardHandler> GetKeyboardHandler() override;
CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() override;

View File

@ -0,0 +1,145 @@
// Copyright (c) 2021 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.
//
// $hash=1b752686dc1743bed6957503b1cd6999f9a2a4f1$
//
#include "libcef_dll/ctocpp/frame_handler_ctocpp.h"
#include "libcef_dll/cpptoc/browser_cpptoc.h"
#include "libcef_dll/cpptoc/frame_cpptoc.h"
#include "libcef_dll/shutdown_checker.h"
// VIRTUAL METHODS - Body may be edited by hand.
NO_SANITIZE("cfi-icall")
void CefFrameHandlerCToCpp::OnFrameCreated(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame) {
shutdown_checker::AssertNotShutdown();
cef_frame_handler_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, on_frame_created))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return;
// Verify param: frame; type: refptr_diff
DCHECK(frame.get());
if (!frame.get())
return;
// Execute
_struct->on_frame_created(_struct, CefBrowserCppToC::Wrap(browser),
CefFrameCppToC::Wrap(frame));
}
NO_SANITIZE("cfi-icall")
void CefFrameHandlerCToCpp::OnFrameAttached(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame) {
shutdown_checker::AssertNotShutdown();
cef_frame_handler_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, on_frame_attached))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return;
// Verify param: frame; type: refptr_diff
DCHECK(frame.get());
if (!frame.get())
return;
// Execute
_struct->on_frame_attached(_struct, CefBrowserCppToC::Wrap(browser),
CefFrameCppToC::Wrap(frame));
}
NO_SANITIZE("cfi-icall")
void CefFrameHandlerCToCpp::OnFrameDetached(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame) {
shutdown_checker::AssertNotShutdown();
cef_frame_handler_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, on_frame_detached))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return;
// Verify param: frame; type: refptr_diff
DCHECK(frame.get());
if (!frame.get())
return;
// Execute
_struct->on_frame_detached(_struct, CefBrowserCppToC::Wrap(browser),
CefFrameCppToC::Wrap(frame));
}
NO_SANITIZE("cfi-icall")
void CefFrameHandlerCToCpp::OnMainFrameChanged(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> old_frame,
CefRefPtr<CefFrame> new_frame) {
shutdown_checker::AssertNotShutdown();
cef_frame_handler_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, on_main_frame_changed))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return;
// Unverified params: old_frame, new_frame
// Execute
_struct->on_main_frame_changed(_struct, CefBrowserCppToC::Wrap(browser),
CefFrameCppToC::Wrap(old_frame),
CefFrameCppToC::Wrap(new_frame));
}
// CONSTRUCTOR - Do not edit by hand.
CefFrameHandlerCToCpp::CefFrameHandlerCToCpp() {}
// DESTRUCTOR - Do not edit by hand.
CefFrameHandlerCToCpp::~CefFrameHandlerCToCpp() {
shutdown_checker::AssertNotShutdown();
}
template <>
cef_frame_handler_t*
CefCToCppRefCounted<CefFrameHandlerCToCpp,
CefFrameHandler,
cef_frame_handler_t>::UnwrapDerived(CefWrapperType type,
CefFrameHandler* c) {
NOTREACHED() << "Unexpected class type: " << type;
return nullptr;
}
template <>
CefWrapperType CefCToCppRefCounted<CefFrameHandlerCToCpp,
CefFrameHandler,
cef_frame_handler_t>::kWrapperType =
WT_FRAME_HANDLER;

View File

@ -0,0 +1,48 @@
// Copyright (c) 2021 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.
//
// $hash=d254c51cf1312313c462b034a42ff5ea95c41119$
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_FRAME_HANDLER_CTOCPP_H_
#define CEF_LIBCEF_DLL_CTOCPP_FRAME_HANDLER_CTOCPP_H_
#pragma once
#if !defined(BUILDING_CEF_SHARED)
#error This file can be included DLL-side only
#endif
#include "include/capi/cef_frame_handler_capi.h"
#include "include/cef_frame_handler.h"
#include "libcef_dll/ctocpp/ctocpp_ref_counted.h"
// Wrap a C structure with a C++ class.
// This class may be instantiated and accessed DLL-side only.
class CefFrameHandlerCToCpp : public CefCToCppRefCounted<CefFrameHandlerCToCpp,
CefFrameHandler,
cef_frame_handler_t> {
public:
CefFrameHandlerCToCpp();
virtual ~CefFrameHandlerCToCpp();
// CefFrameHandler methods.
void OnFrameCreated(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame) override;
void OnFrameAttached(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame) override;
void OnFrameDetached(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame) override;
void OnMainFrameChanged(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> old_frame,
CefRefPtr<CefFrame> new_frame) override;
};
#endif // CEF_LIBCEF_DLL_CTOCPP_FRAME_HANDLER_CTOCPP_H_

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=8e09f43f2c7faf35a14e7367b2156f4d4e89b74d$
// $hash=8b8237eb5b789df29937eaf46a231e0ca83d86c6$
//
#ifndef CEF_LIBCEF_DLL_WRAPPER_TYPES_H_
@ -65,6 +65,7 @@ enum CefWrapperType {
WT_FIND_HANDLER,
WT_FOCUS_HANDLER,
WT_FRAME,
WT_FRAME_HANDLER,
WT_GET_EXTENSION_RESOURCE_CALLBACK,
WT_IMAGE,
WT_JSDIALOG_CALLBACK,

File diff suppressed because it is too large Load Diff

View File

@ -57,7 +57,8 @@ class RoutingRenderDelegate : public ClientAppRenderer::Delegate {
} // namespace
RoutingTestHandler::RoutingTestHandler() {}
RoutingTestHandler::RoutingTestHandler(CompletionState* completion_state)
: TestHandler(completion_state) {}
void RoutingTestHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
if (!message_router_.get()) {

View File

@ -15,7 +15,7 @@
class RoutingTestHandler : public TestHandler,
public CefMessageRouterBrowserSide::Handler {
public:
RoutingTestHandler();
RoutingTestHandler(CompletionState* completion_state = nullptr);
void OnAfterCreated(CefRefPtr<CefBrowser> browser) override;
void OnBeforeClose(CefRefPtr<CefBrowser> browser) override;

View File

@ -276,11 +276,11 @@ void TestHandler::OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
LOG(WARNING) << "OnRenderProcessTerminated: status = " << status << ".";
}
CefRefPtr<CefBrowser> TestHandler::GetBrowser() {
CefRefPtr<CefBrowser> TestHandler::GetBrowser() const {
return first_browser_;
}
int TestHandler::GetBrowserId() {
int TestHandler::GetBrowserId() const {
return first_browser_id_;
}

View File

@ -181,8 +181,8 @@ class TestHandler : public CefClient,
TerminationStatus status) override;
// These methods should only be used if at most one non-popup browser exists.
CefRefPtr<CefBrowser> GetBrowser();
int GetBrowserId();
CefRefPtr<CefBrowser> GetBrowser() const;
int GetBrowserId() const;
// Copies the map of all the currently existing browsers into |map|. Must be
// called on the UI thread.