mirror of
				https://bitbucket.org/chromiumembedded/cef
				synced 2025-06-05 21:39:12 +02:00 
			
		
		
		
	This change moves the SendProcessMessage method from CefBrowser to CefFrame and adds CefBrowser parameters to OnProcessMessageReceived and OnDraggableRegionsChanged. The internal implementation has changed as follows: - Frame IDs are now a 64-bit combination of the 32-bit render_process_id and render_routing_id values that uniquely identify a RenderFrameHost (RFH). - CefFrameHostImpl objects are now managed by CefBrowserInfo with life span tied to RFH expectations. Specifically, a CefFrameHostImpl object representing a sub-frame will be created when a RenderFrame is created in the renderer process and detached when the associated RenderFrame is deleted or the renderer process in which it runs has died. - The CefFrameHostImpl object representing the main frame will always be valid but the underlying RFH (and associated frame ID) may change over time as a result of cross-origin navigations. Despite these changes calling LoadURL on the main frame object in the browser process will always navigate as expected. - Speculative RFHs, which may be created as a result of a cross-origin navigation and discarded if that navigation is not committed, are now handled correctly (e.g. ignored in most cases until they're committed). - It is less likely, but still possible, to receive a CefFrame object with an invalid frame ID (ID < 0). This can happen in cases where a RFH has not yet been created for a sub-frame. For example, when OnBeforeBrowse is called before initiating navigation in a previously nonexisting sub-frame. To test: All tests pass with NetworkService enabled and disabled.
		
			
				
	
	
		
			430 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			430 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// Copyright (c) 2014 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 are only available to applications that link
 | 
						|
// against the libcef_dll_wrapper target.
 | 
						|
//
 | 
						|
 | 
						|
#ifndef CEF_INCLUDE_WRAPPER_CEF_MESSAGE_ROUTER_H_
 | 
						|
#define CEF_INCLUDE_WRAPPER_CEF_MESSAGE_ROUTER_H_
 | 
						|
#pragma once
 | 
						|
 | 
						|
#include "include/base/cef_ref_counted.h"
 | 
						|
#include "include/cef_base.h"
 | 
						|
#include "include/cef_browser.h"
 | 
						|
#include "include/cef_process_message.h"
 | 
						|
#include "include/cef_v8.h"
 | 
						|
 | 
						|
// 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,
 | 
						|
// 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
 | 
						|
// instances.
 | 
						|
//
 | 
						|
// The renderer-side router implementation exposes a query function and a cancel
 | 
						|
// function via the JavaScript 'window' object:
 | 
						|
//
 | 
						|
//    // Create and send a new query.
 | 
						|
//    var request_id = window.cefQuery({
 | 
						|
//        request: 'my_request',
 | 
						|
//        persistent: false,
 | 
						|
//        onSuccess: function(response) {},
 | 
						|
//        onFailure: function(error_code, error_message) {}
 | 
						|
//    });
 | 
						|
//
 | 
						|
//    // Optionally cancel the query.
 | 
						|
//    window.cefQueryCancel(request_id);
 | 
						|
//
 | 
						|
// When |window.cefQuery| is executed the request is sent asynchronously to one
 | 
						|
// or more C++ Handler objects registered in the browser process. Each C++
 | 
						|
// Handler can choose to either handle or ignore the query in the
 | 
						|
// Handler::OnQuery callback. If a Handler chooses to handle the query then it
 | 
						|
// should execute Callback::Success when a response is available or
 | 
						|
// Callback::Failure if an error occurs. This will result in asynchronous
 | 
						|
// execution of the associated JavaScript callback in the renderer process. Any
 | 
						|
// queries unhandled by C++ code in the browser process will be automatically
 | 
						|
// canceled and the associated JavaScript onFailure callback will be executed
 | 
						|
// with an error code of -1.
 | 
						|
//
 | 
						|
// Queries can be either persistent or non-persistent. If the query is
 | 
						|
// persistent than the callbacks will remain registered until one of the
 | 
						|
// following conditions are met:
 | 
						|
//
 | 
						|
// A. The query is canceled in JavaScript using the |window.cefQueryCancel|
 | 
						|
//    function.
 | 
						|
// B. The query is canceled in C++ code using the Callback::Failure function.
 | 
						|
// C. The context associated with the query is released due to browser
 | 
						|
//    destruction, navigation or renderer process termination.
 | 
						|
//
 | 
						|
// If the query is non-persistent then the registration will be removed after
 | 
						|
// the JavaScript callback is executed a single time. If a query is canceled for
 | 
						|
// a reason other than Callback::Failure being executed then the associated
 | 
						|
// Handler's OnQueryCanceled method will be called.
 | 
						|
//
 | 
						|
// Some possible usage patterns include:
 | 
						|
//
 | 
						|
// One-time Request. Use a non-persistent query to send a JavaScript request.
 | 
						|
//    The Handler evaluates the request and returns the response. The query is
 | 
						|
//    then discarded.
 | 
						|
//
 | 
						|
// Broadcast. Use a persistent query to register as a JavaScript broadcast
 | 
						|
//    receiver. The Handler keeps track of all registered Callbacks and executes
 | 
						|
//    them sequentially to deliver the broadcast message.
 | 
						|
//
 | 
						|
// Subscription. Use a persistent query to register as a JavaScript subscription
 | 
						|
//    receiver. The Handler initiates the subscription feed on the first request
 | 
						|
//    and delivers responses to all registered subscribers as they become
 | 
						|
//    available. The Handler cancels the subscription feed when there are no
 | 
						|
//    longer any registered JavaScript receivers.
 | 
						|
//
 | 
						|
// Message routing occurs on a per-browser and per-context basis. Consequently,
 | 
						|
// additional application logic can be applied by restricting which browser or
 | 
						|
// context instances are passed into the router. If you choose to use this
 | 
						|
// approach do so cautiously. In order for the router to function correctly any
 | 
						|
// browser or context instance passed into a single router callback must then
 | 
						|
// be passed into all router callbacks.
 | 
						|
//
 | 
						|
// There is generally no need to have multiple renderer-side routers unless you
 | 
						|
// wish to have multiple bindings with different JavaScript function names. It
 | 
						|
// can be useful to have multiple browser-side routers with different client-
 | 
						|
// provided Handler instances when implementing different behaviors on a per-
 | 
						|
// browser basis.
 | 
						|
//
 | 
						|
// This implementation places no formatting restrictions on payload content.
 | 
						|
// An application may choose to exchange anything from simple formatted
 | 
						|
// strings to serialized XML or JSON data.
 | 
						|
//
 | 
						|
//
 | 
						|
// EXAMPLE USAGE
 | 
						|
//
 | 
						|
// 1. Define the router configuration. You can optionally specify settings
 | 
						|
//    like the JavaScript function names. The configuration must be the same in
 | 
						|
//    both the browser and renderer processes. If using multiple routers in the
 | 
						|
//    same application make sure to specify unique function names for each
 | 
						|
//    router configuration.
 | 
						|
//
 | 
						|
//    // Example config object showing the default values.
 | 
						|
//    CefMessageRouterConfig config;
 | 
						|
//    config.js_query_function = "cefQuery";
 | 
						|
//    config.js_cancel_function = "cefQueryCancel";
 | 
						|
//
 | 
						|
// 2. Create an instance of CefMessageRouterBrowserSide in the browser process.
 | 
						|
//    You might choose to make it a member of your CefClient implementation,
 | 
						|
//    for example.
 | 
						|
//
 | 
						|
//    browser_side_router_ = CefMessageRouterBrowserSide::Create(config);
 | 
						|
//
 | 
						|
// 3. Register one or more Handlers. The Handler instances must either outlive
 | 
						|
//    the router or be removed from the router before they're deleted.
 | 
						|
//
 | 
						|
//    browser_side_router_->AddHandler(my_handler);
 | 
						|
//
 | 
						|
// 4. Call all required CefMessageRouterBrowserSide methods from other callbacks
 | 
						|
//    in your CefClient implementation (OnBeforeClose, etc). See the
 | 
						|
//    CefMessageRouterBrowserSide class documentation for the complete list of
 | 
						|
//    methods.
 | 
						|
//
 | 
						|
// 5. Create an instance of CefMessageRouterRendererSide in the renderer
 | 
						|
// process.
 | 
						|
//    You might choose to make it a member of your CefApp implementation, for
 | 
						|
//    example.
 | 
						|
//
 | 
						|
//    renderer_side_router_ = CefMessageRouterRendererSide::Create(config);
 | 
						|
//
 | 
						|
// 6. Call all required CefMessageRouterRendererSide methods from other
 | 
						|
//    callbacks in your CefRenderProcessHandler implementation
 | 
						|
//    (OnContextCreated, etc). See the CefMessageRouterRendererSide class
 | 
						|
//    documentation for the complete list of methods.
 | 
						|
//
 | 
						|
// 7. Execute the query function from JavaScript code.
 | 
						|
//
 | 
						|
//    window.cefQuery({request: 'my_request',
 | 
						|
//                     persistent: false,
 | 
						|
//                     onSuccess: function(response) { print(response); },
 | 
						|
//                     onFailure: function(error_code, error_message) {} });
 | 
						|
//
 | 
						|
// 8. Handle the query in your Handler::OnQuery implementation and execute the
 | 
						|
//    appropriate callback either immediately or asynchronously.
 | 
						|
//
 | 
						|
//    void MyHandler::OnQuery(int64 query_id,
 | 
						|
//                            CefRefPtr<CefBrowser> browser,
 | 
						|
//                            CefRefPtr<CefFrame> frame,
 | 
						|
//                            const CefString& request,
 | 
						|
//                            bool persistent,
 | 
						|
//                            CefRefPtr<Callback> callback) {
 | 
						|
//      if (request == "my_request") {
 | 
						|
//        callback->Continue("my_response");
 | 
						|
//        return true;
 | 
						|
//      }
 | 
						|
//      return false;  // Not handled.
 | 
						|
//    }
 | 
						|
//
 | 
						|
// 9. Notice that the onSuccess callback is executed in JavaScript.
 | 
						|
 | 
						|
///
 | 
						|
// Used to configure the query router. The same values must be passed to both
 | 
						|
// CefMessageRouterBrowserSide and CefMessageRouterRendererSide. If using
 | 
						|
// multiple router pairs make sure to choose values that do not conflict.
 | 
						|
///
 | 
						|
struct CefMessageRouterConfig {
 | 
						|
  CefMessageRouterConfig();
 | 
						|
 | 
						|
  // Name of the JavaScript function that will be added to the 'window' object
 | 
						|
  // for sending a query. The default value is "cefQuery".
 | 
						|
  CefString js_query_function;
 | 
						|
 | 
						|
  // Name of the JavaScript function that will be added to the 'window' object
 | 
						|
  // for canceling a pending query. The default value is "cefQueryCancel".
 | 
						|
  CefString js_cancel_function;
 | 
						|
};
 | 
						|
 | 
						|
///
 | 
						|
// Implements the browser side of query routing. The methods of this class may
 | 
						|
// be called on any browser process thread unless otherwise indicated.
 | 
						|
///
 | 
						|
class CefMessageRouterBrowserSide
 | 
						|
    : public base::RefCountedThreadSafe<CefMessageRouterBrowserSide> {
 | 
						|
 public:
 | 
						|
  ///
 | 
						|
  // Callback associated with a single pending asynchronous query. Execute the
 | 
						|
  // Success or Failure method to send an asynchronous response to the
 | 
						|
  // associated JavaScript handler. It is a runtime error to destroy a Callback
 | 
						|
  // object associated with an uncanceled query without first executing one of
 | 
						|
  // the callback methods. The methods of this class may be called on any
 | 
						|
  // browser process thread.
 | 
						|
  ///
 | 
						|
  class Callback : public CefBaseRefCounted {
 | 
						|
   public:
 | 
						|
    ///
 | 
						|
    // Notify the associated JavaScript onSuccess callback that the query has
 | 
						|
    // completed successfully with the specified |response|.
 | 
						|
    ///
 | 
						|
    virtual void Success(const CefString& response) = 0;
 | 
						|
 | 
						|
    ///
 | 
						|
    // Notify the associated JavaScript onFailure callback that the query has
 | 
						|
    // failed with the specified |error_code| and |error_message|.
 | 
						|
    ///
 | 
						|
    virtual void Failure(int error_code, const CefString& error_message) = 0;
 | 
						|
  };
 | 
						|
 | 
						|
  ///
 | 
						|
  // Implement this interface to handle queries. All methods will be executed on
 | 
						|
  // the browser process UI thread.
 | 
						|
  ///
 | 
						|
  class Handler {
 | 
						|
   public:
 | 
						|
    typedef CefMessageRouterBrowserSide::Callback Callback;
 | 
						|
 | 
						|
    ///
 | 
						|
    // Executed when a new query is received. |query_id| uniquely identifies the
 | 
						|
    // query for the life span of the router. Return true to handle the query
 | 
						|
    // or false to propagate the query to other registered handlers, if any. If
 | 
						|
    // no handlers return true from this method then the query will be
 | 
						|
    // automatically canceled with an error code of -1 delivered to the
 | 
						|
    // JavaScript onFailure callback. If this method returns true then a
 | 
						|
    // Callback method must be executed either in this method or asynchronously
 | 
						|
    // to complete the query.
 | 
						|
    ///
 | 
						|
    virtual bool OnQuery(CefRefPtr<CefBrowser> browser,
 | 
						|
                         CefRefPtr<CefFrame> frame,
 | 
						|
                         int64 query_id,
 | 
						|
                         const CefString& request,
 | 
						|
                         bool persistent,
 | 
						|
                         CefRefPtr<Callback> callback) {
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
 | 
						|
    ///
 | 
						|
    // Executed when a query has been canceled either explicitly using the
 | 
						|
    // JavaScript cancel function or implicitly due to browser destruction,
 | 
						|
    // navigation or renderer process termination. It will only be called for
 | 
						|
    // the single handler that returned true from OnQuery for the same
 | 
						|
    // |query_id|. No references to the associated Callback object should be
 | 
						|
    // kept after this method is called, nor should any Callback methods be
 | 
						|
    // executed.
 | 
						|
    ///
 | 
						|
    virtual void OnQueryCanceled(CefRefPtr<CefBrowser> browser,
 | 
						|
                                 CefRefPtr<CefFrame> frame,
 | 
						|
                                 int64 query_id) {}
 | 
						|
 | 
						|
    virtual ~Handler() {}
 | 
						|
  };
 | 
						|
 | 
						|
  ///
 | 
						|
  // Create a new router with the specified configuration.
 | 
						|
  ///
 | 
						|
  static CefRefPtr<CefMessageRouterBrowserSide> Create(
 | 
						|
      const CefMessageRouterConfig& config);
 | 
						|
 | 
						|
  ///
 | 
						|
  // Add a new query handler. If |first| is true it will be added as the first
 | 
						|
  // handler, otherwise it will be added as the last handler. Returns true if
 | 
						|
  // the handler is added successfully or false if the handler has already been
 | 
						|
  // added. Must be called on the browser process UI thread. The Handler object
 | 
						|
  // must either outlive the router or be removed before deletion.
 | 
						|
  ///
 | 
						|
  virtual bool AddHandler(Handler* handler, bool first) = 0;
 | 
						|
 | 
						|
  ///
 | 
						|
  // Remove an existing query handler. Any pending queries associated with the
 | 
						|
  // handler will be canceled. Handler::OnQueryCanceled will be called and the
 | 
						|
  // associated JavaScript onFailure callback will be executed with an error
 | 
						|
  // code of -1. Returns true if the handler is removed successfully or false
 | 
						|
  // if the handler is not found. Must be called on the browser process UI
 | 
						|
  // thread.
 | 
						|
  ///
 | 
						|
  virtual bool RemoveHandler(Handler* handler) = 0;
 | 
						|
 | 
						|
  ///
 | 
						|
  // Cancel all pending queries associated with either |browser| or |handler|.
 | 
						|
  // If both |browser| and |handler| are NULL all pending queries will be
 | 
						|
  // canceled. Handler::OnQueryCanceled will be called and the associated
 | 
						|
  // JavaScript onFailure callback will be executed in all cases with an error
 | 
						|
  // code of -1.
 | 
						|
  ///
 | 
						|
  virtual void CancelPending(CefRefPtr<CefBrowser> browser,
 | 
						|
                             Handler* handler) = 0;
 | 
						|
 | 
						|
  ///
 | 
						|
  // Returns the number of queries currently pending for the specified |browser|
 | 
						|
  // and/or |handler|. Either or both values may be empty. Must be called on the
 | 
						|
  // browser process UI thread.
 | 
						|
  ///
 | 
						|
  virtual int GetPendingCount(CefRefPtr<CefBrowser> browser,
 | 
						|
                              Handler* handler) = 0;
 | 
						|
 | 
						|
  // The below methods should be called from other CEF handlers. They must be
 | 
						|
  // called exactly as documented for the router to function correctly.
 | 
						|
 | 
						|
  ///
 | 
						|
  // Call from CefLifeSpanHandler::OnBeforeClose. Any pending queries associated
 | 
						|
  // with |browser| will be canceled and Handler::OnQueryCanceled will be
 | 
						|
  // called. No JavaScript callbacks will be executed since this indicates
 | 
						|
  // destruction of the browser.
 | 
						|
  ///
 | 
						|
  virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) = 0;
 | 
						|
 | 
						|
  ///
 | 
						|
  // Call from CefRequestHandler::OnRenderProcessTerminated. Any pending queries
 | 
						|
  // associated with |browser| will be canceled and Handler::OnQueryCanceled
 | 
						|
  // will be called. No JavaScript callbacks will be executed since this
 | 
						|
  // indicates destruction of the context.
 | 
						|
  ///
 | 
						|
  virtual void OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser) = 0;
 | 
						|
 | 
						|
  ///
 | 
						|
  // Call from CefRequestHandler::OnBeforeBrowse only if the navigation is
 | 
						|
  // allowed to proceed. If |frame| is the main frame then any pending queries
 | 
						|
  // associated with |browser| will be canceled and Handler::OnQueryCanceled
 | 
						|
  // will be called. No JavaScript callbacks will be executed since this
 | 
						|
  // indicates destruction of the context.
 | 
						|
  ///
 | 
						|
  virtual void OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
 | 
						|
                              CefRefPtr<CefFrame> frame) = 0;
 | 
						|
 | 
						|
  ///
 | 
						|
  // Call from CefClient::OnProcessMessageReceived. Returns true if the message
 | 
						|
  // is handled by this router or false otherwise.
 | 
						|
  ///
 | 
						|
  virtual bool OnProcessMessageReceived(
 | 
						|
      CefRefPtr<CefBrowser> browser,
 | 
						|
      CefRefPtr<CefFrame> frame,
 | 
						|
      CefProcessId source_process,
 | 
						|
      CefRefPtr<CefProcessMessage> message) = 0;
 | 
						|
 | 
						|
 protected:
 | 
						|
  // Protect against accidental deletion of this object.
 | 
						|
  friend class base::RefCountedThreadSafe<CefMessageRouterBrowserSide>;
 | 
						|
  virtual ~CefMessageRouterBrowserSide() {}
 | 
						|
};
 | 
						|
 | 
						|
///
 | 
						|
// Implements the renderer side of query routing. The methods of this class must
 | 
						|
// be called on the render process main thread.
 | 
						|
///
 | 
						|
class CefMessageRouterRendererSide
 | 
						|
    : public base::RefCountedThreadSafe<CefMessageRouterRendererSide> {
 | 
						|
 public:
 | 
						|
  ///
 | 
						|
  // Create a new router with the specified configuration.
 | 
						|
  ///
 | 
						|
  static CefRefPtr<CefMessageRouterRendererSide> Create(
 | 
						|
      const CefMessageRouterConfig& config);
 | 
						|
 | 
						|
  ///
 | 
						|
  // Returns the number of queries currently pending for the specified |browser|
 | 
						|
  // and/or |context|. Either or both values may be empty.
 | 
						|
  ///
 | 
						|
  virtual int GetPendingCount(CefRefPtr<CefBrowser> browser,
 | 
						|
                              CefRefPtr<CefV8Context> context) = 0;
 | 
						|
 | 
						|
  // The below methods should be called from other CEF handlers. They must be
 | 
						|
  // called exactly as documented for the router to function correctly.
 | 
						|
 | 
						|
  ///
 | 
						|
  // Call from CefRenderProcessHandler::OnContextCreated. Registers the
 | 
						|
  // JavaScripts functions with the new context.
 | 
						|
  ///
 | 
						|
  virtual void OnContextCreated(CefRefPtr<CefBrowser> browser,
 | 
						|
                                CefRefPtr<CefFrame> frame,
 | 
						|
                                CefRefPtr<CefV8Context> context) = 0;
 | 
						|
 | 
						|
  ///
 | 
						|
  // Call from CefRenderProcessHandler::OnContextReleased. Any pending queries
 | 
						|
  // associated with the released context will be canceled and
 | 
						|
  // Handler::OnQueryCanceled will be called in the browser process.
 | 
						|
  ///
 | 
						|
  virtual void OnContextReleased(CefRefPtr<CefBrowser> browser,
 | 
						|
                                 CefRefPtr<CefFrame> frame,
 | 
						|
                                 CefRefPtr<CefV8Context> context) = 0;
 | 
						|
 | 
						|
  ///
 | 
						|
  // Call from CefRenderProcessHandler::OnProcessMessageReceived. Returns true
 | 
						|
  // if the message is handled by this router or false otherwise.
 | 
						|
  ///
 | 
						|
  virtual bool OnProcessMessageReceived(
 | 
						|
      CefRefPtr<CefBrowser> browser,
 | 
						|
      CefRefPtr<CefFrame> frame,
 | 
						|
      CefProcessId source_process,
 | 
						|
      CefRefPtr<CefProcessMessage> message) = 0;
 | 
						|
 | 
						|
 protected:
 | 
						|
  // Protect against accidental deletion of this object.
 | 
						|
  friend class base::RefCountedThreadSafe<CefMessageRouterRendererSide>;
 | 
						|
  virtual ~CefMessageRouterRendererSide() {}
 | 
						|
};
 | 
						|
 | 
						|
#endif  // CEF_INCLUDE_WRAPPER_CEF_MESSAGE_ROUTER_H_
 |