mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Add a shared memory variant of CefProcessMessage (fixes issue #3126)
CefSharedProcessMessageBuilder supports creation of a CefProcessMessage backed by a CefSharedMemoryRegion. Performance tests comparing the existing ArgumentList approach and the new SharedMemoryRegion approach have been added to cefclient at http://tests/ipc_performance. CefMessageRouter has been updated to use SharedMemoryRegion as transport for larger message payloads. The threshold is configurable via |CefMessageRouterConfig.message_size_threshold|. To test: run `ceftests --gtest_filter=SendSharedProcessMessageTest.*:SharedProcessMessageTest.*:MessageRouterTest.Threshold*`
This commit is contained in:
committed by
Marshall Greenblatt
parent
a931d49f3e
commit
81e892d19e
2
BUILD.gn
2
BUILD.gn
@ -814,6 +814,8 @@ static_library("libcef_static") {
|
|||||||
"libcef/common/parser_impl.cc",
|
"libcef/common/parser_impl.cc",
|
||||||
"libcef/common/process_message_impl.cc",
|
"libcef/common/process_message_impl.cc",
|
||||||
"libcef/common/process_message_impl.h",
|
"libcef/common/process_message_impl.h",
|
||||||
|
"libcef/common/process_message_smr_impl.cc",
|
||||||
|
"libcef/common/process_message_smr_impl.h",
|
||||||
"libcef/common/request_impl.cc",
|
"libcef/common/request_impl.cc",
|
||||||
"libcef/common/request_impl.h",
|
"libcef/common/request_impl.h",
|
||||||
"libcef/common/resource_bundle_delegate.cc",
|
"libcef/common/resource_bundle_delegate.cc",
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
# by hand. See the translator.README.txt file in the tools directory for
|
# by hand. See the translator.README.txt file in the tools directory for
|
||||||
# more information.
|
# more information.
|
||||||
#
|
#
|
||||||
# $hash=f8ae899cc69a48e9878fa4db2fcc3b7e54230062$
|
# $hash=f374acb217db4183917195716d5522a9eb897cdf$
|
||||||
#
|
#
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -75,6 +75,8 @@
|
|||||||
'include/cef_response_filter.h',
|
'include/cef_response_filter.h',
|
||||||
'include/cef_scheme.h',
|
'include/cef_scheme.h',
|
||||||
'include/cef_server.h',
|
'include/cef_server.h',
|
||||||
|
'include/cef_shared_memory_region.h',
|
||||||
|
'include/cef_shared_process_message_builder.h',
|
||||||
'include/cef_ssl_info.h',
|
'include/cef_ssl_info.h',
|
||||||
'include/cef_ssl_status.h',
|
'include/cef_ssl_status.h',
|
||||||
'include/cef_stream.h',
|
'include/cef_stream.h',
|
||||||
@ -175,6 +177,8 @@
|
|||||||
'include/capi/cef_response_filter_capi.h',
|
'include/capi/cef_response_filter_capi.h',
|
||||||
'include/capi/cef_scheme_capi.h',
|
'include/capi/cef_scheme_capi.h',
|
||||||
'include/capi/cef_server_capi.h',
|
'include/capi/cef_server_capi.h',
|
||||||
|
'include/capi/cef_shared_memory_region_capi.h',
|
||||||
|
'include/capi/cef_shared_process_message_builder_capi.h',
|
||||||
'include/capi/cef_ssl_info_capi.h',
|
'include/capi/cef_ssl_info_capi.h',
|
||||||
'include/capi/cef_ssl_status_capi.h',
|
'include/capi/cef_ssl_status_capi.h',
|
||||||
'include/capi/cef_stream_capi.h',
|
'include/capi/cef_stream_capi.h',
|
||||||
@ -442,6 +446,10 @@
|
|||||||
'libcef_dll/ctocpp/server_handler_ctocpp.h',
|
'libcef_dll/ctocpp/server_handler_ctocpp.h',
|
||||||
'libcef_dll/ctocpp/set_cookie_callback_ctocpp.cc',
|
'libcef_dll/ctocpp/set_cookie_callback_ctocpp.cc',
|
||||||
'libcef_dll/ctocpp/set_cookie_callback_ctocpp.h',
|
'libcef_dll/ctocpp/set_cookie_callback_ctocpp.h',
|
||||||
|
'libcef_dll/cpptoc/shared_memory_region_cpptoc.cc',
|
||||||
|
'libcef_dll/cpptoc/shared_memory_region_cpptoc.h',
|
||||||
|
'libcef_dll/cpptoc/shared_process_message_builder_cpptoc.cc',
|
||||||
|
'libcef_dll/cpptoc/shared_process_message_builder_cpptoc.h',
|
||||||
'libcef_dll/cpptoc/stream_reader_cpptoc.cc',
|
'libcef_dll/cpptoc/stream_reader_cpptoc.cc',
|
||||||
'libcef_dll/cpptoc/stream_reader_cpptoc.h',
|
'libcef_dll/cpptoc/stream_reader_cpptoc.h',
|
||||||
'libcef_dll/cpptoc/stream_writer_cpptoc.cc',
|
'libcef_dll/cpptoc/stream_writer_cpptoc.cc',
|
||||||
@ -754,6 +762,10 @@
|
|||||||
'libcef_dll/cpptoc/server_handler_cpptoc.h',
|
'libcef_dll/cpptoc/server_handler_cpptoc.h',
|
||||||
'libcef_dll/cpptoc/set_cookie_callback_cpptoc.cc',
|
'libcef_dll/cpptoc/set_cookie_callback_cpptoc.cc',
|
||||||
'libcef_dll/cpptoc/set_cookie_callback_cpptoc.h',
|
'libcef_dll/cpptoc/set_cookie_callback_cpptoc.h',
|
||||||
|
'libcef_dll/ctocpp/shared_memory_region_ctocpp.cc',
|
||||||
|
'libcef_dll/ctocpp/shared_memory_region_ctocpp.h',
|
||||||
|
'libcef_dll/ctocpp/shared_process_message_builder_ctocpp.cc',
|
||||||
|
'libcef_dll/ctocpp/shared_process_message_builder_ctocpp.h',
|
||||||
'libcef_dll/ctocpp/stream_reader_ctocpp.cc',
|
'libcef_dll/ctocpp/stream_reader_ctocpp.cc',
|
||||||
'libcef_dll/ctocpp/stream_reader_ctocpp.h',
|
'libcef_dll/ctocpp/stream_reader_ctocpp.h',
|
||||||
'libcef_dll/ctocpp/stream_writer_ctocpp.cc',
|
'libcef_dll/ctocpp/stream_writer_ctocpp.cc',
|
||||||
|
@ -177,6 +177,8 @@
|
|||||||
'tests/shared/browser/resource_util.h',
|
'tests/shared/browser/resource_util.h',
|
||||||
],
|
],
|
||||||
'shared_sources_common': [
|
'shared_sources_common': [
|
||||||
|
'tests/shared/common/binary_value_utils.cc',
|
||||||
|
'tests/shared/common/binary_value_utils.h',
|
||||||
'tests/shared/common/client_app.cc',
|
'tests/shared/common/client_app.cc',
|
||||||
'tests/shared/common/client_app.h',
|
'tests/shared/common/client_app.h',
|
||||||
'tests/shared/common/client_app_other.cc',
|
'tests/shared/common/client_app_other.cc',
|
||||||
@ -289,6 +291,8 @@
|
|||||||
'tests/cefclient/renderer/client_app_delegates_renderer.cc',
|
'tests/cefclient/renderer/client_app_delegates_renderer.cc',
|
||||||
'tests/cefclient/renderer/client_renderer.cc',
|
'tests/cefclient/renderer/client_renderer.cc',
|
||||||
'tests/cefclient/renderer/client_renderer.h',
|
'tests/cefclient/renderer/client_renderer.h',
|
||||||
|
'tests/cefclient/renderer/ipc_performance_test.cc',
|
||||||
|
'tests/cefclient/renderer/ipc_performance_test.h',
|
||||||
'tests/cefclient/renderer/performance_test.cc',
|
'tests/cefclient/renderer/performance_test.cc',
|
||||||
'tests/cefclient/renderer/performance_test.h',
|
'tests/cefclient/renderer/performance_test.h',
|
||||||
'tests/cefclient/renderer/performance_test_setup.h',
|
'tests/cefclient/renderer/performance_test_setup.h',
|
||||||
@ -298,6 +302,7 @@
|
|||||||
'tests/cefclient/resources/binding.html',
|
'tests/cefclient/resources/binding.html',
|
||||||
'tests/cefclient/resources/dialogs.html',
|
'tests/cefclient/resources/dialogs.html',
|
||||||
'tests/cefclient/resources/draggable.html',
|
'tests/cefclient/resources/draggable.html',
|
||||||
|
'tests/cefclient/resources/ipc_performance.html',
|
||||||
'tests/cefclient/resources/localstorage.html',
|
'tests/cefclient/resources/localstorage.html',
|
||||||
'tests/cefclient/resources/logo.png',
|
'tests/cefclient/resources/logo.png',
|
||||||
'tests/cefclient/resources/media_router.html',
|
'tests/cefclient/resources/media_router.html',
|
||||||
@ -476,7 +481,12 @@
|
|||||||
'tests/ceftests/jsdialog_unittest.cc',
|
'tests/ceftests/jsdialog_unittest.cc',
|
||||||
'tests/ceftests/life_span_unittest.cc',
|
'tests/ceftests/life_span_unittest.cc',
|
||||||
'tests/ceftests/media_access_unittest.cc',
|
'tests/ceftests/media_access_unittest.cc',
|
||||||
'tests/ceftests/message_router_unittest.cc',
|
'tests/ceftests/message_router_harness_unittest.cc',
|
||||||
|
'tests/ceftests/message_router_multi_query_unittest.cc',
|
||||||
|
'tests/ceftests/message_router_single_query_unittest.cc',
|
||||||
|
'tests/ceftests/message_router_threshold_unittest.cc',
|
||||||
|
'tests/ceftests/message_router_unittest_utils.cc',
|
||||||
|
'tests/ceftests/message_router_unittest_utils.h',
|
||||||
'tests/ceftests/navigation_unittest.cc',
|
'tests/ceftests/navigation_unittest.cc',
|
||||||
'tests/ceftests/os_rendering_unittest.cc',
|
'tests/ceftests/os_rendering_unittest.cc',
|
||||||
'tests/ceftests/osr_accessibility_unittest.cc',
|
'tests/ceftests/osr_accessibility_unittest.cc',
|
||||||
@ -499,6 +509,8 @@
|
|||||||
'tests/ceftests/scheme_handler_unittest.cc',
|
'tests/ceftests/scheme_handler_unittest.cc',
|
||||||
'tests/ceftests/scoped_temp_dir_unittest.cc',
|
'tests/ceftests/scoped_temp_dir_unittest.cc',
|
||||||
'tests/ceftests/server_unittest.cc',
|
'tests/ceftests/server_unittest.cc',
|
||||||
|
'tests/ceftests/send_shared_process_message_unittest.cc',
|
||||||
|
"tests/ceftests/shared_process_message_unittest.cc",
|
||||||
'tests/ceftests/stream_unittest.cc',
|
'tests/ceftests/stream_unittest.cc',
|
||||||
'tests/ceftests/stream_resource_handler_unittest.cc',
|
'tests/ceftests/stream_resource_handler_unittest.cc',
|
||||||
'tests/ceftests/string_unittest.cc',
|
'tests/ceftests/string_unittest.cc',
|
||||||
@ -564,7 +576,12 @@
|
|||||||
'tests/ceftests/dom_unittest.cc',
|
'tests/ceftests/dom_unittest.cc',
|
||||||
'tests/ceftests/frame_unittest.cc',
|
'tests/ceftests/frame_unittest.cc',
|
||||||
'tests/ceftests/media_access_unittest.cc',
|
'tests/ceftests/media_access_unittest.cc',
|
||||||
'tests/ceftests/message_router_unittest.cc',
|
'tests/ceftests/message_router_harness_unittest.cc',
|
||||||
|
'tests/ceftests/message_router_multi_query_unittest.cc',
|
||||||
|
'tests/ceftests/message_router_single_query_unittest.cc',
|
||||||
|
'tests/ceftests/message_router_threshold_unittest.cc',
|
||||||
|
'tests/ceftests/message_router_unittest_utils.cc',
|
||||||
|
'tests/ceftests/message_router_unittest_utils.h',
|
||||||
'tests/ceftests/navigation_unittest.cc',
|
'tests/ceftests/navigation_unittest.cc',
|
||||||
'tests/ceftests/pdf_viewer_unittest.cc',
|
'tests/ceftests/pdf_viewer_unittest.cc',
|
||||||
'tests/ceftests/preference_unittest.cc',
|
'tests/ceftests/preference_unittest.cc',
|
||||||
@ -576,6 +593,8 @@
|
|||||||
'tests/ceftests/routing_test_handler.cc',
|
'tests/ceftests/routing_test_handler.cc',
|
||||||
'tests/ceftests/routing_test_handler.h',
|
'tests/ceftests/routing_test_handler.h',
|
||||||
'tests/ceftests/scheme_handler_unittest.cc',
|
'tests/ceftests/scheme_handler_unittest.cc',
|
||||||
|
'tests/ceftests/send_shared_process_message_unittest.cc',
|
||||||
|
"tests/ceftests/shared_process_message_unittest.cc",
|
||||||
'tests/ceftests/urlrequest_unittest.cc',
|
'tests/ceftests/urlrequest_unittest.cc',
|
||||||
'tests/ceftests/test_handler.cc',
|
'tests/ceftests/test_handler.cc',
|
||||||
'tests/ceftests/test_handler.h',
|
'tests/ceftests/test_handler.h',
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
// by hand. See the translator.README.txt file in the tools directory for
|
// by hand. See the translator.README.txt file in the tools directory for
|
||||||
// more information.
|
// more information.
|
||||||
//
|
//
|
||||||
// $hash=2549ea10cd3a41bc04ab81bad24eb12787de68b9$
|
// $hash=026a7f827962222a1df8b62a8e7bdfbf4dce27e0$
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef CEF_INCLUDE_CAPI_CEF_PROCESS_MESSAGE_CAPI_H_
|
#ifndef CEF_INCLUDE_CAPI_CEF_PROCESS_MESSAGE_CAPI_H_
|
||||||
@ -41,6 +41,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "include/capi/cef_base_capi.h"
|
#include "include/capi/cef_base_capi.h"
|
||||||
|
#include "include/capi/cef_shared_memory_region_capi.h"
|
||||||
#include "include/capi/cef_values_capi.h"
|
#include "include/capi/cef_values_capi.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -69,7 +70,8 @@ typedef struct _cef_process_message_t {
|
|||||||
int(CEF_CALLBACK* is_read_only)(struct _cef_process_message_t* self);
|
int(CEF_CALLBACK* is_read_only)(struct _cef_process_message_t* self);
|
||||||
|
|
||||||
///
|
///
|
||||||
// Returns a writable copy of this object.
|
// Returns a writable copy of this object. Returns nullptr when message
|
||||||
|
// contains a shared memory region.
|
||||||
///
|
///
|
||||||
struct _cef_process_message_t*(CEF_CALLBACK* copy)(
|
struct _cef_process_message_t*(CEF_CALLBACK* copy)(
|
||||||
struct _cef_process_message_t* self);
|
struct _cef_process_message_t* self);
|
||||||
@ -82,10 +84,18 @@ typedef struct _cef_process_message_t {
|
|||||||
struct _cef_process_message_t* self);
|
struct _cef_process_message_t* self);
|
||||||
|
|
||||||
///
|
///
|
||||||
// Returns the list of arguments.
|
// Returns the list of arguments. Returns nullptr when message contains a
|
||||||
|
// shared memory region.
|
||||||
///
|
///
|
||||||
struct _cef_list_value_t*(CEF_CALLBACK* get_argument_list)(
|
struct _cef_list_value_t*(CEF_CALLBACK* get_argument_list)(
|
||||||
struct _cef_process_message_t* self);
|
struct _cef_process_message_t* self);
|
||||||
|
|
||||||
|
///
|
||||||
|
// Returns the shared memory region. Returns nullptr when message contains an
|
||||||
|
// argument list.
|
||||||
|
///
|
||||||
|
struct _cef_shared_memory_region_t*(CEF_CALLBACK* get_shared_memory_region)(
|
||||||
|
struct _cef_process_message_t* self);
|
||||||
} cef_process_message_t;
|
} cef_process_message_t;
|
||||||
|
|
||||||
///
|
///
|
||||||
|
79
include/capi/cef_shared_memory_region_capi.h
Normal file
79
include/capi/cef_shared_memory_region_capi.h
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
// Copyright (c) 2022 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=212f13ac6baeeefb86f1648d1e18ccba95fd5f79$
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef CEF_INCLUDE_CAPI_CEF_SHARED_MEMORY_REGION_CAPI_H_
|
||||||
|
#define CEF_INCLUDE_CAPI_CEF_SHARED_MEMORY_REGION_CAPI_H_
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "include/capi/cef_base_capi.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
///
|
||||||
|
// Structure that wraps platform-dependent share memory region mapping.
|
||||||
|
///
|
||||||
|
typedef struct _cef_shared_memory_region_t {
|
||||||
|
///
|
||||||
|
// Base structure.
|
||||||
|
///
|
||||||
|
cef_base_ref_counted_t base;
|
||||||
|
|
||||||
|
///
|
||||||
|
// Returns true (1) if the mapping is valid.
|
||||||
|
///
|
||||||
|
int(CEF_CALLBACK* is_valid)(struct _cef_shared_memory_region_t* self);
|
||||||
|
|
||||||
|
///
|
||||||
|
// Returns the size of the mapping in bytes. Returns 0 for invalid instances.
|
||||||
|
///
|
||||||
|
size_t(CEF_CALLBACK* size)(struct _cef_shared_memory_region_t* self);
|
||||||
|
|
||||||
|
///
|
||||||
|
// Returns the pointer to the memory. Returns nullptr for invalid instances.
|
||||||
|
// The returned pointer is only valid for the life span of this object.
|
||||||
|
///
|
||||||
|
const void*(CEF_CALLBACK* memory)(struct _cef_shared_memory_region_t* self);
|
||||||
|
} cef_shared_memory_region_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // CEF_INCLUDE_CAPI_CEF_SHARED_MEMORY_REGION_CAPI_H_
|
101
include/capi/cef_shared_process_message_builder_capi.h
Normal file
101
include/capi/cef_shared_process_message_builder_capi.h
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
// Copyright (c) 2022 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=0ed88d26dab045ebef0f4f4ae209e7f11206a242$
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef CEF_INCLUDE_CAPI_CEF_SHARED_PROCESS_MESSAGE_BUILDER_CAPI_H_
|
||||||
|
#define CEF_INCLUDE_CAPI_CEF_SHARED_PROCESS_MESSAGE_BUILDER_CAPI_H_
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "include/capi/cef_process_message_capi.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
///
|
||||||
|
// Structure that builds a cef_process_message_t containing a shared memory
|
||||||
|
// region. This structure is not thread-safe but may be used exclusively on a
|
||||||
|
// different thread from the one which constructed it.
|
||||||
|
///
|
||||||
|
typedef struct _cef_shared_process_message_builder_t {
|
||||||
|
///
|
||||||
|
// Base structure.
|
||||||
|
///
|
||||||
|
cef_base_ref_counted_t base;
|
||||||
|
|
||||||
|
///
|
||||||
|
// Returns true (1) if the builder is valid.
|
||||||
|
///
|
||||||
|
int(CEF_CALLBACK* is_valid)(
|
||||||
|
struct _cef_shared_process_message_builder_t* self);
|
||||||
|
|
||||||
|
///
|
||||||
|
// Returns the size of the shared memory region in bytes. Returns 0 for
|
||||||
|
// invalid instances.
|
||||||
|
///
|
||||||
|
size_t(CEF_CALLBACK* size)(
|
||||||
|
struct _cef_shared_process_message_builder_t* self);
|
||||||
|
|
||||||
|
///
|
||||||
|
// Returns the pointer to the writable memory. Returns nullptr for invalid
|
||||||
|
// instances. The returned pointer is only valid for the life span of this
|
||||||
|
// object.
|
||||||
|
///
|
||||||
|
void*(CEF_CALLBACK* memory)(
|
||||||
|
struct _cef_shared_process_message_builder_t* self);
|
||||||
|
|
||||||
|
///
|
||||||
|
// Creates a new cef_process_message_t from the data provided to the builder.
|
||||||
|
// Returns nullptr for invalid instances. Invalidates the builder instance.
|
||||||
|
///
|
||||||
|
struct _cef_process_message_t*(CEF_CALLBACK* build)(
|
||||||
|
struct _cef_shared_process_message_builder_t* self);
|
||||||
|
} cef_shared_process_message_builder_t;
|
||||||
|
|
||||||
|
///
|
||||||
|
// Creates a new cef_shared_process_message_builder_t with the specified |name|
|
||||||
|
// and shared memory region of specified |byte_size|.
|
||||||
|
///
|
||||||
|
CEF_EXPORT cef_shared_process_message_builder_t*
|
||||||
|
cef_shared_process_message_builder_create(const cef_string_t* name,
|
||||||
|
size_t byte_size);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // CEF_INCLUDE_CAPI_CEF_SHARED_PROCESS_MESSAGE_BUILDER_CAPI_H_
|
@ -42,13 +42,13 @@
|
|||||||
// way that may cause binary incompatibility with other builds. The universal
|
// way that may cause binary incompatibility with other builds. The universal
|
||||||
// hash value will change if any platform is affected whereas the platform hash
|
// hash value will change if any platform is affected whereas the platform hash
|
||||||
// values will change only if that particular platform is affected.
|
// values will change only if that particular platform is affected.
|
||||||
#define CEF_API_HASH_UNIVERSAL "794a4cf2ad83db17558bd2ca2d721487875a37e8"
|
#define CEF_API_HASH_UNIVERSAL "d3fdeba02acc73ac571a1be658789f2ff770f09c"
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
#define CEF_API_HASH_PLATFORM "aa627f71c1cbdf13beeb3fe740337f4cc1cb5dc5"
|
#define CEF_API_HASH_PLATFORM "94db0746536862260c9b47d54128a744dbb29fcf"
|
||||||
#elif defined(OS_MAC)
|
#elif defined(OS_MAC)
|
||||||
#define CEF_API_HASH_PLATFORM "6bda80f2ee107a22780193a7af9101eb5a4db8a0"
|
#define CEF_API_HASH_PLATFORM "1c8d61e3bee1c974a2f71688bbdcfc0f6f01d457"
|
||||||
#elif defined(OS_LINUX)
|
#elif defined(OS_LINUX)
|
||||||
#define CEF_API_HASH_PLATFORM "c83b942ce72835d0ea01bfc4cab3928b92abdb85"
|
#define CEF_API_HASH_PLATFORM "6d9e52b9e54ded43a7e0dfcf80b6f40ec75f3215"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "include/cef_base.h"
|
#include "include/cef_base.h"
|
||||||
|
#include "include/cef_shared_memory_region.h"
|
||||||
#include "include/cef_values.h"
|
#include "include/cef_values.h"
|
||||||
|
|
||||||
typedef cef_process_id_t CefProcessId;
|
typedef cef_process_id_t CefProcessId;
|
||||||
@ -71,6 +72,7 @@ class CefProcessMessage : public virtual CefBaseRefCounted {
|
|||||||
|
|
||||||
///
|
///
|
||||||
// Returns a writable copy of this object.
|
// Returns a writable copy of this object.
|
||||||
|
// Returns nullptr when message contains a shared memory region.
|
||||||
///
|
///
|
||||||
/*--cef()--*/
|
/*--cef()--*/
|
||||||
virtual CefRefPtr<CefProcessMessage> Copy() = 0;
|
virtual CefRefPtr<CefProcessMessage> Copy() = 0;
|
||||||
@ -83,9 +85,17 @@ class CefProcessMessage : public virtual CefBaseRefCounted {
|
|||||||
|
|
||||||
///
|
///
|
||||||
// Returns the list of arguments.
|
// Returns the list of arguments.
|
||||||
|
// Returns nullptr when message contains a shared memory region.
|
||||||
///
|
///
|
||||||
/*--cef()--*/
|
/*--cef()--*/
|
||||||
virtual CefRefPtr<CefListValue> GetArgumentList() = 0;
|
virtual CefRefPtr<CefListValue> GetArgumentList() = 0;
|
||||||
|
|
||||||
|
///
|
||||||
|
// Returns the shared memory region.
|
||||||
|
// Returns nullptr when message contains an argument list.
|
||||||
|
///
|
||||||
|
/*--cef()--*/
|
||||||
|
virtual CefRefPtr<CefSharedMemoryRegion> GetSharedMemoryRegion() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CEF_INCLUDE_CEF_MESSAGE_H_
|
#endif // CEF_INCLUDE_CEF_MESSAGE_H_
|
||||||
|
69
include/cef_shared_memory_region.h
Normal file
69
include/cef_shared_memory_region.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
// Copyright (c) 2022 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_SHARED_MEMORY_REGION_H_
|
||||||
|
#define CEF_INCLUDE_CEF_SHARED_MEMORY_REGION_H_
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "include/cef_base.h"
|
||||||
|
|
||||||
|
///
|
||||||
|
// Class that wraps platform-dependent share memory region mapping.
|
||||||
|
///
|
||||||
|
/*--cef(source=library)--*/
|
||||||
|
class CefSharedMemoryRegion : public virtual CefBaseRefCounted {
|
||||||
|
public:
|
||||||
|
///
|
||||||
|
// Returns true if the mapping is valid.
|
||||||
|
///
|
||||||
|
/*--cef()--*/
|
||||||
|
virtual bool IsValid() = 0;
|
||||||
|
|
||||||
|
///
|
||||||
|
// Returns the size of the mapping in bytes. Returns 0 for invalid instances.
|
||||||
|
///
|
||||||
|
/*--cef()--*/
|
||||||
|
virtual size_t Size() = 0;
|
||||||
|
|
||||||
|
///
|
||||||
|
// Returns the pointer to the memory. Returns nullptr for invalid instances.
|
||||||
|
// The returned pointer is only valid for the life span of this object.
|
||||||
|
///
|
||||||
|
/*--cef()--*/
|
||||||
|
virtual const void* Memory() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CEF_INCLUDE_CEF_SHARED_MEMORY_REGION_H_
|
87
include/cef_shared_process_message_builder.h
Normal file
87
include/cef_shared_process_message_builder.h
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
// Copyright (c) 2022 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_SHARED_PROCESS_MESSAGE_BUILDER_H_
|
||||||
|
#define CEF_INCLUDE_CEF_SHARED_PROCESS_MESSAGE_BUILDER_H_
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "include/cef_process_message.h"
|
||||||
|
|
||||||
|
///
|
||||||
|
// Class that builds a CefProcessMessage containing a shared memory region.
|
||||||
|
// This class is not thread-safe but may be used exclusively on a different
|
||||||
|
// thread from the one which constructed it.
|
||||||
|
///
|
||||||
|
/*--cef(source=library)--*/
|
||||||
|
class CefSharedProcessMessageBuilder : public virtual CefBaseRefCounted {
|
||||||
|
public:
|
||||||
|
///
|
||||||
|
// Creates a new CefSharedProcessMessageBuilder with the specified |name| and
|
||||||
|
// shared memory region of specified |byte_size|.
|
||||||
|
///
|
||||||
|
/*--cef()--*/
|
||||||
|
static CefRefPtr<CefSharedProcessMessageBuilder> Create(const CefString& name,
|
||||||
|
size_t byte_size);
|
||||||
|
///
|
||||||
|
// Returns true if the builder is valid.
|
||||||
|
///
|
||||||
|
/*--cef()--*/
|
||||||
|
virtual bool IsValid() = 0;
|
||||||
|
|
||||||
|
///
|
||||||
|
// Returns the size of the shared memory region in bytes. Returns 0 for
|
||||||
|
// invalid instances.
|
||||||
|
///
|
||||||
|
/*--cef()--*/
|
||||||
|
virtual size_t Size() = 0;
|
||||||
|
|
||||||
|
///
|
||||||
|
// Returns the pointer to the writable memory. Returns nullptr for invalid
|
||||||
|
// instances. The returned pointer is only valid for the life span of this
|
||||||
|
// object.
|
||||||
|
///
|
||||||
|
/*--cef()--*/
|
||||||
|
virtual void* Memory() = 0;
|
||||||
|
|
||||||
|
///
|
||||||
|
// Creates a new CefProcessMessage from the data provided to the builder.
|
||||||
|
// Returns nullptr for invalid instances. Invalidates the builder instance.
|
||||||
|
///
|
||||||
|
/*--cef()--*/
|
||||||
|
virtual CefRefPtr<CefProcessMessage> Build() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CEF_INCLUDE_CEF_SHARED_PROCESS_MESSAGE_BUILDER_H_
|
@ -207,6 +207,10 @@ struct CefMessageRouterConfig {
|
|||||||
// Name of the JavaScript function that will be added to the 'window' object
|
// Name of the JavaScript function that will be added to the 'window' object
|
||||||
// for canceling a pending query. The default value is "cefQueryCancel".
|
// for canceling a pending query. The default value is "cefQueryCancel".
|
||||||
CefString js_cancel_function;
|
CefString js_cancel_function;
|
||||||
|
|
||||||
|
// Messages of size (in bytes) larger than this threshold will be sent via
|
||||||
|
// shared memory region.
|
||||||
|
size_t message_size_threshold;
|
||||||
};
|
};
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -42,6 +42,16 @@ void CefBrowserFrame::SendMessage(const std::string& name,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CefBrowserFrame::SendSharedMemoryRegion(
|
||||||
|
const std::string& name,
|
||||||
|
base::ReadOnlySharedMemoryRegion region) {
|
||||||
|
// Always send to the newly created RFH, which may be speculative when
|
||||||
|
// navigating cross-origin.
|
||||||
|
if (auto host = GetFrameHost(/*prefer_speculative=*/true)) {
|
||||||
|
host->SendSharedMemoryRegion(name, std::move(region));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CefBrowserFrame::FrameAttached(
|
void CefBrowserFrame::FrameAttached(
|
||||||
mojo::PendingRemote<cef::mojom::RenderFrame> render_frame,
|
mojo::PendingRemote<cef::mojom::RenderFrame> render_frame,
|
||||||
bool reattached) {
|
bool reattached) {
|
||||||
|
@ -36,6 +36,8 @@ class CefBrowserFrame
|
|||||||
private:
|
private:
|
||||||
// cef::mojom::BrowserFrame methods:
|
// cef::mojom::BrowserFrame methods:
|
||||||
void SendMessage(const std::string& name, base::Value arguments) override;
|
void SendMessage(const std::string& name, base::Value arguments) override;
|
||||||
|
void SendSharedMemoryRegion(const std::string& name,
|
||||||
|
base::ReadOnlySharedMemoryRegion region) override;
|
||||||
void FrameAttached(mojo::PendingRemote<cef::mojom::RenderFrame> render_frame,
|
void FrameAttached(mojo::PendingRemote<cef::mojom::RenderFrame> render_frame,
|
||||||
bool reattached) override;
|
bool reattached) override;
|
||||||
void DidFinishFrameLoad(const GURL& validated_url,
|
void DidFinishFrameLoad(const GURL& validated_url,
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "libcef/common/frame_util.h"
|
#include "libcef/common/frame_util.h"
|
||||||
#include "libcef/common/net/url_util.h"
|
#include "libcef/common/net/url_util.h"
|
||||||
#include "libcef/common/process_message_impl.h"
|
#include "libcef/common/process_message_impl.h"
|
||||||
|
#include "libcef/common/process_message_smr_impl.h"
|
||||||
#include "libcef/common/request_impl.h"
|
#include "libcef/common/request_impl.h"
|
||||||
#include "libcef/common/string_util.h"
|
#include "libcef/common/string_util.h"
|
||||||
#include "libcef/common/task_runner_impl.h"
|
#include "libcef/common/task_runner_impl.h"
|
||||||
@ -238,18 +239,31 @@ void CefFrameHostImpl::SendProcessMessage(
|
|||||||
if (!message || !message->IsValid())
|
if (!message || !message->IsValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Invalidate the message object immediately by taking the argument list.
|
if (message->GetArgumentList() != nullptr) {
|
||||||
auto argument_list =
|
// Invalidate the message object immediately by taking the argument list.
|
||||||
static_cast<CefProcessMessageImpl*>(message.get())->TakeArgumentList();
|
auto argument_list =
|
||||||
|
static_cast<CefProcessMessageImpl*>(message.get())->TakeArgumentList();
|
||||||
|
|
||||||
SendToRenderFrame(__FUNCTION__,
|
SendToRenderFrame(
|
||||||
base::BindOnce(
|
__FUNCTION__,
|
||||||
[](const CefString& name, base::ListValue argument_list,
|
base::BindOnce(
|
||||||
const RenderFrameType& render_frame) {
|
[](const CefString& name, base::ListValue argument_list,
|
||||||
render_frame->SendMessage(name,
|
const RenderFrameType& render_frame) {
|
||||||
std::move(argument_list));
|
render_frame->SendMessage(name, std::move(argument_list));
|
||||||
},
|
},
|
||||||
message->GetName(), std::move(argument_list)));
|
message->GetName(), std::move(argument_list)));
|
||||||
|
} else {
|
||||||
|
auto region =
|
||||||
|
static_cast<CefProcessMessageSMRImpl*>(message.get())->TakeRegion();
|
||||||
|
SendToRenderFrame(
|
||||||
|
__FUNCTION__,
|
||||||
|
base::BindOnce(
|
||||||
|
[](const CefString& name, base::ReadOnlySharedMemoryRegion region,
|
||||||
|
const RenderFrameType& render_frame) {
|
||||||
|
render_frame->SendSharedMemoryRegion(name, std::move(region));
|
||||||
|
},
|
||||||
|
message->GetName(), std::move(region)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefFrameHostImpl::SetFocused(bool focused) {
|
void CefFrameHostImpl::SetFocused(bool focused) {
|
||||||
@ -564,6 +578,19 @@ void CefFrameHostImpl::SendMessage(const std::string& name,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CefFrameHostImpl::SendSharedMemoryRegion(
|
||||||
|
const std::string& name,
|
||||||
|
base::ReadOnlySharedMemoryRegion region) {
|
||||||
|
if (auto browser = GetBrowserHostBase()) {
|
||||||
|
if (auto client = browser->GetClient()) {
|
||||||
|
CefRefPtr<CefProcessMessage> message(
|
||||||
|
new CefProcessMessageSMRImpl(name, std::move(region)));
|
||||||
|
browser->GetClient()->OnProcessMessageReceived(browser.get(), this,
|
||||||
|
PID_RENDERER, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CefFrameHostImpl::FrameAttached(
|
void CefFrameHostImpl::FrameAttached(
|
||||||
mojo::PendingRemote<cef::mojom::RenderFrame> render_frame_remote,
|
mojo::PendingRemote<cef::mojom::RenderFrame> render_frame_remote,
|
||||||
bool reattached) {
|
bool reattached) {
|
||||||
|
@ -126,6 +126,8 @@ class CefFrameHostImpl : public CefFrame, public cef::mojom::BrowserFrame {
|
|||||||
|
|
||||||
// cef::mojom::BrowserFrame methods forwarded from CefBrowserFrame.
|
// cef::mojom::BrowserFrame methods forwarded from CefBrowserFrame.
|
||||||
void SendMessage(const std::string& name, base::Value arguments) override;
|
void SendMessage(const std::string& name, base::Value arguments) override;
|
||||||
|
void SendSharedMemoryRegion(const std::string& name,
|
||||||
|
base::ReadOnlySharedMemoryRegion region) override;
|
||||||
void FrameAttached(mojo::PendingRemote<cef::mojom::RenderFrame> render_frame,
|
void FrameAttached(mojo::PendingRemote<cef::mojom::RenderFrame> render_frame,
|
||||||
bool reattached) override;
|
bool reattached) override;
|
||||||
void DidFinishFrameLoad(const GURL& validated_url,
|
void DidFinishFrameLoad(const GURL& validated_url,
|
||||||
|
@ -55,6 +55,9 @@ interface RenderFrame {
|
|||||||
// Send a message to the render process.
|
// Send a message to the render process.
|
||||||
SendMessage(string name, mojo_base.mojom.Value arguments);
|
SendMessage(string name, mojo_base.mojom.Value arguments);
|
||||||
|
|
||||||
|
// Send a shared memory region to the render process.
|
||||||
|
SendSharedMemoryRegion(string name, mojo_base.mojom.ReadOnlySharedMemoryRegion region);
|
||||||
|
|
||||||
// Send a command.
|
// Send a command.
|
||||||
SendCommand(string command);
|
SendCommand(string command);
|
||||||
|
|
||||||
@ -80,6 +83,9 @@ interface BrowserFrame {
|
|||||||
// Send a message to the browser process.
|
// Send a message to the browser process.
|
||||||
SendMessage(string name, mojo_base.mojom.Value arguments);
|
SendMessage(string name, mojo_base.mojom.Value arguments);
|
||||||
|
|
||||||
|
// Send a shared memory region to the browser process.
|
||||||
|
SendSharedMemoryRegion(string name, mojo_base.mojom.ReadOnlySharedMemoryRegion region);
|
||||||
|
|
||||||
// The render frame is ready to begin handling actions.
|
// The render frame is ready to begin handling actions.
|
||||||
FrameAttached(pending_remote<RenderFrame> render_frame,
|
FrameAttached(pending_remote<RenderFrame> render_frame,
|
||||||
bool reattached);
|
bool reattached);
|
||||||
|
@ -42,6 +42,9 @@ class CefProcessMessageImpl : public CefProcessMessage {
|
|||||||
CefRefPtr<CefProcessMessage> Copy() override;
|
CefRefPtr<CefProcessMessage> Copy() override;
|
||||||
CefString GetName() override;
|
CefString GetName() override;
|
||||||
CefRefPtr<CefListValue> GetArgumentList() override;
|
CefRefPtr<CefListValue> GetArgumentList() override;
|
||||||
|
CefRefPtr<CefSharedMemoryRegion> GetSharedMemoryRegion() override {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const CefString name_;
|
const CefString name_;
|
||||||
|
90
libcef/common/process_message_smr_impl.cc
Normal file
90
libcef/common/process_message_smr_impl.cc
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
// Copyright (c) 2022 The Chromium Embedded Framework Authors. All rights
|
||||||
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "libcef/common/process_message_smr_impl.h"
|
||||||
|
|
||||||
|
#include "base/logging.h"
|
||||||
|
#include "base/memory/ptr_util.h"
|
||||||
|
#include "base/memory/shared_memory_mapping.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class CefSharedMemoryRegionImpl final : public CefSharedMemoryRegion {
|
||||||
|
public:
|
||||||
|
CefSharedMemoryRegionImpl(base::ReadOnlySharedMemoryMapping&& mapping)
|
||||||
|
: mapping_(std::move(mapping)) {}
|
||||||
|
CefSharedMemoryRegionImpl(const CefSharedMemoryRegionImpl&) = delete;
|
||||||
|
CefSharedMemoryRegionImpl& operator=(const CefSharedMemoryRegionImpl&) =
|
||||||
|
delete;
|
||||||
|
|
||||||
|
// CefSharedMemoryRegion methods
|
||||||
|
bool IsValid() override { return mapping_.IsValid(); }
|
||||||
|
size_t Size() override { return IsValid() ? mapping_.size() : 0; }
|
||||||
|
const void* Memory() override { return mapping_.memory(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
base::ReadOnlySharedMemoryMapping mapping_;
|
||||||
|
IMPLEMENT_REFCOUNTING(CefSharedMemoryRegionImpl);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
CefProcessMessageSMRImpl::CefProcessMessageSMRImpl(
|
||||||
|
const CefString& name,
|
||||||
|
base::ReadOnlySharedMemoryRegion&& region)
|
||||||
|
: name_(name), region_(std::move(region)) {
|
||||||
|
DCHECK(!name_.empty());
|
||||||
|
DCHECK(region_.IsValid());
|
||||||
|
}
|
||||||
|
|
||||||
|
CefProcessMessageSMRImpl::~CefProcessMessageSMRImpl() = default;
|
||||||
|
|
||||||
|
bool CefProcessMessageSMRImpl::IsValid() {
|
||||||
|
return region_.IsValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
CefString CefProcessMessageSMRImpl::GetName() {
|
||||||
|
return name_;
|
||||||
|
}
|
||||||
|
|
||||||
|
CefRefPtr<CefSharedMemoryRegion>
|
||||||
|
CefProcessMessageSMRImpl::GetSharedMemoryRegion() {
|
||||||
|
return new CefSharedMemoryRegionImpl(region_.Map());
|
||||||
|
}
|
||||||
|
|
||||||
|
base::ReadOnlySharedMemoryRegion CefProcessMessageSMRImpl::TakeRegion() {
|
||||||
|
return std::move(region_);
|
||||||
|
};
|
||||||
|
|
||||||
|
// static
|
||||||
|
CefRefPtr<CefSharedProcessMessageBuilder>
|
||||||
|
CefSharedProcessMessageBuilder::Create(const CefString& name,
|
||||||
|
size_t byte_size) {
|
||||||
|
return new CefSharedProcessMessageBuilderImpl(name, byte_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
CefSharedProcessMessageBuilderImpl::CefSharedProcessMessageBuilderImpl(
|
||||||
|
const CefString& name,
|
||||||
|
size_t byte_size)
|
||||||
|
: name_(name),
|
||||||
|
region_(base::ReadOnlySharedMemoryRegion::Create(byte_size)) {}
|
||||||
|
|
||||||
|
bool CefSharedProcessMessageBuilderImpl::IsValid() {
|
||||||
|
return region_.region.IsValid() && region_.mapping.IsValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t CefSharedProcessMessageBuilderImpl::Size() {
|
||||||
|
return !IsValid() ? 0 : region_.mapping.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void* CefSharedProcessMessageBuilderImpl::Memory() {
|
||||||
|
return !IsValid() ? nullptr : region_.mapping.memory();
|
||||||
|
}
|
||||||
|
|
||||||
|
CefRefPtr<CefProcessMessage> CefSharedProcessMessageBuilderImpl::Build() {
|
||||||
|
if (!IsValid()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return new CefProcessMessageSMRImpl(name_, std::move(region_.region));
|
||||||
|
}
|
58
libcef/common/process_message_smr_impl.h
Normal file
58
libcef/common/process_message_smr_impl.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
// Copyright (c) 2022 The Chromium Embedded Framework Authors. All rights
|
||||||
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef CEF_LIBCEF_COMMON_PROCESS_MESSAGE_SMR_IMPL_H_
|
||||||
|
#define CEF_LIBCEF_COMMON_PROCESS_MESSAGE_SMR_IMPL_H_
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "include/cef_process_message.h"
|
||||||
|
#include "include/cef_shared_process_message_builder.h"
|
||||||
|
|
||||||
|
#include "base/memory/read_only_shared_memory_region.h"
|
||||||
|
|
||||||
|
class CefProcessMessageSMRImpl final : public CefProcessMessage {
|
||||||
|
public:
|
||||||
|
CefProcessMessageSMRImpl(const CefString& name,
|
||||||
|
base::ReadOnlySharedMemoryRegion&& region);
|
||||||
|
CefProcessMessageSMRImpl(const CefProcessMessageSMRImpl&) = delete;
|
||||||
|
CefProcessMessageSMRImpl& operator=(const CefProcessMessageSMRImpl&) = delete;
|
||||||
|
~CefProcessMessageSMRImpl() override;
|
||||||
|
|
||||||
|
// CefProcessMessage methods.
|
||||||
|
bool IsValid() override;
|
||||||
|
bool IsReadOnly() override { return true; }
|
||||||
|
CefRefPtr<CefProcessMessage> Copy() override { return nullptr; }
|
||||||
|
CefString GetName() override;
|
||||||
|
CefRefPtr<CefListValue> GetArgumentList() override { return nullptr; };
|
||||||
|
CefRefPtr<CefSharedMemoryRegion> GetSharedMemoryRegion() override;
|
||||||
|
[[nodiscard]] base::ReadOnlySharedMemoryRegion TakeRegion();
|
||||||
|
|
||||||
|
private:
|
||||||
|
const CefString name_;
|
||||||
|
base::ReadOnlySharedMemoryRegion region_;
|
||||||
|
|
||||||
|
IMPLEMENT_REFCOUNTING(CefProcessMessageSMRImpl);
|
||||||
|
};
|
||||||
|
|
||||||
|
class CefSharedProcessMessageBuilderImpl final
|
||||||
|
: public CefSharedProcessMessageBuilder {
|
||||||
|
public:
|
||||||
|
CefSharedProcessMessageBuilderImpl(const CefString& name, size_t byte_size);
|
||||||
|
CefSharedProcessMessageBuilderImpl(const CefProcessMessageSMRImpl&) = delete;
|
||||||
|
CefSharedProcessMessageBuilderImpl& operator=(
|
||||||
|
const CefSharedProcessMessageBuilderImpl&) = delete;
|
||||||
|
|
||||||
|
bool IsValid() override;
|
||||||
|
size_t Size() override;
|
||||||
|
void* Memory() override;
|
||||||
|
CefRefPtr<CefProcessMessage> Build() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const CefString name_;
|
||||||
|
base::MappedReadOnlyRegion region_;
|
||||||
|
|
||||||
|
IMPLEMENT_REFCOUNTING(CefSharedProcessMessageBuilderImpl);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CEF_LIBCEF_COMMON_PROCESS_MESSAGE_SMR_IMPL_H_
|
@ -21,6 +21,7 @@
|
|||||||
#include "libcef/common/frame_util.h"
|
#include "libcef/common/frame_util.h"
|
||||||
#include "libcef/common/net/http_header_utils.h"
|
#include "libcef/common/net/http_header_utils.h"
|
||||||
#include "libcef/common/process_message_impl.h"
|
#include "libcef/common/process_message_impl.h"
|
||||||
|
#include "libcef/common/process_message_smr_impl.h"
|
||||||
#include "libcef/common/request_impl.h"
|
#include "libcef/common/request_impl.h"
|
||||||
#include "libcef/common/string_util.h"
|
#include "libcef/common/string_util.h"
|
||||||
#include "libcef/renderer/blink_glue.h"
|
#include "libcef/renderer/blink_glue.h"
|
||||||
@ -270,16 +271,30 @@ void CefFrameImpl::SendProcessMessage(CefProcessId target_process,
|
|||||||
if (!message || !message->IsValid())
|
if (!message || !message->IsValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SendToBrowserFrame(
|
if (message->GetArgumentList() != nullptr) {
|
||||||
__FUNCTION__,
|
// Invalidate the message object immediately by taking the argument list.
|
||||||
base::BindOnce(
|
auto argument_list =
|
||||||
[](CefRefPtr<CefProcessMessage> message,
|
static_cast<CefProcessMessageImpl*>(message.get())->TakeArgumentList();
|
||||||
const BrowserFrameType& browser_frame) {
|
SendToBrowserFrame(
|
||||||
auto impl = static_cast<CefProcessMessageImpl*>(message.get());
|
__FUNCTION__,
|
||||||
browser_frame->SendMessage(impl->GetName(),
|
base::BindOnce(
|
||||||
impl->TakeArgumentList());
|
[](const CefString& name, base::ListValue argument_list,
|
||||||
},
|
const BrowserFrameType& render_frame) {
|
||||||
message));
|
render_frame->SendMessage(name, std::move(argument_list));
|
||||||
|
},
|
||||||
|
message->GetName(), std::move(argument_list)));
|
||||||
|
} else {
|
||||||
|
auto region =
|
||||||
|
static_cast<CefProcessMessageSMRImpl*>(message.get())->TakeRegion();
|
||||||
|
SendToBrowserFrame(
|
||||||
|
__FUNCTION__,
|
||||||
|
base::BindOnce(
|
||||||
|
[](const CefString& name, base::ReadOnlySharedMemoryRegion region,
|
||||||
|
const BrowserFrameType& render_frame) {
|
||||||
|
render_frame->SendSharedMemoryRegion(name, std::move(region));
|
||||||
|
},
|
||||||
|
message->GetName(), std::move(region)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<blink::WebURLLoader> CefFrameImpl::CreateURLLoader() {
|
std::unique_ptr<blink::WebURLLoader> CefFrameImpl::CreateURLLoader() {
|
||||||
@ -654,6 +669,18 @@ void CefFrameImpl::SendMessage(const std::string& name, base::Value arguments) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CefFrameImpl::SendSharedMemoryRegion(
|
||||||
|
const std::string& name,
|
||||||
|
base::ReadOnlySharedMemoryRegion region) {
|
||||||
|
if (auto app = CefAppManager::Get()->GetApplication()) {
|
||||||
|
if (auto handler = app->GetRenderProcessHandler()) {
|
||||||
|
CefRefPtr<CefProcessMessage> message(
|
||||||
|
new CefProcessMessageSMRImpl(name, std::move(region)));
|
||||||
|
handler->OnProcessMessageReceived(browser_, this, PID_BROWSER, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CefFrameImpl::SendCommand(const std::string& command) {
|
void CefFrameImpl::SendCommand(const std::string& command) {
|
||||||
ExecuteOnLocalFrame(
|
ExecuteOnLocalFrame(
|
||||||
__FUNCTION__,
|
__FUNCTION__,
|
||||||
|
@ -135,6 +135,8 @@ class CefFrameImpl
|
|||||||
// cef::mojom::RenderFrame methods:
|
// cef::mojom::RenderFrame methods:
|
||||||
void FrameAttachedAck() override;
|
void FrameAttachedAck() override;
|
||||||
void SendMessage(const std::string& name, base::Value arguments) override;
|
void SendMessage(const std::string& name, base::Value arguments) override;
|
||||||
|
void SendSharedMemoryRegion(const std::string& name,
|
||||||
|
base::ReadOnlySharedMemoryRegion region) override;
|
||||||
void SendCommand(const std::string& command) override;
|
void SendCommand(const std::string& command) override;
|
||||||
void SendCommandWithResponse(
|
void SendCommandWithResponse(
|
||||||
const std::string& command,
|
const std::string& command,
|
||||||
|
@ -9,11 +9,12 @@
|
|||||||
// implementations. See the translator.README.txt file in the tools directory
|
// implementations. See the translator.README.txt file in the tools directory
|
||||||
// for more information.
|
// for more information.
|
||||||
//
|
//
|
||||||
// $hash=b63f665e68e4dc6269c3e88b81068190ea90abb3$
|
// $hash=5d331596c0425f145a19d8de6a866841d9ed8a87$
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "libcef_dll/cpptoc/process_message_cpptoc.h"
|
#include "libcef_dll/cpptoc/process_message_cpptoc.h"
|
||||||
#include "libcef_dll/cpptoc/list_value_cpptoc.h"
|
#include "libcef_dll/cpptoc/list_value_cpptoc.h"
|
||||||
|
#include "libcef_dll/cpptoc/shared_memory_region_cpptoc.h"
|
||||||
#include "libcef_dll/shutdown_checker.h"
|
#include "libcef_dll/shutdown_checker.h"
|
||||||
|
|
||||||
// GLOBAL FUNCTIONS - Body may be edited by hand.
|
// GLOBAL FUNCTIONS - Body may be edited by hand.
|
||||||
@ -127,6 +128,24 @@ process_message_get_argument_list(struct _cef_process_message_t* self) {
|
|||||||
return CefListValueCppToC::Wrap(_retval);
|
return CefListValueCppToC::Wrap(_retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct _cef_shared_memory_region_t* CEF_CALLBACK
|
||||||
|
process_message_get_shared_memory_region(struct _cef_process_message_t* self) {
|
||||||
|
shutdown_checker::AssertNotShutdown();
|
||||||
|
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
DCHECK(self);
|
||||||
|
if (!self)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
CefRefPtr<CefSharedMemoryRegion> _retval =
|
||||||
|
CefProcessMessageCppToC::Get(self)->GetSharedMemoryRegion();
|
||||||
|
|
||||||
|
// Return type: refptr_same
|
||||||
|
return CefSharedMemoryRegionCppToC::Wrap(_retval);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// CONSTRUCTOR - Do not edit by hand.
|
// CONSTRUCTOR - Do not edit by hand.
|
||||||
@ -137,6 +156,8 @@ CefProcessMessageCppToC::CefProcessMessageCppToC() {
|
|||||||
GetStruct()->copy = process_message_copy;
|
GetStruct()->copy = process_message_copy;
|
||||||
GetStruct()->get_name = process_message_get_name;
|
GetStruct()->get_name = process_message_get_name;
|
||||||
GetStruct()->get_argument_list = process_message_get_argument_list;
|
GetStruct()->get_argument_list = process_message_get_argument_list;
|
||||||
|
GetStruct()->get_shared_memory_region =
|
||||||
|
process_message_get_shared_memory_region;
|
||||||
}
|
}
|
||||||
|
|
||||||
// DESTRUCTOR - Do not edit by hand.
|
// DESTRUCTOR - Do not edit by hand.
|
||||||
|
105
libcef_dll/cpptoc/shared_memory_region_cpptoc.cc
Normal file
105
libcef_dll/cpptoc/shared_memory_region_cpptoc.cc
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
// Copyright (c) 2022 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=b8c6bf91bf16cb696121e7d304c21fbcdc927ffd$
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "libcef_dll/cpptoc/shared_memory_region_cpptoc.h"
|
||||||
|
#include "libcef_dll/shutdown_checker.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// MEMBER FUNCTIONS - Body may be edited by hand.
|
||||||
|
|
||||||
|
int CEF_CALLBACK
|
||||||
|
shared_memory_region_is_valid(struct _cef_shared_memory_region_t* self) {
|
||||||
|
shutdown_checker::AssertNotShutdown();
|
||||||
|
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
DCHECK(self);
|
||||||
|
if (!self)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
bool _retval = CefSharedMemoryRegionCppToC::Get(self)->IsValid();
|
||||||
|
|
||||||
|
// Return type: bool
|
||||||
|
return _retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t CEF_CALLBACK
|
||||||
|
shared_memory_region_size(struct _cef_shared_memory_region_t* self) {
|
||||||
|
shutdown_checker::AssertNotShutdown();
|
||||||
|
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
DCHECK(self);
|
||||||
|
if (!self)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
size_t _retval = CefSharedMemoryRegionCppToC::Get(self)->Size();
|
||||||
|
|
||||||
|
// Return type: simple
|
||||||
|
return _retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
const void* CEF_CALLBACK
|
||||||
|
shared_memory_region_memory(struct _cef_shared_memory_region_t* self) {
|
||||||
|
shutdown_checker::AssertNotShutdown();
|
||||||
|
|
||||||
|
shutdown_checker::AssertNotShutdown();
|
||||||
|
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
DCHECK(self);
|
||||||
|
if (!self)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
const void* _retval = CefSharedMemoryRegionCppToC::Get(self)->Memory();
|
||||||
|
|
||||||
|
// Return type: simple
|
||||||
|
return _retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// CONSTRUCTOR - Do not edit by hand.
|
||||||
|
|
||||||
|
CefSharedMemoryRegionCppToC::CefSharedMemoryRegionCppToC() {
|
||||||
|
GetStruct()->is_valid = shared_memory_region_is_valid;
|
||||||
|
GetStruct()->size = shared_memory_region_size;
|
||||||
|
GetStruct()->memory = shared_memory_region_memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DESTRUCTOR - Do not edit by hand.
|
||||||
|
|
||||||
|
CefSharedMemoryRegionCppToC::~CefSharedMemoryRegionCppToC() {
|
||||||
|
shutdown_checker::AssertNotShutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
CefRefPtr<CefSharedMemoryRegion> CefCppToCRefCounted<
|
||||||
|
CefSharedMemoryRegionCppToC,
|
||||||
|
CefSharedMemoryRegion,
|
||||||
|
cef_shared_memory_region_t>::UnwrapDerived(CefWrapperType type,
|
||||||
|
cef_shared_memory_region_t* s) {
|
||||||
|
NOTREACHED() << "Unexpected class type: " << type;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
CefWrapperType CefCppToCRefCounted<CefSharedMemoryRegionCppToC,
|
||||||
|
CefSharedMemoryRegion,
|
||||||
|
cef_shared_memory_region_t>::kWrapperType =
|
||||||
|
WT_SHARED_MEMORY_REGION;
|
38
libcef_dll/cpptoc/shared_memory_region_cpptoc.h
Normal file
38
libcef_dll/cpptoc/shared_memory_region_cpptoc.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Copyright (c) 2022 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=77de7d9d9e62fa5075ff6e76e4647639c51a7f05$
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef CEF_LIBCEF_DLL_CPPTOC_SHARED_MEMORY_REGION_CPPTOC_H_
|
||||||
|
#define CEF_LIBCEF_DLL_CPPTOC_SHARED_MEMORY_REGION_CPPTOC_H_
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined(BUILDING_CEF_SHARED)
|
||||||
|
#error This file can be included DLL-side only
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "include/capi/cef_shared_memory_region_capi.h"
|
||||||
|
#include "include/cef_shared_memory_region.h"
|
||||||
|
#include "libcef_dll/cpptoc/cpptoc_ref_counted.h"
|
||||||
|
|
||||||
|
// Wrap a C++ class with a C structure.
|
||||||
|
// This class may be instantiated and accessed DLL-side only.
|
||||||
|
class CefSharedMemoryRegionCppToC
|
||||||
|
: public CefCppToCRefCounted<CefSharedMemoryRegionCppToC,
|
||||||
|
CefSharedMemoryRegion,
|
||||||
|
cef_shared_memory_region_t> {
|
||||||
|
public:
|
||||||
|
CefSharedMemoryRegionCppToC();
|
||||||
|
virtual ~CefSharedMemoryRegionCppToC();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CEF_LIBCEF_DLL_CPPTOC_SHARED_MEMORY_REGION_CPPTOC_H_
|
145
libcef_dll/cpptoc/shared_process_message_builder_cpptoc.cc
Normal file
145
libcef_dll/cpptoc/shared_process_message_builder_cpptoc.cc
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
// Copyright (c) 2022 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=b3c3551c52baf66ab3cd4ee485313ef41a29313b$
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "libcef_dll/cpptoc/shared_process_message_builder_cpptoc.h"
|
||||||
|
#include "libcef_dll/cpptoc/process_message_cpptoc.h"
|
||||||
|
#include "libcef_dll/shutdown_checker.h"
|
||||||
|
|
||||||
|
// GLOBAL FUNCTIONS - Body may be edited by hand.
|
||||||
|
|
||||||
|
CEF_EXPORT cef_shared_process_message_builder_t*
|
||||||
|
cef_shared_process_message_builder_create(const cef_string_t* name,
|
||||||
|
size_t byte_size) {
|
||||||
|
shutdown_checker::AssertNotShutdown();
|
||||||
|
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
// Verify param: name; type: string_byref_const
|
||||||
|
DCHECK(name);
|
||||||
|
if (!name)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
CefRefPtr<CefSharedProcessMessageBuilder> _retval =
|
||||||
|
CefSharedProcessMessageBuilder::Create(CefString(name), byte_size);
|
||||||
|
|
||||||
|
// Return type: refptr_same
|
||||||
|
return CefSharedProcessMessageBuilderCppToC::Wrap(_retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// MEMBER FUNCTIONS - Body may be edited by hand.
|
||||||
|
|
||||||
|
int CEF_CALLBACK shared_process_message_builder_is_valid(
|
||||||
|
struct _cef_shared_process_message_builder_t* self) {
|
||||||
|
shutdown_checker::AssertNotShutdown();
|
||||||
|
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
DCHECK(self);
|
||||||
|
if (!self)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
bool _retval = CefSharedProcessMessageBuilderCppToC::Get(self)->IsValid();
|
||||||
|
|
||||||
|
// Return type: bool
|
||||||
|
return _retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t CEF_CALLBACK shared_process_message_builder_size(
|
||||||
|
struct _cef_shared_process_message_builder_t* self) {
|
||||||
|
shutdown_checker::AssertNotShutdown();
|
||||||
|
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
DCHECK(self);
|
||||||
|
if (!self)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
size_t _retval = CefSharedProcessMessageBuilderCppToC::Get(self)->Size();
|
||||||
|
|
||||||
|
// Return type: simple
|
||||||
|
return _retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* CEF_CALLBACK shared_process_message_builder_memory(
|
||||||
|
struct _cef_shared_process_message_builder_t* self) {
|
||||||
|
shutdown_checker::AssertNotShutdown();
|
||||||
|
|
||||||
|
DCHECK(self);
|
||||||
|
if (!self)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
void* _retval = CefSharedProcessMessageBuilderCppToC::Get(self)->Memory();
|
||||||
|
|
||||||
|
// Return type: simple
|
||||||
|
return _retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
cef_process_message_t* CEF_CALLBACK shared_process_message_builder_build(
|
||||||
|
struct _cef_shared_process_message_builder_t* self) {
|
||||||
|
shutdown_checker::AssertNotShutdown();
|
||||||
|
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
DCHECK(self);
|
||||||
|
if (!self)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
CefRefPtr<CefProcessMessage> _retval =
|
||||||
|
CefSharedProcessMessageBuilderCppToC::Get(self)->Build();
|
||||||
|
|
||||||
|
// Return type: refptr_same
|
||||||
|
return CefProcessMessageCppToC::Wrap(_retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// CONSTRUCTOR - Do not edit by hand.
|
||||||
|
|
||||||
|
CefSharedProcessMessageBuilderCppToC::CefSharedProcessMessageBuilderCppToC() {
|
||||||
|
GetStruct()->is_valid = shared_process_message_builder_is_valid;
|
||||||
|
GetStruct()->size = shared_process_message_builder_size;
|
||||||
|
GetStruct()->memory = shared_process_message_builder_memory;
|
||||||
|
GetStruct()->build = shared_process_message_builder_build;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DESTRUCTOR - Do not edit by hand.
|
||||||
|
|
||||||
|
CefSharedProcessMessageBuilderCppToC::~CefSharedProcessMessageBuilderCppToC() {
|
||||||
|
shutdown_checker::AssertNotShutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
CefRefPtr<CefSharedProcessMessageBuilder>
|
||||||
|
CefCppToCRefCounted<CefSharedProcessMessageBuilderCppToC,
|
||||||
|
CefSharedProcessMessageBuilder,
|
||||||
|
cef_shared_process_message_builder_t>::
|
||||||
|
UnwrapDerived(CefWrapperType type,
|
||||||
|
cef_shared_process_message_builder_t* s) {
|
||||||
|
NOTREACHED() << "Unexpected class type: " << type;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
CefWrapperType
|
||||||
|
CefCppToCRefCounted<CefSharedProcessMessageBuilderCppToC,
|
||||||
|
CefSharedProcessMessageBuilder,
|
||||||
|
cef_shared_process_message_builder_t>::kWrapperType =
|
||||||
|
WT_SHARED_PROCESS_MESSAGE_BUILDER;
|
38
libcef_dll/cpptoc/shared_process_message_builder_cpptoc.h
Normal file
38
libcef_dll/cpptoc/shared_process_message_builder_cpptoc.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Copyright (c) 2022 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=a3ec0a78d1e092d99780b6ec87d345a20c081be6$
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef CEF_LIBCEF_DLL_CPPTOC_SHARED_PROCESS_MESSAGE_BUILDER_CPPTOC_H_
|
||||||
|
#define CEF_LIBCEF_DLL_CPPTOC_SHARED_PROCESS_MESSAGE_BUILDER_CPPTOC_H_
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined(BUILDING_CEF_SHARED)
|
||||||
|
#error This file can be included DLL-side only
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "include/capi/cef_shared_process_message_builder_capi.h"
|
||||||
|
#include "include/cef_shared_process_message_builder.h"
|
||||||
|
#include "libcef_dll/cpptoc/cpptoc_ref_counted.h"
|
||||||
|
|
||||||
|
// Wrap a C++ class with a C structure.
|
||||||
|
// This class may be instantiated and accessed DLL-side only.
|
||||||
|
class CefSharedProcessMessageBuilderCppToC
|
||||||
|
: public CefCppToCRefCounted<CefSharedProcessMessageBuilderCppToC,
|
||||||
|
CefSharedProcessMessageBuilder,
|
||||||
|
cef_shared_process_message_builder_t> {
|
||||||
|
public:
|
||||||
|
CefSharedProcessMessageBuilderCppToC();
|
||||||
|
virtual ~CefSharedProcessMessageBuilderCppToC();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CEF_LIBCEF_DLL_CPPTOC_SHARED_PROCESS_MESSAGE_BUILDER_CPPTOC_H_
|
@ -9,11 +9,12 @@
|
|||||||
// implementations. See the translator.README.txt file in the tools directory
|
// implementations. See the translator.README.txt file in the tools directory
|
||||||
// for more information.
|
// for more information.
|
||||||
//
|
//
|
||||||
// $hash=7ab779c6c98a1bd2385f14d514304a28ef58717f$
|
// $hash=0f16a0f4711caf0b3761bf6480622de2e75b72ef$
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "libcef_dll/ctocpp/process_message_ctocpp.h"
|
#include "libcef_dll/ctocpp/process_message_ctocpp.h"
|
||||||
#include "libcef_dll/ctocpp/list_value_ctocpp.h"
|
#include "libcef_dll/ctocpp/list_value_ctocpp.h"
|
||||||
|
#include "libcef_dll/ctocpp/shared_memory_region_ctocpp.h"
|
||||||
#include "libcef_dll/shutdown_checker.h"
|
#include "libcef_dll/shutdown_checker.h"
|
||||||
|
|
||||||
// STATIC METHODS - Body may be edited by hand.
|
// STATIC METHODS - Body may be edited by hand.
|
||||||
@ -122,6 +123,25 @@ CefRefPtr<CefListValue> CefProcessMessageCToCpp::GetArgumentList() {
|
|||||||
return CefListValueCToCpp::Wrap(_retval);
|
return CefListValueCToCpp::Wrap(_retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NO_SANITIZE("cfi-icall")
|
||||||
|
CefRefPtr<CefSharedMemoryRegion>
|
||||||
|
CefProcessMessageCToCpp::GetSharedMemoryRegion() {
|
||||||
|
shutdown_checker::AssertNotShutdown();
|
||||||
|
|
||||||
|
cef_process_message_t* _struct = GetStruct();
|
||||||
|
if (CEF_MEMBER_MISSING(_struct, get_shared_memory_region))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
cef_shared_memory_region_t* _retval =
|
||||||
|
_struct->get_shared_memory_region(_struct);
|
||||||
|
|
||||||
|
// Return type: refptr_same
|
||||||
|
return CefSharedMemoryRegionCToCpp::Wrap(_retval);
|
||||||
|
}
|
||||||
|
|
||||||
// CONSTRUCTOR - Do not edit by hand.
|
// CONSTRUCTOR - Do not edit by hand.
|
||||||
|
|
||||||
CefProcessMessageCToCpp::CefProcessMessageCToCpp() {}
|
CefProcessMessageCToCpp::CefProcessMessageCToCpp() {}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
// implementations. See the translator.README.txt file in the tools directory
|
// implementations. See the translator.README.txt file in the tools directory
|
||||||
// for more information.
|
// for more information.
|
||||||
//
|
//
|
||||||
// $hash=39bf2321370b32cf02bf502529568e935b303550$
|
// $hash=f52b0dfcee0d432a334166fce348234d0d239b85$
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef CEF_LIBCEF_DLL_CTOCPP_PROCESS_MESSAGE_CTOCPP_H_
|
#ifndef CEF_LIBCEF_DLL_CTOCPP_PROCESS_MESSAGE_CTOCPP_H_
|
||||||
@ -40,6 +40,7 @@ class CefProcessMessageCToCpp
|
|||||||
CefRefPtr<CefProcessMessage> Copy() override;
|
CefRefPtr<CefProcessMessage> Copy() override;
|
||||||
CefString GetName() override;
|
CefString GetName() override;
|
||||||
CefRefPtr<CefListValue> GetArgumentList() override;
|
CefRefPtr<CefListValue> GetArgumentList() override;
|
||||||
|
CefRefPtr<CefSharedMemoryRegion> GetSharedMemoryRegion() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CEF_LIBCEF_DLL_CTOCPP_PROCESS_MESSAGE_CTOCPP_H_
|
#endif // CEF_LIBCEF_DLL_CTOCPP_PROCESS_MESSAGE_CTOCPP_H_
|
||||||
|
90
libcef_dll/ctocpp/shared_memory_region_ctocpp.cc
Normal file
90
libcef_dll/ctocpp/shared_memory_region_ctocpp.cc
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
// Copyright (c) 2022 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=fd0a4c1bd80a53778d6e40e4ebcd9d4484f91269$
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "libcef_dll/ctocpp/shared_memory_region_ctocpp.h"
|
||||||
|
#include "libcef_dll/shutdown_checker.h"
|
||||||
|
|
||||||
|
// VIRTUAL METHODS - Body may be edited by hand.
|
||||||
|
|
||||||
|
NO_SANITIZE("cfi-icall") bool CefSharedMemoryRegionCToCpp::IsValid() {
|
||||||
|
shutdown_checker::AssertNotShutdown();
|
||||||
|
|
||||||
|
cef_shared_memory_region_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") size_t CefSharedMemoryRegionCToCpp::Size() {
|
||||||
|
shutdown_checker::AssertNotShutdown();
|
||||||
|
|
||||||
|
cef_shared_memory_region_t* _struct = GetStruct();
|
||||||
|
if (CEF_MEMBER_MISSING(_struct, size))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
size_t _retval = _struct->size(_struct);
|
||||||
|
|
||||||
|
// Return type: simple
|
||||||
|
return _retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
NO_SANITIZE("cfi-icall") const void* CefSharedMemoryRegionCToCpp::Memory() {
|
||||||
|
shutdown_checker::AssertNotShutdown();
|
||||||
|
|
||||||
|
cef_shared_memory_region_t* _struct = GetStruct();
|
||||||
|
if (CEF_MEMBER_MISSING(_struct, memory))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
const void* _retval = _struct->memory(_struct);
|
||||||
|
|
||||||
|
// Return type: simple
|
||||||
|
return _retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CONSTRUCTOR - Do not edit by hand.
|
||||||
|
|
||||||
|
CefSharedMemoryRegionCToCpp::CefSharedMemoryRegionCToCpp() {}
|
||||||
|
|
||||||
|
// DESTRUCTOR - Do not edit by hand.
|
||||||
|
|
||||||
|
CefSharedMemoryRegionCToCpp::~CefSharedMemoryRegionCToCpp() {
|
||||||
|
shutdown_checker::AssertNotShutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
cef_shared_memory_region_t* CefCToCppRefCounted<
|
||||||
|
CefSharedMemoryRegionCToCpp,
|
||||||
|
CefSharedMemoryRegion,
|
||||||
|
cef_shared_memory_region_t>::UnwrapDerived(CefWrapperType type,
|
||||||
|
CefSharedMemoryRegion* c) {
|
||||||
|
NOTREACHED() << "Unexpected class type: " << type;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
CefWrapperType CefCToCppRefCounted<CefSharedMemoryRegionCToCpp,
|
||||||
|
CefSharedMemoryRegion,
|
||||||
|
cef_shared_memory_region_t>::kWrapperType =
|
||||||
|
WT_SHARED_MEMORY_REGION;
|
43
libcef_dll/ctocpp/shared_memory_region_ctocpp.h
Normal file
43
libcef_dll/ctocpp/shared_memory_region_ctocpp.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// Copyright (c) 2022 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=d477b2660e271bbdc4d6e8f866f006b84f13e50d$
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef CEF_LIBCEF_DLL_CTOCPP_SHARED_MEMORY_REGION_CTOCPP_H_
|
||||||
|
#define CEF_LIBCEF_DLL_CTOCPP_SHARED_MEMORY_REGION_CTOCPP_H_
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined(WRAPPING_CEF_SHARED)
|
||||||
|
#error This file can be included wrapper-side only
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "include/capi/cef_shared_memory_region_capi.h"
|
||||||
|
#include "include/cef_shared_memory_region.h"
|
||||||
|
#include "libcef_dll/ctocpp/ctocpp_ref_counted.h"
|
||||||
|
|
||||||
|
// Wrap a C structure with a C++ class.
|
||||||
|
// This class may be instantiated and accessed wrapper-side only.
|
||||||
|
class CefSharedMemoryRegionCToCpp
|
||||||
|
: public CefCToCppRefCounted<CefSharedMemoryRegionCToCpp,
|
||||||
|
CefSharedMemoryRegion,
|
||||||
|
cef_shared_memory_region_t> {
|
||||||
|
public:
|
||||||
|
CefSharedMemoryRegionCToCpp();
|
||||||
|
virtual ~CefSharedMemoryRegionCToCpp();
|
||||||
|
|
||||||
|
// CefSharedMemoryRegion methods.
|
||||||
|
bool IsValid() override;
|
||||||
|
size_t Size() override;
|
||||||
|
const void* Memory() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CEF_LIBCEF_DLL_CTOCPP_SHARED_MEMORY_REGION_CTOCPP_H_
|
132
libcef_dll/ctocpp/shared_process_message_builder_ctocpp.cc
Normal file
132
libcef_dll/ctocpp/shared_process_message_builder_ctocpp.cc
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
// Copyright (c) 2022 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=a20e093efb07503fe9e64c97c14091e3921544cd$
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "libcef_dll/ctocpp/shared_process_message_builder_ctocpp.h"
|
||||||
|
#include "libcef_dll/ctocpp/process_message_ctocpp.h"
|
||||||
|
#include "libcef_dll/shutdown_checker.h"
|
||||||
|
|
||||||
|
// STATIC METHODS - Body may be edited by hand.
|
||||||
|
|
||||||
|
NO_SANITIZE("cfi-icall")
|
||||||
|
CefRefPtr<CefSharedProcessMessageBuilder>
|
||||||
|
CefSharedProcessMessageBuilder::Create(const CefString& name,
|
||||||
|
size_t byte_size) {
|
||||||
|
shutdown_checker::AssertNotShutdown();
|
||||||
|
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
// Verify param: name; type: string_byref_const
|
||||||
|
DCHECK(!name.empty());
|
||||||
|
if (name.empty())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
cef_shared_process_message_builder_t* _retval =
|
||||||
|
cef_shared_process_message_builder_create(name.GetStruct(), byte_size);
|
||||||
|
|
||||||
|
// Return type: refptr_same
|
||||||
|
return CefSharedProcessMessageBuilderCToCpp::Wrap(_retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
// VIRTUAL METHODS - Body may be edited by hand.
|
||||||
|
|
||||||
|
NO_SANITIZE("cfi-icall") bool CefSharedProcessMessageBuilderCToCpp::IsValid() {
|
||||||
|
shutdown_checker::AssertNotShutdown();
|
||||||
|
|
||||||
|
cef_shared_process_message_builder_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") size_t CefSharedProcessMessageBuilderCToCpp::Size() {
|
||||||
|
shutdown_checker::AssertNotShutdown();
|
||||||
|
|
||||||
|
cef_shared_process_message_builder_t* _struct = GetStruct();
|
||||||
|
if (CEF_MEMBER_MISSING(_struct, size))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
size_t _retval = _struct->size(_struct);
|
||||||
|
|
||||||
|
// Return type: simple
|
||||||
|
return _retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
NO_SANITIZE("cfi-icall") void* CefSharedProcessMessageBuilderCToCpp::Memory() {
|
||||||
|
shutdown_checker::AssertNotShutdown();
|
||||||
|
|
||||||
|
cef_shared_process_message_builder_t* _struct = GetStruct();
|
||||||
|
if (CEF_MEMBER_MISSING(_struct, memory))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
void* _retval = _struct->memory(_struct);
|
||||||
|
|
||||||
|
// Return type: simple
|
||||||
|
return _retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
NO_SANITIZE("cfi-icall")
|
||||||
|
CefRefPtr<CefProcessMessage> CefSharedProcessMessageBuilderCToCpp::Build() {
|
||||||
|
shutdown_checker::AssertNotShutdown();
|
||||||
|
|
||||||
|
cef_shared_process_message_builder_t* _struct = GetStruct();
|
||||||
|
if (CEF_MEMBER_MISSING(_struct, build))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
cef_process_message_t* _retval = _struct->build(_struct);
|
||||||
|
|
||||||
|
// Return type: refptr_same
|
||||||
|
return CefProcessMessageCToCpp::Wrap(_retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
// CONSTRUCTOR - Do not edit by hand.
|
||||||
|
|
||||||
|
CefSharedProcessMessageBuilderCToCpp::CefSharedProcessMessageBuilderCToCpp() {}
|
||||||
|
|
||||||
|
// DESTRUCTOR - Do not edit by hand.
|
||||||
|
|
||||||
|
CefSharedProcessMessageBuilderCToCpp::~CefSharedProcessMessageBuilderCToCpp() {
|
||||||
|
shutdown_checker::AssertNotShutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
cef_shared_process_message_builder_t*
|
||||||
|
CefCToCppRefCounted<CefSharedProcessMessageBuilderCToCpp,
|
||||||
|
CefSharedProcessMessageBuilder,
|
||||||
|
cef_shared_process_message_builder_t>::
|
||||||
|
UnwrapDerived(CefWrapperType type, CefSharedProcessMessageBuilder* c) {
|
||||||
|
NOTREACHED() << "Unexpected class type: " << type;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
CefWrapperType
|
||||||
|
CefCToCppRefCounted<CefSharedProcessMessageBuilderCToCpp,
|
||||||
|
CefSharedProcessMessageBuilder,
|
||||||
|
cef_shared_process_message_builder_t>::kWrapperType =
|
||||||
|
WT_SHARED_PROCESS_MESSAGE_BUILDER;
|
44
libcef_dll/ctocpp/shared_process_message_builder_ctocpp.h
Normal file
44
libcef_dll/ctocpp/shared_process_message_builder_ctocpp.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// Copyright (c) 2022 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=0a8bf76a2347d7afc98e1cbeb61b88be4bc7e789$
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef CEF_LIBCEF_DLL_CTOCPP_SHARED_PROCESS_MESSAGE_BUILDER_CTOCPP_H_
|
||||||
|
#define CEF_LIBCEF_DLL_CTOCPP_SHARED_PROCESS_MESSAGE_BUILDER_CTOCPP_H_
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined(WRAPPING_CEF_SHARED)
|
||||||
|
#error This file can be included wrapper-side only
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "include/capi/cef_shared_process_message_builder_capi.h"
|
||||||
|
#include "include/cef_shared_process_message_builder.h"
|
||||||
|
#include "libcef_dll/ctocpp/ctocpp_ref_counted.h"
|
||||||
|
|
||||||
|
// Wrap a C structure with a C++ class.
|
||||||
|
// This class may be instantiated and accessed wrapper-side only.
|
||||||
|
class CefSharedProcessMessageBuilderCToCpp
|
||||||
|
: public CefCToCppRefCounted<CefSharedProcessMessageBuilderCToCpp,
|
||||||
|
CefSharedProcessMessageBuilder,
|
||||||
|
cef_shared_process_message_builder_t> {
|
||||||
|
public:
|
||||||
|
CefSharedProcessMessageBuilderCToCpp();
|
||||||
|
virtual ~CefSharedProcessMessageBuilderCToCpp();
|
||||||
|
|
||||||
|
// CefSharedProcessMessageBuilder methods.
|
||||||
|
bool IsValid() override;
|
||||||
|
size_t Size() override;
|
||||||
|
void* Memory() override;
|
||||||
|
CefRefPtr<CefProcessMessage> Build() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CEF_LIBCEF_DLL_CTOCPP_SHARED_PROCESS_MESSAGE_BUILDER_CTOCPP_H_
|
@ -8,6 +8,7 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
#include "include/base/cef_callback.h"
|
#include "include/base/cef_callback.h"
|
||||||
|
#include "include/cef_shared_process_message_builder.h"
|
||||||
#include "include/cef_task.h"
|
#include "include/cef_task.h"
|
||||||
#include "include/wrapper/cef_closure_task.h"
|
#include "include/wrapper/cef_closure_task.h"
|
||||||
#include "include/wrapper/cef_helpers.h"
|
#include "include/wrapper/cef_helpers.h"
|
||||||
@ -31,6 +32,10 @@ const char kMemberPersistent[] = "persistent";
|
|||||||
const int kCanceledErrorCode = -1;
|
const int kCanceledErrorCode = -1;
|
||||||
const char kCanceledErrorMessage[] = "The query has been canceled";
|
const char kCanceledErrorMessage[] = "The query has been canceled";
|
||||||
|
|
||||||
|
// Value of 16KB is chosen as a result of performance tests available at
|
||||||
|
// http://tests/ipc_performance
|
||||||
|
constexpr size_t kResponseSizeThreshold = 16384;
|
||||||
|
|
||||||
// Validate configuration settings.
|
// Validate configuration settings.
|
||||||
bool ValidateConfig(CefMessageRouterConfig& config) {
|
bool ValidateConfig(CefMessageRouterConfig& config) {
|
||||||
// Must specify function names.
|
// Must specify function names.
|
||||||
@ -41,6 +46,124 @@ bool ValidateConfig(CefMessageRouterConfig& config) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct MessageHeader {
|
||||||
|
int context_id;
|
||||||
|
int request_id;
|
||||||
|
bool is_success;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ParsedMessage {
|
||||||
|
int context_id;
|
||||||
|
int request_id;
|
||||||
|
bool success;
|
||||||
|
int error_code;
|
||||||
|
CefString message;
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t GetMessageSize(const CefString& response) {
|
||||||
|
return sizeof(MessageHeader) +
|
||||||
|
(response.size() * sizeof(CefString::char_type));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CopyResponseIntoMemory(void* memory, const CefString& response) {
|
||||||
|
const size_t bytes = response.size() * sizeof(CefString::char_type);
|
||||||
|
void* dest = static_cast<uint8_t*>(memory) + sizeof(MessageHeader);
|
||||||
|
memcpy(dest, response.c_str(), bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
CefString GetStringFromMemory(const void* memory, size_t size) {
|
||||||
|
const size_t bytes = size - sizeof(MessageHeader);
|
||||||
|
const size_t string_len = bytes / sizeof(CefString::char_type);
|
||||||
|
const CefString::char_type* src =
|
||||||
|
reinterpret_cast<const CefString::char_type*>(
|
||||||
|
static_cast<const uint8_t*>(memory) + sizeof(MessageHeader));
|
||||||
|
constexpr bool copy = true;
|
||||||
|
CefString result;
|
||||||
|
result.FromString(src, string_len, copy);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
CefRefPtr<CefProcessMessage> BuildListMessage(const std::string& message_name,
|
||||||
|
int context_id,
|
||||||
|
int request_id,
|
||||||
|
const CefString& response) {
|
||||||
|
auto message = CefProcessMessage::Create(message_name);
|
||||||
|
CefRefPtr<CefListValue> args = message->GetArgumentList();
|
||||||
|
args->SetInt(0, context_id);
|
||||||
|
args->SetInt(1, request_id);
|
||||||
|
args->SetBool(2, true); // Indicates a success result.
|
||||||
|
args->SetString(3, response);
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
CefRefPtr<CefProcessMessage> BuildBinaryMessage(const std::string& message_name,
|
||||||
|
int context_id,
|
||||||
|
int request_id,
|
||||||
|
const CefString& response) {
|
||||||
|
const size_t message_size = GetMessageSize(response);
|
||||||
|
auto builder =
|
||||||
|
CefSharedProcessMessageBuilder::Create(message_name, message_size);
|
||||||
|
if (!builder->IsValid()) {
|
||||||
|
LOG(ERROR) << "Failed to allocate shared memory region of size "
|
||||||
|
<< message_size;
|
||||||
|
// Use list message as a fallback
|
||||||
|
return BuildListMessage(message_name, context_id, request_id, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto header = static_cast<MessageHeader*>(builder->Memory());
|
||||||
|
header->context_id = context_id;
|
||||||
|
header->request_id = request_id;
|
||||||
|
header->is_success = true;
|
||||||
|
|
||||||
|
CopyResponseIntoMemory(builder->Memory(), response);
|
||||||
|
|
||||||
|
return builder->Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
CefRefPtr<CefProcessMessage> BuildMessage(size_t threshold,
|
||||||
|
const std::string& message_name,
|
||||||
|
int context_id,
|
||||||
|
int request_id,
|
||||||
|
const CefString& response) {
|
||||||
|
if (response.size() <= threshold) {
|
||||||
|
return BuildListMessage(message_name, context_id, request_id, response);
|
||||||
|
} else {
|
||||||
|
return BuildBinaryMessage(message_name, context_id, request_id, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ParsedMessage ParseMessage(const CefRefPtr<CefProcessMessage>& message) {
|
||||||
|
if (auto args = message->GetArgumentList()) {
|
||||||
|
DCHECK_GT(args->GetSize(), 3U);
|
||||||
|
|
||||||
|
const int context_id = args->GetInt(0);
|
||||||
|
const int request_id = args->GetInt(1);
|
||||||
|
const bool is_success = args->GetBool(2);
|
||||||
|
|
||||||
|
if (is_success) {
|
||||||
|
return ParsedMessage{context_id, request_id, is_success, 0,
|
||||||
|
args->GetString(3)};
|
||||||
|
}
|
||||||
|
|
||||||
|
DCHECK_EQ(args->GetSize(), 5U);
|
||||||
|
return ParsedMessage{context_id, request_id, is_success, args->GetInt(3),
|
||||||
|
args->GetString(4)};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const auto region = message->GetSharedMemoryRegion()) {
|
||||||
|
if (region->IsValid()) {
|
||||||
|
DCHECK_GE(region->Size(), sizeof(MessageHeader));
|
||||||
|
auto header = static_cast<const MessageHeader*>(region->Memory());
|
||||||
|
DCHECK(header->is_success);
|
||||||
|
return ParsedMessage{
|
||||||
|
header->context_id, header->request_id, header->is_success, 0,
|
||||||
|
GetStringFromMemory(region->Memory(), region->Size())};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ParsedMessage{};
|
||||||
|
}
|
||||||
|
|
||||||
// Helper template for generated ID values.
|
// Helper template for generated ID values.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class IdGenerator {
|
class IdGenerator {
|
||||||
@ -428,14 +551,11 @@ class CefMessageRouterBrowserSideImpl : public CefMessageRouterBrowserSide {
|
|||||||
int context_id,
|
int context_id,
|
||||||
int request_id,
|
int request_id,
|
||||||
const CefString& response) {
|
const CefString& response) {
|
||||||
CefRefPtr<CefProcessMessage> message =
|
if (auto message =
|
||||||
CefProcessMessage::Create(query_message_name_);
|
BuildMessage(config_.message_size_threshold, query_message_name_,
|
||||||
CefRefPtr<CefListValue> args = message->GetArgumentList();
|
context_id, request_id, response)) {
|
||||||
args->SetInt(0, context_id);
|
frame->SendProcessMessage(PID_RENDERER, message);
|
||||||
args->SetInt(1, request_id);
|
}
|
||||||
args->SetBool(2, true); // Indicates a success result.
|
|
||||||
args->SetString(3, response);
|
|
||||||
frame->SendProcessMessage(PID_RENDERER, message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendQueryFailure(QueryInfo* info,
|
void SendQueryFailure(QueryInfo* info,
|
||||||
@ -817,31 +937,21 @@ class CefMessageRouterRendererSideImpl : public CefMessageRouterRendererSide {
|
|||||||
|
|
||||||
const std::string& message_name = message->GetName();
|
const std::string& message_name = message->GetName();
|
||||||
if (message_name == query_message_name_) {
|
if (message_name == query_message_name_) {
|
||||||
CefRefPtr<CefListValue> args = message->GetArgumentList();
|
auto content = ParseMessage(message);
|
||||||
DCHECK_GT(args->GetSize(), 3U);
|
if (content.success) {
|
||||||
|
|
||||||
const int context_id = args->GetInt(0);
|
|
||||||
const int request_id = args->GetInt(1);
|
|
||||||
bool is_success = args->GetBool(2);
|
|
||||||
|
|
||||||
if (is_success) {
|
|
||||||
DCHECK_EQ(args->GetSize(), 4U);
|
|
||||||
const CefString& response = args->GetString(3);
|
|
||||||
CefPostTask(
|
CefPostTask(
|
||||||
TID_RENDERER,
|
TID_RENDERER,
|
||||||
base::BindOnce(
|
base::BindOnce(
|
||||||
&CefMessageRouterRendererSideImpl::ExecuteSuccessCallback, this,
|
&CefMessageRouterRendererSideImpl::ExecuteSuccessCallback, this,
|
||||||
browser->GetIdentifier(), context_id, request_id, response));
|
browser->GetIdentifier(), content.context_id,
|
||||||
|
content.request_id, content.message));
|
||||||
} else {
|
} else {
|
||||||
DCHECK_EQ(args->GetSize(), 5U);
|
|
||||||
int error_code = args->GetInt(3);
|
|
||||||
const CefString& error_message = args->GetString(4);
|
|
||||||
CefPostTask(
|
CefPostTask(
|
||||||
TID_RENDERER,
|
TID_RENDERER,
|
||||||
base::BindOnce(
|
base::BindOnce(
|
||||||
&CefMessageRouterRendererSideImpl::ExecuteFailureCallback, this,
|
&CefMessageRouterRendererSideImpl::ExecuteFailureCallback, this,
|
||||||
browser->GetIdentifier(), context_id, request_id, error_code,
|
browser->GetIdentifier(), content.context_id,
|
||||||
error_message));
|
content.request_id, content.error_code, content.message));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -913,10 +1023,9 @@ class CefMessageRouterRendererSideImpl : public CefMessageRouterRendererSide {
|
|||||||
|
|
||||||
const int request_id = request_id_generator_.GetNextId();
|
const int request_id = request_id_generator_.GetNextId();
|
||||||
|
|
||||||
RequestInfo* info = new RequestInfo;
|
auto* info =
|
||||||
info->persistent = persistent;
|
new RequestInfo{persistent, success_callback, failure_callback};
|
||||||
info->success_callback = success_callback;
|
|
||||||
info->failure_callback = failure_callback;
|
|
||||||
browser_request_info_map_.Add(browser->GetIdentifier(),
|
browser_request_info_map_.Add(browser->GetIdentifier(),
|
||||||
std::make_pair(context_id, request_id), info);
|
std::make_pair(context_id, request_id), info);
|
||||||
|
|
||||||
@ -1117,7 +1226,9 @@ class CefMessageRouterRendererSideImpl : public CefMessageRouterRendererSide {
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
CefMessageRouterConfig::CefMessageRouterConfig()
|
CefMessageRouterConfig::CefMessageRouterConfig()
|
||||||
: js_query_function("cefQuery"), js_cancel_function("cefQueryCancel") {}
|
: js_query_function("cefQuery"),
|
||||||
|
js_cancel_function("cefQueryCancel"),
|
||||||
|
message_size_threshold(kResponseSizeThreshold) {}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
CefRefPtr<CefMessageRouterBrowserSide> CefMessageRouterBrowserSide::Create(
|
CefRefPtr<CefMessageRouterBrowserSide> CefMessageRouterBrowserSide::Create(
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
// implementations. See the translator.README.txt file in the tools directory
|
// implementations. See the translator.README.txt file in the tools directory
|
||||||
// for more information.
|
// for more information.
|
||||||
//
|
//
|
||||||
// $hash=5bf495a6015a7c0937225685bfbe8e0163e67583$
|
// $hash=9c3fcd2a053f20a9a09b9938996f5df9eb2053ef$
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
@ -39,6 +39,7 @@
|
|||||||
#include "include/capi/cef_response_capi.h"
|
#include "include/capi/cef_response_capi.h"
|
||||||
#include "include/capi/cef_scheme_capi.h"
|
#include "include/capi/cef_scheme_capi.h"
|
||||||
#include "include/capi/cef_server_capi.h"
|
#include "include/capi/cef_server_capi.h"
|
||||||
|
#include "include/capi/cef_shared_process_message_builder_capi.h"
|
||||||
#include "include/capi/cef_ssl_info_capi.h"
|
#include "include/capi/cef_ssl_info_capi.h"
|
||||||
#include "include/capi/cef_stream_capi.h"
|
#include "include/capi/cef_stream_capi.h"
|
||||||
#include "include/capi/cef_task_capi.h"
|
#include "include/capi/cef_task_capi.h"
|
||||||
@ -219,6 +220,9 @@ typedef void (*cef_server_create_ptr)(const cef_string_t*,
|
|||||||
uint16,
|
uint16,
|
||||||
int,
|
int,
|
||||||
struct _cef_server_handler_t*);
|
struct _cef_server_handler_t*);
|
||||||
|
typedef struct _cef_shared_process_message_builder_t* (
|
||||||
|
*cef_shared_process_message_builder_create_ptr)(const cef_string_t*,
|
||||||
|
size_t);
|
||||||
typedef struct _cef_stream_reader_t* (*cef_stream_reader_create_for_file_ptr)(
|
typedef struct _cef_stream_reader_t* (*cef_stream_reader_create_for_file_ptr)(
|
||||||
const cef_string_t*);
|
const cef_string_t*);
|
||||||
typedef struct _cef_stream_reader_t* (
|
typedef struct _cef_stream_reader_t* (
|
||||||
@ -580,6 +584,8 @@ struct libcef_pointers {
|
|||||||
cef_resource_bundle_get_global_ptr cef_resource_bundle_get_global;
|
cef_resource_bundle_get_global_ptr cef_resource_bundle_get_global;
|
||||||
cef_response_create_ptr cef_response_create;
|
cef_response_create_ptr cef_response_create;
|
||||||
cef_server_create_ptr cef_server_create;
|
cef_server_create_ptr cef_server_create;
|
||||||
|
cef_shared_process_message_builder_create_ptr
|
||||||
|
cef_shared_process_message_builder_create;
|
||||||
cef_stream_reader_create_for_file_ptr cef_stream_reader_create_for_file;
|
cef_stream_reader_create_for_file_ptr cef_stream_reader_create_for_file;
|
||||||
cef_stream_reader_create_for_data_ptr cef_stream_reader_create_for_data;
|
cef_stream_reader_create_for_data_ptr cef_stream_reader_create_for_data;
|
||||||
cef_stream_reader_create_for_handler_ptr cef_stream_reader_create_for_handler;
|
cef_stream_reader_create_for_handler_ptr cef_stream_reader_create_for_handler;
|
||||||
@ -789,6 +795,7 @@ int libcef_init_pointers(const char* path) {
|
|||||||
INIT_ENTRY(cef_resource_bundle_get_global);
|
INIT_ENTRY(cef_resource_bundle_get_global);
|
||||||
INIT_ENTRY(cef_response_create);
|
INIT_ENTRY(cef_response_create);
|
||||||
INIT_ENTRY(cef_server_create);
|
INIT_ENTRY(cef_server_create);
|
||||||
|
INIT_ENTRY(cef_shared_process_message_builder_create);
|
||||||
INIT_ENTRY(cef_stream_reader_create_for_file);
|
INIT_ENTRY(cef_stream_reader_create_for_file);
|
||||||
INIT_ENTRY(cef_stream_reader_create_for_data);
|
INIT_ENTRY(cef_stream_reader_create_for_data);
|
||||||
INIT_ENTRY(cef_stream_reader_create_for_handler);
|
INIT_ENTRY(cef_stream_reader_create_for_handler);
|
||||||
@ -1341,6 +1348,14 @@ void cef_server_create(const cef_string_t* address,
|
|||||||
g_libcef_pointers.cef_server_create(address, port, backlog, handler);
|
g_libcef_pointers.cef_server_create(address, port, backlog, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NO_SANITIZE("cfi-icall")
|
||||||
|
struct _cef_shared_process_message_builder_t*
|
||||||
|
cef_shared_process_message_builder_create(const cef_string_t* name,
|
||||||
|
size_t byte_size) {
|
||||||
|
return g_libcef_pointers.cef_shared_process_message_builder_create(name,
|
||||||
|
byte_size);
|
||||||
|
}
|
||||||
|
|
||||||
NO_SANITIZE("cfi-icall")
|
NO_SANITIZE("cfi-icall")
|
||||||
struct _cef_stream_reader_t* cef_stream_reader_create_for_file(
|
struct _cef_stream_reader_t* cef_stream_reader_create_for_file(
|
||||||
const cef_string_t* fileName) {
|
const cef_string_t* fileName) {
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
// implementations. See the translator.README.txt file in the tools directory
|
// implementations. See the translator.README.txt file in the tools directory
|
||||||
// for more information.
|
// for more information.
|
||||||
//
|
//
|
||||||
// $hash=54ed016f3b2bbffebc96ac9cadd3c3986d240342$
|
// $hash=27716558f027af36498437317407384392a34b71$
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef CEF_LIBCEF_DLL_WRAPPER_TYPES_H_
|
#ifndef CEF_LIBCEF_DLL_WRAPPER_TYPES_H_
|
||||||
@ -133,6 +133,8 @@ enum CefWrapperType {
|
|||||||
WT_SERVER,
|
WT_SERVER,
|
||||||
WT_SERVER_HANDLER,
|
WT_SERVER_HANDLER,
|
||||||
WT_SET_COOKIE_CALLBACK,
|
WT_SET_COOKIE_CALLBACK,
|
||||||
|
WT_SHARED_MEMORY_REGION,
|
||||||
|
WT_SHARED_PROCESS_MESSAGE_BUILDER,
|
||||||
WT_STREAM_READER,
|
WT_STREAM_READER,
|
||||||
WT_STREAM_WRITER,
|
WT_STREAM_WRITER,
|
||||||
WT_STRING_VISITOR,
|
WT_STRING_VISITOR,
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "include/cef_command_ids.h"
|
#include "include/cef_command_ids.h"
|
||||||
#include "include/cef_frame.h"
|
#include "include/cef_frame.h"
|
||||||
#include "include/cef_parser.h"
|
#include "include/cef_parser.h"
|
||||||
|
#include "include/cef_shared_process_message_builder.h"
|
||||||
#include "include/cef_ssl_status.h"
|
#include "include/cef_ssl_status.h"
|
||||||
#include "include/cef_x509_certificate.h"
|
#include "include/cef_x509_certificate.h"
|
||||||
#include "include/wrapper/cef_closure_task.h"
|
#include "include/wrapper/cef_closure_task.h"
|
||||||
@ -24,6 +25,7 @@
|
|||||||
#include "tests/cefclient/browser/test_runner.h"
|
#include "tests/cefclient/browser/test_runner.h"
|
||||||
#include "tests/shared/browser/extension_util.h"
|
#include "tests/shared/browser/extension_util.h"
|
||||||
#include "tests/shared/browser/resource_util.h"
|
#include "tests/shared/browser/resource_util.h"
|
||||||
|
#include "tests/shared/common/binary_value_utils.h"
|
||||||
#include "tests/shared/common/client_switches.h"
|
#include "tests/shared/common/client_switches.h"
|
||||||
|
|
||||||
namespace client {
|
namespace client {
|
||||||
@ -52,7 +54,7 @@ enum client_menu_ids {
|
|||||||
CLIENT_ID_TESTMENU_RADIOITEM3,
|
CLIENT_ID_TESTMENU_RADIOITEM3,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Musr match the value in client_renderer.cc.
|
// Must match the value in client_renderer.cc.
|
||||||
const char kFocusedNodeChangedMessage[] = "ClientRenderer.FocusedNodeChanged";
|
const char kFocusedNodeChangedMessage[] = "ClientRenderer.FocusedNodeChanged";
|
||||||
|
|
||||||
std::string GetTimeString(const CefTime& value) {
|
std::string GetTimeString(const CefTime& value) {
|
||||||
@ -224,6 +226,66 @@ std::string GetCertificateInformation(CefRefPtr<CefX509Certificate> cert,
|
|||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OnTestProcessMessageReceived(
|
||||||
|
const CefRefPtr<CefFrame>& frame,
|
||||||
|
const CefRefPtr<CefProcessMessage>& process_message,
|
||||||
|
const bv_utils::TimePoint& finish_time) {
|
||||||
|
DCHECK(process_message->IsValid());
|
||||||
|
|
||||||
|
CefRefPtr<CefListValue> input_args = process_message->GetArgumentList();
|
||||||
|
DCHECK_EQ(input_args->GetSize(), 1U);
|
||||||
|
|
||||||
|
const auto renderer_msg =
|
||||||
|
bv_utils::GetRendererMsgFromBinary(input_args->GetBinary(0));
|
||||||
|
|
||||||
|
CefRefPtr<CefProcessMessage> response =
|
||||||
|
CefProcessMessage::Create(bv_utils::kTestSendProcessMessage);
|
||||||
|
CefRefPtr<CefListValue> args = response->GetArgumentList();
|
||||||
|
|
||||||
|
const auto message_size = std::max(input_args->GetBinary(0)->GetSize(),
|
||||||
|
sizeof(bv_utils::BrowserMessage));
|
||||||
|
std::vector<uint8_t> data(message_size);
|
||||||
|
|
||||||
|
const auto browser_msg =
|
||||||
|
reinterpret_cast<bv_utils::BrowserMessage*>(data.data());
|
||||||
|
browser_msg->test_id = renderer_msg.test_id;
|
||||||
|
browser_msg->duration = finish_time - renderer_msg.start_time;
|
||||||
|
browser_msg->start_time = bv_utils::Now();
|
||||||
|
|
||||||
|
args->SetBinary(0, bv_utils::CreateCefBinaryValue(data));
|
||||||
|
frame->SendProcessMessage(PID_RENDERER, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnTestSMRProcessMessageReceived(
|
||||||
|
const CefRefPtr<CefFrame>& frame,
|
||||||
|
const CefRefPtr<CefProcessMessage>& process_message,
|
||||||
|
const bv_utils::TimePoint& finish_time) {
|
||||||
|
DCHECK(process_message->IsValid());
|
||||||
|
|
||||||
|
CefRefPtr<CefSharedMemoryRegion> region =
|
||||||
|
process_message->GetSharedMemoryRegion();
|
||||||
|
DCHECK_GE(region->Size(), sizeof(bv_utils::RendererMessage));
|
||||||
|
|
||||||
|
const auto renderer_msg =
|
||||||
|
static_cast<const bv_utils::RendererMessage*>(region->Memory());
|
||||||
|
const auto message_size =
|
||||||
|
std::max(region->Size(), sizeof(bv_utils::BrowserMessage));
|
||||||
|
const auto renderer_time = renderer_msg->start_time;
|
||||||
|
const auto duration = finish_time - renderer_time;
|
||||||
|
const auto start_time = bv_utils::Now();
|
||||||
|
|
||||||
|
auto builder = CefSharedProcessMessageBuilder::Create(
|
||||||
|
bv_utils::kTestSendSMRProcessMessage, message_size);
|
||||||
|
|
||||||
|
const auto browser_msg =
|
||||||
|
static_cast<bv_utils::BrowserMessage*>(builder->Memory());
|
||||||
|
browser_msg->test_id = renderer_msg->test_id;
|
||||||
|
browser_msg->duration = duration;
|
||||||
|
browser_msg->start_time = start_time;
|
||||||
|
|
||||||
|
frame->SendProcessMessage(PID_RENDERER, builder->Build());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class ClientDownloadImageCallback : public CefDownloadImageCallback {
|
class ClientDownloadImageCallback : public CefDownloadImageCallback {
|
||||||
@ -332,13 +394,15 @@ bool ClientHandler::OnProcessMessageReceived(
|
|||||||
CefRefPtr<CefProcessMessage> message) {
|
CefRefPtr<CefProcessMessage> message) {
|
||||||
CEF_REQUIRE_UI_THREAD();
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
|
||||||
|
const auto finish_time = bv_utils::Now();
|
||||||
|
|
||||||
if (message_router_->OnProcessMessageReceived(browser, frame, source_process,
|
if (message_router_->OnProcessMessageReceived(browser, frame, source_process,
|
||||||
message)) {
|
message)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for messages from the client renderer.
|
// Check for messages from the client renderer.
|
||||||
std::string message_name = message->GetName();
|
const std::string& message_name = message->GetName();
|
||||||
if (message_name == kFocusedNodeChangedMessage) {
|
if (message_name == kFocusedNodeChangedMessage) {
|
||||||
// A message is sent from ClientRenderDelegate to tell us whether the
|
// A message is sent from ClientRenderDelegate to tell us whether the
|
||||||
// currently focused DOM node is editable. Use of |focus_on_editable_field_|
|
// currently focused DOM node is editable. Use of |focus_on_editable_field_|
|
||||||
@ -348,6 +412,16 @@ bool ClientHandler::OnProcessMessageReceived(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (message_name == bv_utils::kTestSendProcessMessage) {
|
||||||
|
OnTestProcessMessageReceived(frame, message, finish_time);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message_name == bv_utils::kTestSendSMRProcessMessage) {
|
||||||
|
OnTestSMRProcessMessageReceived(frame, message, finish_time);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,27 +46,28 @@
|
|||||||
#define IDS_BINDING_HTML 1000
|
#define IDS_BINDING_HTML 1000
|
||||||
#define IDS_DIALOGS_HTML 1001
|
#define IDS_DIALOGS_HTML 1001
|
||||||
#define IDS_DRAGGABLE_HTML 1002
|
#define IDS_DRAGGABLE_HTML 1002
|
||||||
#define IDS_LOCALSTORAGE_HTML 1003
|
#define IDS_IPC_PERFORMANCE_HTML 1003
|
||||||
#define IDS_LOGO_PNG 1004
|
#define IDS_LOCALSTORAGE_HTML 1004
|
||||||
#define IDS_MEDIA_ROUTER_HTML 1005
|
#define IDS_LOGO_PNG 1005
|
||||||
#define IDS_MENU_ICON_1X_PNG 1006
|
#define IDS_MEDIA_ROUTER_HTML 1006
|
||||||
#define IDS_MENU_ICON_2X_PNG 1007
|
#define IDS_MENU_ICON_1X_PNG 1007
|
||||||
#define IDS_OSRTEST_HTML 1008
|
#define IDS_MENU_ICON_2X_PNG 1008
|
||||||
#define IDS_OTHER_TESTS_HTML 1009
|
#define IDS_OSRTEST_HTML 1009
|
||||||
#define IDS_PDF_HTML 1010
|
#define IDS_OTHER_TESTS_HTML 1010
|
||||||
#define IDS_PDF_PDF 1011
|
#define IDS_PDF_HTML 1011
|
||||||
#define IDS_PERFORMANCE_HTML 1012
|
#define IDS_PDF_PDF 1012
|
||||||
#define IDS_PERFORMANCE2_HTML 1013
|
#define IDS_PERFORMANCE_HTML 1013
|
||||||
#define IDS_PREFERENCES_HTML 1014
|
#define IDS_PERFORMANCE2_HTML 1014
|
||||||
#define IDS_RESPONSE_FILTER_HTML 1015
|
#define IDS_PREFERENCES_HTML 1015
|
||||||
#define IDS_SERVER_HTML 1016
|
#define IDS_RESPONSE_FILTER_HTML 1016
|
||||||
#define IDS_TRANSPARENCY_HTML 1017
|
#define IDS_SERVER_HTML 1017
|
||||||
#define IDS_URLREQUEST_HTML 1018
|
#define IDS_TRANSPARENCY_HTML 1018
|
||||||
#define IDS_WEBSOCKET_HTML 1019
|
#define IDS_URLREQUEST_HTML 1019
|
||||||
#define IDS_WINDOW_HTML 1020
|
#define IDS_WEBSOCKET_HTML 1020
|
||||||
#define IDS_WINDOW_ICON_1X_PNG 1021
|
#define IDS_WINDOW_HTML 1021
|
||||||
#define IDS_WINDOW_ICON_2X_PNG 1022
|
#define IDS_WINDOW_ICON_1X_PNG 1022
|
||||||
#define IDS_XMLHTTPREQUEST_HTML 1023
|
#define IDS_WINDOW_ICON_2X_PNG 1023
|
||||||
|
#define IDS_XMLHTTPREQUEST_HTML 1024
|
||||||
|
|
||||||
#define IDS_EXTENSIONS_SET_PAGE_COLOR_ICON_PNG 1030
|
#define IDS_EXTENSIONS_SET_PAGE_COLOR_ICON_PNG 1030
|
||||||
#define IDS_EXTENSIONS_SET_PAGE_COLOR_MANIFEST_JSON 1031
|
#define IDS_EXTENSIONS_SET_PAGE_COLOR_MANIFEST_JSON 1031
|
||||||
|
@ -13,40 +13,40 @@ int GetResourceId(const char* resource_name) {
|
|||||||
static struct _resource_map {
|
static struct _resource_map {
|
||||||
const char* name;
|
const char* name;
|
||||||
int id;
|
int id;
|
||||||
} resource_map[] = {
|
} resource_map[] = {{"binding.html", IDS_BINDING_HTML},
|
||||||
{"binding.html", IDS_BINDING_HTML},
|
{"dialogs.html", IDS_DIALOGS_HTML},
|
||||||
{"dialogs.html", IDS_DIALOGS_HTML},
|
{"draggable.html", IDS_DRAGGABLE_HTML},
|
||||||
{"draggable.html", IDS_DRAGGABLE_HTML},
|
{"extensions/set_page_color/icon.png",
|
||||||
{"extensions/set_page_color/icon.png",
|
IDS_EXTENSIONS_SET_PAGE_COLOR_ICON_PNG},
|
||||||
IDS_EXTENSIONS_SET_PAGE_COLOR_ICON_PNG},
|
{"extensions/set_page_color/manifest.json",
|
||||||
{"extensions/set_page_color/manifest.json",
|
IDS_EXTENSIONS_SET_PAGE_COLOR_MANIFEST_JSON},
|
||||||
IDS_EXTENSIONS_SET_PAGE_COLOR_MANIFEST_JSON},
|
{"extensions/set_page_color/popup.html",
|
||||||
{"extensions/set_page_color/popup.html",
|
IDS_EXTENSIONS_SET_PAGE_COLOR_POPUP_HTML},
|
||||||
IDS_EXTENSIONS_SET_PAGE_COLOR_POPUP_HTML},
|
{"extensions/set_page_color/popup.js",
|
||||||
{"extensions/set_page_color/popup.js",
|
IDS_EXTENSIONS_SET_PAGE_COLOR_POPUP_JS},
|
||||||
IDS_EXTENSIONS_SET_PAGE_COLOR_POPUP_JS},
|
{"ipc_performance.html", IDS_IPC_PERFORMANCE_HTML},
|
||||||
{"localstorage.html", IDS_LOCALSTORAGE_HTML},
|
{"localstorage.html", IDS_LOCALSTORAGE_HTML},
|
||||||
{"logo.png", IDS_LOGO_PNG},
|
{"logo.png", IDS_LOGO_PNG},
|
||||||
{"media_router.html", IDS_MEDIA_ROUTER_HTML},
|
{"media_router.html", IDS_MEDIA_ROUTER_HTML},
|
||||||
{"menu_icon.1x.png", IDS_MENU_ICON_1X_PNG},
|
{"menu_icon.1x.png", IDS_MENU_ICON_1X_PNG},
|
||||||
{"menu_icon.2x.png", IDS_MENU_ICON_2X_PNG},
|
{"menu_icon.2x.png", IDS_MENU_ICON_2X_PNG},
|
||||||
{"osr_test.html", IDS_OSRTEST_HTML},
|
{"osr_test.html", IDS_OSRTEST_HTML},
|
||||||
{"other_tests.html", IDS_OTHER_TESTS_HTML},
|
{"other_tests.html", IDS_OTHER_TESTS_HTML},
|
||||||
{"pdf.html", IDS_PDF_HTML},
|
{"pdf.html", IDS_PDF_HTML},
|
||||||
{"pdf.pdf", IDS_PDF_PDF},
|
{"pdf.pdf", IDS_PDF_PDF},
|
||||||
{"performance.html", IDS_PERFORMANCE_HTML},
|
{"performance.html", IDS_PERFORMANCE_HTML},
|
||||||
{"performance2.html", IDS_PERFORMANCE2_HTML},
|
{"performance2.html", IDS_PERFORMANCE2_HTML},
|
||||||
{"preferences.html", IDS_PREFERENCES_HTML},
|
{"preferences.html", IDS_PREFERENCES_HTML},
|
||||||
{"response_filter.html", IDS_RESPONSE_FILTER_HTML},
|
{"response_filter.html", IDS_RESPONSE_FILTER_HTML},
|
||||||
{"server.html", IDS_SERVER_HTML},
|
{"server.html", IDS_SERVER_HTML},
|
||||||
{"transparency.html", IDS_TRANSPARENCY_HTML},
|
{"transparency.html", IDS_TRANSPARENCY_HTML},
|
||||||
{"urlrequest.html", IDS_URLREQUEST_HTML},
|
{"urlrequest.html", IDS_URLREQUEST_HTML},
|
||||||
{"websocket.html", IDS_WEBSOCKET_HTML},
|
{"websocket.html", IDS_WEBSOCKET_HTML},
|
||||||
{"window.html", IDS_WINDOW_HTML},
|
{"window.html", IDS_WINDOW_HTML},
|
||||||
{"window_icon.1x.png", IDS_WINDOW_ICON_1X_PNG},
|
{"window_icon.1x.png", IDS_WINDOW_ICON_1X_PNG},
|
||||||
{"window_icon.2x.png", IDS_WINDOW_ICON_2X_PNG},
|
{"window_icon.2x.png", IDS_WINDOW_ICON_2X_PNG},
|
||||||
{"xmlhttprequest.html", IDS_XMLHTTPREQUEST_HTML},
|
{"xmlhttprequest.html", IDS_XMLHTTPREQUEST_HTML},
|
||||||
};
|
{"xmlhttprequest.html", IDS_XMLHTTPREQUEST_HTML}};
|
||||||
|
|
||||||
for (size_t i = 0; i < sizeof(resource_map) / sizeof(_resource_map); ++i) {
|
for (size_t i = 0; i < sizeof(resource_map) / sizeof(_resource_map); ++i) {
|
||||||
if (!strcmp(resource_map[i].name, resource_name))
|
if (!strcmp(resource_map[i].name, resource_name))
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
// can be found in the LICENSE file.
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
#include "tests/cefclient/renderer/client_renderer.h"
|
#include "tests/cefclient/renderer/client_renderer.h"
|
||||||
|
#include "tests/cefclient/renderer/ipc_performance_test.h"
|
||||||
#include "tests/cefclient/renderer/performance_test.h"
|
#include "tests/cefclient/renderer/performance_test.h"
|
||||||
#include "tests/shared/renderer/client_app_renderer.h"
|
#include "tests/shared/renderer/client_app_renderer.h"
|
||||||
|
|
||||||
@ -12,6 +13,7 @@ namespace client {
|
|||||||
void ClientAppRenderer::CreateDelegates(DelegateSet& delegates) {
|
void ClientAppRenderer::CreateDelegates(DelegateSet& delegates) {
|
||||||
renderer::CreateDelegates(delegates);
|
renderer::CreateDelegates(delegates);
|
||||||
performance_test::CreateDelegates(delegates);
|
performance_test::CreateDelegates(delegates);
|
||||||
|
ipc_performance_test::CreateDelegates(delegates);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace client
|
} // namespace client
|
||||||
|
249
tests/cefclient/renderer/ipc_performance_test.cc
Normal file
249
tests/cefclient/renderer/ipc_performance_test.cc
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
// Copyright (c) 2022 The Chromium Embedded Framework Authors. All rights
|
||||||
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "tests/cefclient/renderer/ipc_performance_test.h"
|
||||||
|
|
||||||
|
#include "include/cef_shared_process_message_builder.h"
|
||||||
|
#include "include/wrapper/cef_helpers.h"
|
||||||
|
#include "tests/shared/common/binary_value_utils.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// JS object member names.
|
||||||
|
constexpr char kMessageSize[] = "size";
|
||||||
|
constexpr char kTestId[] = "testId";
|
||||||
|
constexpr CefV8Value::PropertyAttribute kAttributes =
|
||||||
|
static_cast<CefV8Value::PropertyAttribute>(
|
||||||
|
V8_PROPERTY_ATTRIBUTE_READONLY | V8_PROPERTY_ATTRIBUTE_DONTENUM |
|
||||||
|
V8_PROPERTY_ATTRIBUTE_DONTDELETE);
|
||||||
|
|
||||||
|
struct TestInfo {
|
||||||
|
size_t message_size = 0;
|
||||||
|
int id = 0;
|
||||||
|
bool is_valid = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
TestInfo GetTest(const CefV8ValueList& arguments, CefString& exception) {
|
||||||
|
TestInfo info{};
|
||||||
|
|
||||||
|
if (arguments.size() != 1 || !arguments[0]->IsObject()) {
|
||||||
|
exception = "Invalid arguments; expecting a single object";
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
CefRefPtr<CefV8Value> arg = arguments[0];
|
||||||
|
CefRefPtr<CefV8Value> message_size = arg->GetValue(kMessageSize);
|
||||||
|
if (!message_size.get() || !message_size->IsInt()) {
|
||||||
|
exception =
|
||||||
|
"Invalid arguments; object member 'size' is required and must have "
|
||||||
|
"integer type";
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message_size->GetIntValue() < 1) {
|
||||||
|
exception =
|
||||||
|
"Invalid arguments; object member 'size' must be "
|
||||||
|
"positive";
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
CefRefPtr<CefV8Value> test_id = arg->GetValue(kTestId);
|
||||||
|
if (!message_size.get() || !message_size->IsInt()) {
|
||||||
|
exception =
|
||||||
|
"Invalid arguments; object member 'testId' is required and must "
|
||||||
|
"have integer type";
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
info.message_size = static_cast<size_t>(message_size->GetIntValue());
|
||||||
|
info.id = test_id->GetIntValue();
|
||||||
|
info.is_valid = true;
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle bindings in the render process.
|
||||||
|
class IpcDelegate final : public client::ClientAppRenderer::Delegate {
|
||||||
|
public:
|
||||||
|
class V8HandlerImpl final : public CefV8Handler {
|
||||||
|
public:
|
||||||
|
explicit V8HandlerImpl(const CefRefPtr<IpcDelegate>& delegate)
|
||||||
|
: delegate_(delegate) {}
|
||||||
|
V8HandlerImpl(const V8HandlerImpl&) = delete;
|
||||||
|
V8HandlerImpl& operator=(const V8HandlerImpl&) = delete;
|
||||||
|
|
||||||
|
bool Execute(const CefString& name,
|
||||||
|
CefRefPtr<CefV8Value> object,
|
||||||
|
const CefV8ValueList& arguments,
|
||||||
|
CefRefPtr<CefV8Value>& retval,
|
||||||
|
CefString& exception) override {
|
||||||
|
if (name == bv_utils::kTestSendProcessMessage) {
|
||||||
|
const auto test = GetTest(arguments, exception);
|
||||||
|
if (test.is_valid) {
|
||||||
|
SendTestProcessMessage(test.message_size, test.id);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name == bv_utils::kTestSendSMRProcessMessage) {
|
||||||
|
const auto test = GetTest(arguments, exception);
|
||||||
|
if (test.is_valid) {
|
||||||
|
SendTestSMRProcessMessage(test.message_size, test.id);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SendTestProcessMessage(int message_size, int test_id) {
|
||||||
|
auto context = CefV8Context::GetCurrentContext();
|
||||||
|
delegate_->SendTestProcessMessage(context->GetFrame(), message_size,
|
||||||
|
test_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendTestSMRProcessMessage(int message_size, int test_id) {
|
||||||
|
auto context = CefV8Context::GetCurrentContext();
|
||||||
|
delegate_->SendTestSMRProcessMessage(context->GetFrame(), message_size,
|
||||||
|
test_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
CefRefPtr<IpcDelegate> delegate_;
|
||||||
|
IMPLEMENT_REFCOUNTING(V8HandlerImpl);
|
||||||
|
};
|
||||||
|
|
||||||
|
IpcDelegate() = default;
|
||||||
|
IpcDelegate(const IpcDelegate&) = delete;
|
||||||
|
IpcDelegate& operator=(const IpcDelegate&) = delete;
|
||||||
|
|
||||||
|
void OnContextCreated(CefRefPtr<client::ClientAppRenderer> app,
|
||||||
|
CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
CefRefPtr<CefV8Context> context) override {
|
||||||
|
CEF_REQUIRE_RENDERER_THREAD();
|
||||||
|
|
||||||
|
CefRefPtr<CefV8Handler> handler = new V8HandlerImpl(this);
|
||||||
|
|
||||||
|
// Register function handlers with the 'window' object.
|
||||||
|
auto window = context->GetGlobal();
|
||||||
|
window->SetValue(
|
||||||
|
bv_utils::kTestSendProcessMessage,
|
||||||
|
CefV8Value::CreateFunction(bv_utils::kTestSendProcessMessage, handler),
|
||||||
|
kAttributes);
|
||||||
|
|
||||||
|
window->SetValue(bv_utils::kTestSendSMRProcessMessage,
|
||||||
|
CefV8Value::CreateFunction(
|
||||||
|
bv_utils::kTestSendSMRProcessMessage, handler),
|
||||||
|
kAttributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OnProcessMessageReceived(CefRefPtr<client::ClientAppRenderer> app,
|
||||||
|
CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
CefProcessId source_process,
|
||||||
|
CefRefPtr<CefProcessMessage> message) override {
|
||||||
|
CEF_REQUIRE_RENDERER_THREAD();
|
||||||
|
const auto finish_time = bv_utils::Now();
|
||||||
|
|
||||||
|
if (message->GetName() == bv_utils::kTestSendProcessMessage) {
|
||||||
|
auto args = message->GetArgumentList();
|
||||||
|
DCHECK_EQ(args->GetSize(), 1U);
|
||||||
|
|
||||||
|
const auto browser_msg =
|
||||||
|
bv_utils::GetBrowserMsgFromBinary(args->GetBinary(0));
|
||||||
|
PassTestResultToJs(frame, finish_time, browser_msg);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message->GetName() == bv_utils::kTestSendSMRProcessMessage) {
|
||||||
|
const auto region = message->GetSharedMemoryRegion();
|
||||||
|
DCHECK(region->IsValid());
|
||||||
|
DCHECK_GE(region->Size(), sizeof(bv_utils::BrowserMessage));
|
||||||
|
|
||||||
|
const auto browser_msg =
|
||||||
|
static_cast<const bv_utils::BrowserMessage*>(region->Memory());
|
||||||
|
|
||||||
|
PassTestResultToJs(frame, finish_time, *browser_msg);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
IMPLEMENT_REFCOUNTING(IpcDelegate);
|
||||||
|
|
||||||
|
void SendTestProcessMessage(CefRefPtr<CefFrame> frame,
|
||||||
|
size_t message_size,
|
||||||
|
int test_id) {
|
||||||
|
CEF_REQUIRE_RENDERER_THREAD();
|
||||||
|
|
||||||
|
auto process_message =
|
||||||
|
CefProcessMessage::Create(bv_utils::kTestSendProcessMessage);
|
||||||
|
auto args = process_message->GetArgumentList();
|
||||||
|
|
||||||
|
const auto buffer_size =
|
||||||
|
std::max(message_size, sizeof(bv_utils::RendererMessage));
|
||||||
|
std::vector<uint8_t> buffer(buffer_size);
|
||||||
|
|
||||||
|
const auto renderer_msg =
|
||||||
|
reinterpret_cast<bv_utils::RendererMessage*>(buffer.data());
|
||||||
|
|
||||||
|
renderer_msg->test_id = test_id;
|
||||||
|
renderer_msg->start_time = bv_utils::Now();
|
||||||
|
|
||||||
|
args->SetBinary(0, bv_utils::CreateCefBinaryValue(buffer));
|
||||||
|
frame->SendProcessMessage(PID_BROWSER, process_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendTestSMRProcessMessage(CefRefPtr<CefFrame> frame,
|
||||||
|
size_t message_size,
|
||||||
|
int test_id) {
|
||||||
|
CEF_REQUIRE_RENDERER_THREAD();
|
||||||
|
|
||||||
|
const auto buffer_size =
|
||||||
|
std::max(message_size, sizeof(bv_utils::RendererMessage));
|
||||||
|
const auto start_time = bv_utils::Now();
|
||||||
|
|
||||||
|
auto builder = CefSharedProcessMessageBuilder::Create(
|
||||||
|
bv_utils::kTestSendSMRProcessMessage, buffer_size);
|
||||||
|
|
||||||
|
auto renderer_msg =
|
||||||
|
static_cast<bv_utils::RendererMessage*>(builder->Memory());
|
||||||
|
renderer_msg->test_id = test_id;
|
||||||
|
renderer_msg->start_time = start_time;
|
||||||
|
|
||||||
|
frame->SendProcessMessage(PID_BROWSER, builder->Build());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute the onSuccess JavaScript callback.
|
||||||
|
void PassTestResultToJs(CefRefPtr<CefFrame> frame,
|
||||||
|
const bv_utils::TimePoint& finish_time,
|
||||||
|
const bv_utils::BrowserMessage& msg) {
|
||||||
|
const auto rendered_to_browser = msg.duration;
|
||||||
|
const auto browser_to_rendered = finish_time - msg.start_time;
|
||||||
|
|
||||||
|
CefString code = "testSendProcessMessageResult(" +
|
||||||
|
std::to_string(msg.test_id) + ", " +
|
||||||
|
bv_utils::ToMilliString(rendered_to_browser) + ", " +
|
||||||
|
bv_utils::ToMilliString(browser_to_rendered) + ");";
|
||||||
|
|
||||||
|
frame->ExecuteJavaScript(code, frame->GetURL(), 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace client {
|
||||||
|
namespace ipc_performance_test {
|
||||||
|
|
||||||
|
void CreateDelegates(ClientAppRenderer::DelegateSet& delegates) {
|
||||||
|
delegates.insert(new IpcDelegate());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ipc_performance_test
|
||||||
|
} // namespace client
|
19
tests/cefclient/renderer/ipc_performance_test.h
Normal file
19
tests/cefclient/renderer/ipc_performance_test.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// Copyright (c) 2022 The Chromium Embedded Framework Authors. All rights
|
||||||
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef CEF_TESTS_CEFCLIENT_RENDERER_IPC_PERFORMANCE_TEST_H_
|
||||||
|
#define CEF_TESTS_CEFCLIENT_RENDERER_IPC_PERFORMANCE_TEST_H_
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "tests/shared/renderer/client_app_renderer.h"
|
||||||
|
|
||||||
|
namespace client {
|
||||||
|
namespace ipc_performance_test {
|
||||||
|
|
||||||
|
void CreateDelegates(ClientAppRenderer::DelegateSet& delegates);
|
||||||
|
|
||||||
|
} // namespace ipc_performance_test
|
||||||
|
} // namespace client
|
||||||
|
|
||||||
|
#endif // CEF_TESTS_CEFCLIENT_RENDERER_IPC_PERFORMANCE_TEST_H_
|
448
tests/cefclient/resources/ipc_performance.html
Normal file
448
tests/cefclient/resources/ipc_performance.html
Normal file
@ -0,0 +1,448 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>IPC Performance Tests</title>
|
||||||
|
<script src="https://cdn.plot.ly/plotly-2.12.1.min.js"></script>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Tahoma, Serif;
|
||||||
|
font-size: 10pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.positive {
|
||||||
|
color: green;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.negative {
|
||||||
|
color: red;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.resultTable {
|
||||||
|
border: 1px solid black;
|
||||||
|
border-collapse: collapse;
|
||||||
|
empty-cells: show;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.resultTable td {
|
||||||
|
padding: 2px 4px;
|
||||||
|
border: 1px solid black;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.resultTable > thead > tr {
|
||||||
|
font-weight: bold;
|
||||||
|
background: lightblue;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.resultTable > tbody > tr:nth-child(odd) {
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.resultTable > tbody > tr:nth-child(even) {
|
||||||
|
background: lightgray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hide {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body background-color="white">
|
||||||
|
<h1>IPC Performance Tests</h1>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<p>
|
||||||
|
There is no progress indication of the tests because it
|
||||||
|
significantly influences measurements. <br />It usually takes 30
|
||||||
|
seconds (for 100 samples) to complete the tests. <br /><b>AL</b> -
|
||||||
|
ArgumentList-based process messages. <b>SM</b> -
|
||||||
|
SharedMemoryRegion-based process messages.
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Samples:
|
||||||
|
<input
|
||||||
|
id="sSamples"
|
||||||
|
type="text"
|
||||||
|
value="100"
|
||||||
|
required
|
||||||
|
pattern="[0-9]+"
|
||||||
|
/>
|
||||||
|
<button id="sRun" autofocus onclick="runTestSuite()">Run</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div style="padding-top: 10px; padding-bottom: 10px">
|
||||||
|
<table id="resultTable" class="resultTable">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td class="center" style="width: 8%">Message Size</td>
|
||||||
|
<td class="center" style="width: 8%">AL Round Trip Avg, ms</td>
|
||||||
|
<td class="center" style="width: 8%">SM Round Trip Avg, ms</td>
|
||||||
|
<td class="center" style="width: 10%">Relative Trip Difference</td>
|
||||||
|
<td class="center" style="width: 8%">AL Speed, MB/s</td>
|
||||||
|
<td class="center" style="width: 8%">SM Speed, MB/s</td>
|
||||||
|
<td class="center" style="width: 10%">Relative Speed Difference</td>
|
||||||
|
<td class="center" style="width: 8%">AL Standard Deviation</td>
|
||||||
|
<td class="center" style="width: 8%">SM Standard Deviation</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<!-- result rows here -->
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="round_trip_avg_chart">
|
||||||
|
<!-- Average round trip linear chart will be drawn inside this DIV -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="box_plot_chart">
|
||||||
|
<!-- Box plot of round trip time will be drawn inside this DIV -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
let tests = [];
|
||||||
|
let box_plot_test_data = [];
|
||||||
|
let round_trip_avg_plot_data = [];
|
||||||
|
|
||||||
|
function nextTest(test) {
|
||||||
|
setTimeout(() => {
|
||||||
|
execNextTest(test.index);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSendProcessMessageResult(
|
||||||
|
testIndex,
|
||||||
|
fromRendererToBrowser,
|
||||||
|
fromBrowserToRenderer
|
||||||
|
) {
|
||||||
|
const test = tests[testIndex];
|
||||||
|
|
||||||
|
const roundTrip = fromRendererToBrowser + fromBrowserToRenderer;
|
||||||
|
test.totalRoundTrip += roundTrip;
|
||||||
|
test.sample++;
|
||||||
|
box_plot_test_data[testIndex].x.push(roundTrip);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
execTest(testIndex);
|
||||||
|
}, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendRequest(size, testIndex) {
|
||||||
|
window.testSendProcessMessage({
|
||||||
|
size: size,
|
||||||
|
testId: testIndex,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendSMRRequest(size, testIndex) {
|
||||||
|
window.testSendSMRProcessMessage({
|
||||||
|
size: size,
|
||||||
|
testId: testIndex,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getStandardDeviation(array, mean) {
|
||||||
|
const n = array.length;
|
||||||
|
if (n < 5) return null;
|
||||||
|
return Math.sqrt(
|
||||||
|
array.map((x) => Math.pow(x - mean, 2)).reduce((a, b) => a + b) /
|
||||||
|
(n - 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function execTest(testIndex) {
|
||||||
|
const test = tests[testIndex];
|
||||||
|
|
||||||
|
if (test.sample >= test.totalSamples) {
|
||||||
|
return nextTest(test);
|
||||||
|
}
|
||||||
|
|
||||||
|
test.func(test.index);
|
||||||
|
}
|
||||||
|
|
||||||
|
function column(prepared, value) {
|
||||||
|
return (
|
||||||
|
"<td class='right'>" + (!prepared ? "-" : value.toFixed(2)) + "</td>"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function relativeDiffColumn(prepared, value, isBiggerBetter) {
|
||||||
|
if (!prepared) return "<td class='right'>-</td>";
|
||||||
|
|
||||||
|
const isPositive = value > 0 == isBiggerBetter;
|
||||||
|
return [
|
||||||
|
"<td class='right ",
|
||||||
|
isPositive ? "positive" : "negative",
|
||||||
|
"'>",
|
||||||
|
value > 0 ? "+" : "",
|
||||||
|
value.toFixed(2),
|
||||||
|
"%</td>",
|
||||||
|
].join("");
|
||||||
|
}
|
||||||
|
|
||||||
|
function displayResult(test) {
|
||||||
|
const id = "testResultRow_" + test.index;
|
||||||
|
|
||||||
|
const markup = [
|
||||||
|
"<tr id='",
|
||||||
|
id,
|
||||||
|
"'>",
|
||||||
|
"<td class='left'>",
|
||||||
|
test.name,
|
||||||
|
"</td>",
|
||||||
|
column(test.prepared, test.avgRoundTrip),
|
||||||
|
column(test.prepared, test.avgRoundTripSMR),
|
||||||
|
relativeDiffColumn(test.prepared, test.relativeTripDiff, false),
|
||||||
|
column(test.prepared, test.speed),
|
||||||
|
column(test.prepared, test.speedSMR),
|
||||||
|
relativeDiffColumn(test.prepared, test.relativeSpeedDiff, true),
|
||||||
|
"<td class='right'>",
|
||||||
|
!test.prepared || test.stdDeviation == null
|
||||||
|
? "-"
|
||||||
|
: test.stdDeviation.toFixed(2),
|
||||||
|
"</td>",
|
||||||
|
"<td class='right'>",
|
||||||
|
!test.prepared || test.stdDeviationSMR == null
|
||||||
|
? "-"
|
||||||
|
: test.stdDeviationSMR.toFixed(2),
|
||||||
|
"</td>",
|
||||||
|
"</tr>",
|
||||||
|
].join("");
|
||||||
|
|
||||||
|
const row = document.getElementById(id);
|
||||||
|
if (row) {
|
||||||
|
row.outerHTML = markup;
|
||||||
|
} else {
|
||||||
|
const tbody = document.getElementById("resultTable").tBodies[0];
|
||||||
|
tbody.insertAdjacentHTML("beforeEnd", markup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildTestResults(tests) {
|
||||||
|
testResults = [];
|
||||||
|
|
||||||
|
let oldRoundTrip = {
|
||||||
|
x: [],
|
||||||
|
y: [],
|
||||||
|
type: "scatter",
|
||||||
|
name: "ArgumentList",
|
||||||
|
};
|
||||||
|
|
||||||
|
let newRoundTrip = {
|
||||||
|
x: [],
|
||||||
|
y: [],
|
||||||
|
type: "scatter",
|
||||||
|
name: "SharedMemoryRegion",
|
||||||
|
};
|
||||||
|
|
||||||
|
for (let i = 0; i < tests.length / 2; i++) {
|
||||||
|
const index = testResults.length;
|
||||||
|
|
||||||
|
const test = tests[i * 2];
|
||||||
|
const testSMR = tests[i * 2 + 1];
|
||||||
|
|
||||||
|
const avgRoundTrip = test.totalRoundTrip / test.totalSamples;
|
||||||
|
const avgRoundTripSMR = testSMR.totalRoundTrip / testSMR.totalSamples;
|
||||||
|
const relativeTripDiff =
|
||||||
|
((avgRoundTripSMR - avgRoundTrip) / avgRoundTrip) * 100;
|
||||||
|
|
||||||
|
// In MB/s
|
||||||
|
const speed = test.messageSize / (avgRoundTrip * 1000);
|
||||||
|
const speedSMR = testSMR.messageSize / (avgRoundTripSMR * 1000);
|
||||||
|
const relativeSpeedDiff = ((speedSMR - speed) / speed) * 100;
|
||||||
|
|
||||||
|
const stdDeviation = getStandardDeviation(
|
||||||
|
box_plot_test_data[test.index].x,
|
||||||
|
avgRoundTrip
|
||||||
|
);
|
||||||
|
const stdDeviationSMR = getStandardDeviation(
|
||||||
|
box_plot_test_data[testSMR.index].x,
|
||||||
|
avgRoundTripSMR
|
||||||
|
);
|
||||||
|
|
||||||
|
testResults.push({
|
||||||
|
name: humanFileSize(test.messageSize),
|
||||||
|
index: index,
|
||||||
|
prepared: true,
|
||||||
|
avgRoundTrip: avgRoundTrip,
|
||||||
|
avgRoundTripSMR: avgRoundTripSMR,
|
||||||
|
relativeTripDiff: relativeTripDiff,
|
||||||
|
speed: speed,
|
||||||
|
speedSMR: speedSMR,
|
||||||
|
relativeSpeedDiff: relativeSpeedDiff,
|
||||||
|
stdDeviation: stdDeviation,
|
||||||
|
stdDeviationSMR: stdDeviationSMR,
|
||||||
|
});
|
||||||
|
|
||||||
|
oldRoundTrip.x.push(test.messageSize);
|
||||||
|
newRoundTrip.x.push(test.messageSize);
|
||||||
|
oldRoundTrip.y.push(avgRoundTrip);
|
||||||
|
newRoundTrip.y.push(avgRoundTripSMR);
|
||||||
|
}
|
||||||
|
|
||||||
|
round_trip_avg_plot_data = [oldRoundTrip, newRoundTrip];
|
||||||
|
return testResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildEmptyTestResults(tests) {
|
||||||
|
testResults = [];
|
||||||
|
for (let i = 0; i < tests.length / 2; i++) {
|
||||||
|
const index = testResults.length;
|
||||||
|
const test = tests[i * 2];
|
||||||
|
|
||||||
|
testResults.push({
|
||||||
|
name: humanFileSize(test.messageSize),
|
||||||
|
index: index,
|
||||||
|
prepared: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return testResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
function prepareQueuedTests(totalSamples) {
|
||||||
|
if (totalSamples <= 0) totalSamples = 1;
|
||||||
|
|
||||||
|
tests.forEach((test) => {
|
||||||
|
test.sample = 0;
|
||||||
|
test.totalRoundTrip = 0;
|
||||||
|
test.totalSamples = totalSamples;
|
||||||
|
});
|
||||||
|
|
||||||
|
testResults = buildEmptyTestResults(tests);
|
||||||
|
testResults.forEach((result) => displayResult(result));
|
||||||
|
|
||||||
|
round_trip_avg_plot_data = [];
|
||||||
|
box_plot_test_data.forEach((data) => {
|
||||||
|
data.x = [];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function queueTest(name, messageSize, testFunc) {
|
||||||
|
const testIndex = tests.length;
|
||||||
|
test = {
|
||||||
|
name: name,
|
||||||
|
messageSize: messageSize,
|
||||||
|
index: testIndex,
|
||||||
|
func: testFunc,
|
||||||
|
};
|
||||||
|
tests.push(test);
|
||||||
|
|
||||||
|
box_plot_test_data.push({
|
||||||
|
x: [],
|
||||||
|
type: "box",
|
||||||
|
boxpoints: "all",
|
||||||
|
name: name,
|
||||||
|
jitter: 0.3,
|
||||||
|
pointpos: -1.8,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function execNextTest(testIndex) {
|
||||||
|
testIndex++;
|
||||||
|
if (tests.length <= testIndex) {
|
||||||
|
return testSuiteFinished();
|
||||||
|
} else {
|
||||||
|
return execTest(testIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function execQueuedTests(totalSamples) {
|
||||||
|
prepareQueuedTests(totalSamples);
|
||||||
|
// Let the updated table render before starting the tests
|
||||||
|
setTimeout(() => execNextTest(-1), 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSettingsState(disabled) {
|
||||||
|
document.getElementById("sSamples").disabled = disabled;
|
||||||
|
document.getElementById("sRun").disabled = disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSuiteFinished() {
|
||||||
|
testResults = buildTestResults(tests);
|
||||||
|
testResults.forEach((result) => displayResult(result));
|
||||||
|
|
||||||
|
const round_trip_layout = {
|
||||||
|
title: "Average round trip, ms (Smaller Better)",
|
||||||
|
};
|
||||||
|
Plotly.newPlot(
|
||||||
|
"round_trip_avg_chart",
|
||||||
|
round_trip_avg_plot_data,
|
||||||
|
round_trip_layout
|
||||||
|
);
|
||||||
|
|
||||||
|
const box_plot_layout = {
|
||||||
|
title: "Round Trip Time, ms",
|
||||||
|
};
|
||||||
|
Plotly.newPlot("box_plot_chart", box_plot_test_data, box_plot_layout);
|
||||||
|
setSettingsState(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function humanFileSize(bytes) {
|
||||||
|
const step = 1024;
|
||||||
|
const originalBytes = bytes;
|
||||||
|
|
||||||
|
if (Math.abs(bytes) < step) {
|
||||||
|
return bytes + " B";
|
||||||
|
}
|
||||||
|
|
||||||
|
const units = [" KB", " MB", " GB"];
|
||||||
|
let u = -1;
|
||||||
|
let count = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
bytes /= step;
|
||||||
|
u += 1;
|
||||||
|
count += 1;
|
||||||
|
} while (Math.abs(bytes) >= step && u < units.length - 1);
|
||||||
|
|
||||||
|
return bytes.toString() + units[u];
|
||||||
|
}
|
||||||
|
|
||||||
|
window.runTestSuite = () => {
|
||||||
|
Plotly.purge("round_trip_avg_chart");
|
||||||
|
Plotly.purge("box_plot_chart");
|
||||||
|
setSettingsState(true);
|
||||||
|
const totalSamples = parseInt(
|
||||||
|
document.getElementById("sSamples").value
|
||||||
|
);
|
||||||
|
execQueuedTests(totalSamples);
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (let size = 512; size <= 512 * 1024; size = size * 2) {
|
||||||
|
queueTest(humanFileSize(size) + " AL", size, (testIndex) =>
|
||||||
|
sendRequest(size, testIndex)
|
||||||
|
);
|
||||||
|
|
||||||
|
queueTest(humanFileSize(size) + " SM", size, (testIndex) =>
|
||||||
|
sendSMRRequest(size, testIndex)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const totalSamples = parseInt(document.getElementById("sSamples").value);
|
||||||
|
prepareQueuedTests(totalSamples);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -17,6 +17,7 @@
|
|||||||
<li><a href="http://www.html5test.com">HTML5 Feature Test</a></li>
|
<li><a href="http://www.html5test.com">HTML5 Feature Test</a></li>
|
||||||
<li><a href="http://html5-demos.appspot.com/static/filesystem/filer.js/demos/index.html">HTML5 Filesystem</a> - requires "cache-path" flag</li>
|
<li><a href="http://html5-demos.appspot.com/static/filesystem/filer.js/demos/index.html">HTML5 Filesystem</a> - requires "cache-path" flag</li>
|
||||||
<li><a href="http://www.youtube.com/watch?v=siOHh0uzcuY&html5=True">HTML5 Video</a></li>
|
<li><a href="http://www.youtube.com/watch?v=siOHh0uzcuY&html5=True">HTML5 Video</a></li>
|
||||||
|
<li><a href="ipc_performance">IPC Performance Tests</a></li>
|
||||||
<li><a href="binding">JavaScript Binding</a></li>
|
<li><a href="binding">JavaScript Binding</a></li>
|
||||||
<li><a href="performance">JavaScript Performance Tests</a></li>
|
<li><a href="performance">JavaScript Performance Tests</a></li>
|
||||||
<li><a href="performance2">JavaScript Performance (2) Tests</a></li>
|
<li><a href="performance2">JavaScript Performance (2) Tests</a></li>
|
||||||
|
@ -32,6 +32,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|||||||
IDS_BINDING_HTML BINARY "..\\binding.html"
|
IDS_BINDING_HTML BINARY "..\\binding.html"
|
||||||
IDS_DIALOGS_HTML BINARY "..\\dialogs.html"
|
IDS_DIALOGS_HTML BINARY "..\\dialogs.html"
|
||||||
IDS_DRAGGABLE_HTML BINARY "..\\draggable.html"
|
IDS_DRAGGABLE_HTML BINARY "..\\draggable.html"
|
||||||
|
IDS_IPC_PERFORMANCE_HTML BINARY "..\\ipc_performance.html"
|
||||||
IDS_LOCALSTORAGE_HTML BINARY "..\\localstorage.html"
|
IDS_LOCALSTORAGE_HTML BINARY "..\\localstorage.html"
|
||||||
IDS_LOGO_PNG BINARY "..\\logo.png"
|
IDS_LOGO_PNG BINARY "..\\logo.png"
|
||||||
IDS_MEDIA_ROUTER_HTML BINARY "..\\media_router.html"
|
IDS_MEDIA_ROUTER_HTML BINARY "..\\media_router.html"
|
||||||
|
@ -59,6 +59,11 @@ void CreateRenderDelegates(ClientAppRenderer::DelegateSet& delegates) {
|
|||||||
delegates);
|
delegates);
|
||||||
CreateProcessMessageRendererTests(delegates);
|
CreateProcessMessageRendererTests(delegates);
|
||||||
|
|
||||||
|
// Bring in the shared process message tests.
|
||||||
|
extern void CreateSharedProcessMessageTests(ClientAppRenderer::DelegateSet &
|
||||||
|
delegates);
|
||||||
|
CreateSharedProcessMessageTests(delegates);
|
||||||
|
|
||||||
// Bring in the RequestHandler tests.
|
// Bring in the RequestHandler tests.
|
||||||
extern void CreateRequestHandlerRendererTests(ClientAppRenderer::DelegateSet &
|
extern void CreateRequestHandlerRendererTests(ClientAppRenderer::DelegateSet &
|
||||||
delegates);
|
delegates);
|
||||||
|
81
tests/ceftests/message_router_harness_unittest.cc
Normal file
81
tests/ceftests/message_router_harness_unittest.cc
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
// Copyright (c) 2022 The Chromium Embedded Framework Authors. All rights
|
||||||
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "tests/ceftests/message_router_unittest_utils.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Used to verify that the test harness (bound functions) behave correctly.
|
||||||
|
class HarnessTestHandler : public SingleLoadTestHandler {
|
||||||
|
public:
|
||||||
|
HarnessTestHandler(bool test_success) : test_success_(test_success) {}
|
||||||
|
|
||||||
|
std::string GetMainHTML() override {
|
||||||
|
std::string html;
|
||||||
|
if (test_success_) {
|
||||||
|
// All assertions should pass.
|
||||||
|
html =
|
||||||
|
"<html><body><script>\n"
|
||||||
|
"var fail_ct = 0;\n"
|
||||||
|
"try { window.mrtAssertTotalCount(" LINESTR
|
||||||
|
",0); } catch (e) { fail_ct++; }\n"
|
||||||
|
"try { window.mrtAssertBrowserCount(" LINESTR
|
||||||
|
",0); } catch (e) { fail_ct++; }\n"
|
||||||
|
"try { window.mrtAssertContextCount(" LINESTR
|
||||||
|
",0); } catch (e) { fail_ct++; }\n"
|
||||||
|
"window.mrtNotify('' + (fail_ct == 0));"
|
||||||
|
"</script></body></html>";
|
||||||
|
} else {
|
||||||
|
// All assertions should fail.
|
||||||
|
html =
|
||||||
|
"<html><body><script>\n"
|
||||||
|
"var fail_ct = 0;\n"
|
||||||
|
"try { window.mrtAssertTotalCount(" LINESTR
|
||||||
|
",1); } catch (e) { fail_ct++; }\n"
|
||||||
|
"try { window.mrtAssertBrowserCount(" LINESTR
|
||||||
|
",1); } catch (e) { fail_ct++; }\n"
|
||||||
|
"try { window.mrtAssertContextCount(" LINESTR
|
||||||
|
",1); } catch (e) { fail_ct++; }\n"
|
||||||
|
"window.mrtNotify('' + (fail_ct == 3));"
|
||||||
|
"</script></body></html>";
|
||||||
|
}
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnNotify(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
const std::string& message) override {
|
||||||
|
AssertMainBrowser(browser);
|
||||||
|
AssertMainFrame(frame);
|
||||||
|
|
||||||
|
got_done_.yes();
|
||||||
|
EXPECT_STREQ("true", message.c_str());
|
||||||
|
DestroyTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyTest() override {
|
||||||
|
EXPECT_TRUE(got_done_);
|
||||||
|
TestHandler::DestroyTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const bool test_success_;
|
||||||
|
TrackCallback got_done_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// Verify that the test harness works with successful assertions.
|
||||||
|
TEST(MessageRouterTest, HarnessSuccess) {
|
||||||
|
CefRefPtr<HarnessTestHandler> handler = new HarnessTestHandler(true);
|
||||||
|
handler->ExecuteTest();
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that the test harness works with failed assertions.
|
||||||
|
TEST(MessageRouterTest, HarnessFailure) {
|
||||||
|
CefRefPtr<HarnessTestHandler> handler = new HarnessTestHandler(false);
|
||||||
|
handler->ExecuteTest();
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
623
tests/ceftests/message_router_single_query_unittest.cc
Normal file
623
tests/ceftests/message_router_single_query_unittest.cc
Normal file
@ -0,0 +1,623 @@
|
|||||||
|
// Copyright (c) 2022 The Chromium Embedded Framework Authors. All rights
|
||||||
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "tests/ceftests/message_router_unittest_utils.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const char kSingleQueryRequest[] = "request_context";
|
||||||
|
const char kSingleQueryResponse[] = "success_response";
|
||||||
|
const int kSingleQueryErrorCode = 5;
|
||||||
|
const char kSingleQueryErrorMessage[] = "error_message";
|
||||||
|
|
||||||
|
// Test a single query in a single page load.
|
||||||
|
class SingleQueryTestHandler : public SingleLoadTestHandler {
|
||||||
|
public:
|
||||||
|
enum TestType {
|
||||||
|
SUCCESS,
|
||||||
|
FAILURE,
|
||||||
|
CANCEL,
|
||||||
|
};
|
||||||
|
|
||||||
|
SingleQueryTestHandler(TestType type, bool sync_callback)
|
||||||
|
: test_type_(type), sync_callback_(sync_callback), query_id_(0) {}
|
||||||
|
|
||||||
|
std::string GetMainHTML() override {
|
||||||
|
std::string html;
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << kSingleQueryErrorCode;
|
||||||
|
const std::string& errorCodeStr = ss.str();
|
||||||
|
|
||||||
|
html =
|
||||||
|
"<html><body><script>\n"
|
||||||
|
// No requests should exist.
|
||||||
|
"window.mrtAssertTotalCount(" LINESTR
|
||||||
|
",0);\n"
|
||||||
|
"window.mrtAssertBrowserCount(" LINESTR
|
||||||
|
",0);\n"
|
||||||
|
"window.mrtAssertContextCount(" LINESTR
|
||||||
|
",0);\n"
|
||||||
|
// Send the query.
|
||||||
|
"var request_id = window.mrtQuery({\n"
|
||||||
|
" request: '" +
|
||||||
|
std::string(kSingleQueryRequest) +
|
||||||
|
"',\n"
|
||||||
|
" persistent: false,\n"
|
||||||
|
" onSuccess: function(response) {\n"
|
||||||
|
// Request should be removed before callback is executed.
|
||||||
|
" window.mrtAssertTotalCount(" LINESTR
|
||||||
|
",0);\n"
|
||||||
|
" window.mrtAssertBrowserCount(" LINESTR
|
||||||
|
",0);\n"
|
||||||
|
" window.mrtAssertContextCount(" LINESTR
|
||||||
|
",0);\n"
|
||||||
|
" if (response == '" +
|
||||||
|
std::string(kSingleQueryResponse) +
|
||||||
|
"')\n"
|
||||||
|
" window.mrtNotify('success');\n"
|
||||||
|
" else\n"
|
||||||
|
" window.mrtNotify('error-onSuccess');\n"
|
||||||
|
" },\n"
|
||||||
|
" onFailure: function(error_code, error_message) {\n"
|
||||||
|
// Request should be removed before callback is executed.
|
||||||
|
" window.mrtAssertTotalCount(" LINESTR
|
||||||
|
",0);\n"
|
||||||
|
" window.mrtAssertBrowserCount(" LINESTR
|
||||||
|
",0);\n"
|
||||||
|
" window.mrtAssertContextCount(" LINESTR
|
||||||
|
",0);\n"
|
||||||
|
" if (error_code == " +
|
||||||
|
errorCodeStr + " && error_message == '" +
|
||||||
|
std::string(kSingleQueryErrorMessage) +
|
||||||
|
"')\n"
|
||||||
|
" window.mrtNotify('failure');\n"
|
||||||
|
" else\n"
|
||||||
|
" window.mrtNotify('error-onFailure');\n"
|
||||||
|
" }\n"
|
||||||
|
"});\n"
|
||||||
|
// Request should exist.
|
||||||
|
"window.mrtAssertTotalCount(" LINESTR
|
||||||
|
",1);\n"
|
||||||
|
"window.mrtAssertBrowserCount(" LINESTR
|
||||||
|
",1);\n"
|
||||||
|
"window.mrtAssertContextCount(" LINESTR ",1);\n";
|
||||||
|
|
||||||
|
if (test_type_ == CANCEL) {
|
||||||
|
html +=
|
||||||
|
"window.mrtQueryCancel(request_id);\n"
|
||||||
|
// Request should be removed immediately.
|
||||||
|
"window.mrtAssertTotalCount(" LINESTR
|
||||||
|
",0);\n"
|
||||||
|
"window.mrtAssertBrowserCount(" LINESTR
|
||||||
|
",0);\n"
|
||||||
|
"window.mrtAssertContextCount(" LINESTR
|
||||||
|
",0);\n"
|
||||||
|
"window.mrtNotify('cancel');\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
html += "</script></body></html>";
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnNotify(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
const std::string& message) override {
|
||||||
|
AssertMainBrowser(browser);
|
||||||
|
AssertMainFrame(frame);
|
||||||
|
|
||||||
|
// OnNotify only be called once.
|
||||||
|
EXPECT_FALSE(got_notify_);
|
||||||
|
got_notify_.yes();
|
||||||
|
|
||||||
|
if (test_type_ == SUCCESS) {
|
||||||
|
EXPECT_STREQ("success", message.c_str());
|
||||||
|
} else if (test_type_ == FAILURE) {
|
||||||
|
EXPECT_STREQ("failure", message.c_str());
|
||||||
|
} else if (test_type_ == CANCEL) {
|
||||||
|
EXPECT_STREQ("cancel", message.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
DestroyTestIfDone();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExecuteCallback() {
|
||||||
|
EXPECT_TRUE(callback_.get());
|
||||||
|
if (test_type_ == SUCCESS) {
|
||||||
|
callback_->Success(kSingleQueryResponse);
|
||||||
|
} else if (test_type_ == FAILURE) {
|
||||||
|
callback_->Failure(kSingleQueryErrorCode, kSingleQueryErrorMessage);
|
||||||
|
} else {
|
||||||
|
ADD_FAILURE(); // Not reached.
|
||||||
|
}
|
||||||
|
callback_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OnQuery(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
int64 query_id,
|
||||||
|
const CefString& request,
|
||||||
|
bool persistent,
|
||||||
|
CefRefPtr<Callback> callback) override {
|
||||||
|
AssertMainBrowser(browser);
|
||||||
|
AssertMainFrame(frame);
|
||||||
|
EXPECT_NE(0, query_id);
|
||||||
|
EXPECT_FALSE(persistent);
|
||||||
|
EXPECT_STREQ(kSingleQueryRequest, request.ToString().c_str());
|
||||||
|
|
||||||
|
got_on_query_.yes();
|
||||||
|
|
||||||
|
query_id_ = query_id;
|
||||||
|
callback_ = callback;
|
||||||
|
|
||||||
|
if (test_type_ == SUCCESS || test_type_ == FAILURE) {
|
||||||
|
if (sync_callback_) {
|
||||||
|
ExecuteCallback();
|
||||||
|
} else {
|
||||||
|
CefPostTask(
|
||||||
|
TID_UI,
|
||||||
|
base::BindOnce(&SingleQueryTestHandler::ExecuteCallback, this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnQueryCanceled(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
int64 query_id) override {
|
||||||
|
AssertMainBrowser(browser);
|
||||||
|
AssertMainFrame(frame);
|
||||||
|
EXPECT_EQ(test_type_, CANCEL);
|
||||||
|
EXPECT_EQ(query_id_, query_id);
|
||||||
|
EXPECT_TRUE(got_on_query_);
|
||||||
|
EXPECT_TRUE(callback_.get());
|
||||||
|
|
||||||
|
got_on_query_canceled_.yes();
|
||||||
|
callback_ = nullptr;
|
||||||
|
|
||||||
|
DestroyTestIfDone();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyTestIfDone() {
|
||||||
|
bool destroy_test = false;
|
||||||
|
if (test_type_ == CANCEL)
|
||||||
|
destroy_test = got_notify_ && got_on_query_canceled_;
|
||||||
|
else
|
||||||
|
destroy_test = got_notify_;
|
||||||
|
if (destroy_test)
|
||||||
|
DestroyTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyTest() override {
|
||||||
|
EXPECT_TRUE(got_notify_);
|
||||||
|
EXPECT_TRUE(got_on_query_);
|
||||||
|
EXPECT_FALSE(callback_.get());
|
||||||
|
|
||||||
|
if (test_type_ == CANCEL)
|
||||||
|
EXPECT_TRUE(got_on_query_canceled_);
|
||||||
|
else
|
||||||
|
EXPECT_FALSE(got_on_query_canceled_);
|
||||||
|
|
||||||
|
TestHandler::DestroyTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const TestType test_type_;
|
||||||
|
const bool sync_callback_;
|
||||||
|
|
||||||
|
int64 query_id_;
|
||||||
|
CefRefPtr<Callback> callback_;
|
||||||
|
|
||||||
|
TrackCallback got_on_query_;
|
||||||
|
TrackCallback got_on_query_canceled_;
|
||||||
|
TrackCallback got_notify_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// Test that a single query with successful result delivered synchronously.
|
||||||
|
TEST(MessageRouterTest, SingleQuerySuccessSyncCallback) {
|
||||||
|
CefRefPtr<SingleQueryTestHandler> handler =
|
||||||
|
new SingleQueryTestHandler(SingleQueryTestHandler::SUCCESS, true);
|
||||||
|
handler->ExecuteTest();
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that a single query with successful result delivered asynchronously.
|
||||||
|
TEST(MessageRouterTest, SingleQuerySuccessAsyncCallback) {
|
||||||
|
CefRefPtr<SingleQueryTestHandler> handler =
|
||||||
|
new SingleQueryTestHandler(SingleQueryTestHandler::SUCCESS, false);
|
||||||
|
handler->ExecuteTest();
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that a single query with failure result delivered synchronously.
|
||||||
|
TEST(MessageRouterTest, SingleQueryFailureSyncCallback) {
|
||||||
|
CefRefPtr<SingleQueryTestHandler> handler =
|
||||||
|
new SingleQueryTestHandler(SingleQueryTestHandler::FAILURE, true);
|
||||||
|
handler->ExecuteTest();
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that a single query with failure result delivered asynchronously.
|
||||||
|
TEST(MessageRouterTest, SingleQueryFailureAsyncCallback) {
|
||||||
|
CefRefPtr<SingleQueryTestHandler> handler =
|
||||||
|
new SingleQueryTestHandler(SingleQueryTestHandler::FAILURE, false);
|
||||||
|
handler->ExecuteTest();
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that a single query with cancellation.
|
||||||
|
TEST(MessageRouterTest, SingleQueryCancel) {
|
||||||
|
CefRefPtr<SingleQueryTestHandler> handler =
|
||||||
|
new SingleQueryTestHandler(SingleQueryTestHandler::CANCEL, true);
|
||||||
|
handler->ExecuteTest();
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const int kSinglePersistentQueryResponseCount = 10;
|
||||||
|
|
||||||
|
// Test a single persistent query in a single page load.
|
||||||
|
class SinglePersistentQueryTestHandler : public SingleLoadTestHandler {
|
||||||
|
public:
|
||||||
|
enum TestType {
|
||||||
|
SUCCESS,
|
||||||
|
FAILURE,
|
||||||
|
};
|
||||||
|
|
||||||
|
SinglePersistentQueryTestHandler(TestType test_type, bool sync_callback)
|
||||||
|
: test_type_(test_type), sync_callback_(sync_callback), query_id_(0) {}
|
||||||
|
|
||||||
|
std::string GetMainHTML() override {
|
||||||
|
std::string html;
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << kSinglePersistentQueryResponseCount;
|
||||||
|
const std::string& responseCountStr = ss.str();
|
||||||
|
ss.str("");
|
||||||
|
ss << kSingleQueryErrorCode;
|
||||||
|
const std::string& errorCodeStr = ss.str();
|
||||||
|
|
||||||
|
html =
|
||||||
|
"<html><body><script>\n"
|
||||||
|
// No requests should exist.
|
||||||
|
"window.mrtAssertTotalCount(" LINESTR
|
||||||
|
",0);\n"
|
||||||
|
"window.mrtAssertBrowserCount(" LINESTR
|
||||||
|
",0);\n"
|
||||||
|
"window.mrtAssertContextCount(" LINESTR
|
||||||
|
",0);\n"
|
||||||
|
// Keep track of the number of responses.
|
||||||
|
"var count = 0;\n"
|
||||||
|
// Send the query.
|
||||||
|
"var request_id = window.mrtQuery({\n"
|
||||||
|
" request: '" +
|
||||||
|
std::string(kSingleQueryRequest) +
|
||||||
|
"',\n"
|
||||||
|
" persistent: true,\n"
|
||||||
|
" onSuccess: function(response) {\n"
|
||||||
|
// Request should not be removed.
|
||||||
|
" window.mrtAssertTotalCount(" LINESTR
|
||||||
|
",1);\n"
|
||||||
|
" window.mrtAssertBrowserCount(" LINESTR
|
||||||
|
",1);\n"
|
||||||
|
" window.mrtAssertContextCount(" LINESTR
|
||||||
|
",1);\n"
|
||||||
|
" if (response == '" +
|
||||||
|
std::string(kSingleQueryResponse) +
|
||||||
|
"') {\n"
|
||||||
|
" if (++count == " +
|
||||||
|
responseCountStr +
|
||||||
|
") {\n"
|
||||||
|
" window.mrtNotify('success');\n"
|
||||||
|
" window.mrtQueryCancel(request_id);\n"
|
||||||
|
// Request should be removed immediately.
|
||||||
|
" window.mrtAssertTotalCount(" LINESTR
|
||||||
|
",0);\n"
|
||||||
|
" window.mrtAssertBrowserCount(" LINESTR
|
||||||
|
",0);\n"
|
||||||
|
" window.mrtAssertContextCount(" LINESTR
|
||||||
|
",0);\n"
|
||||||
|
" }\n"
|
||||||
|
" } else {\n"
|
||||||
|
" window.mrtNotify('error-onSuccess');\n"
|
||||||
|
" }\n"
|
||||||
|
" },\n"
|
||||||
|
" onFailure: function(error_code, error_message) {\n"
|
||||||
|
// Request should be removed before callback is executed.
|
||||||
|
" window.mrtAssertTotalCount(" LINESTR
|
||||||
|
",0);\n"
|
||||||
|
" window.mrtAssertBrowserCount(" LINESTR
|
||||||
|
",0);\n"
|
||||||
|
" window.mrtAssertContextCount(" LINESTR
|
||||||
|
",0);\n"
|
||||||
|
" if (error_code == " +
|
||||||
|
errorCodeStr + " && error_message == '" +
|
||||||
|
std::string(kSingleQueryErrorMessage) +
|
||||||
|
"') {\n"
|
||||||
|
" window.mrtNotify('failure');\n"
|
||||||
|
" } else {\n"
|
||||||
|
" window.mrtNotify('error-onFailure');\n"
|
||||||
|
" }\n"
|
||||||
|
" }\n"
|
||||||
|
"});\n"
|
||||||
|
// Request should exist.
|
||||||
|
"window.mrtAssertTotalCount(" LINESTR
|
||||||
|
",1);\n"
|
||||||
|
"window.mrtAssertBrowserCount(" LINESTR
|
||||||
|
",1);\n"
|
||||||
|
"window.mrtAssertContextCount(" LINESTR ",1);\n";
|
||||||
|
|
||||||
|
html += "</script></body></html>";
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnNotify(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
const std::string& message) override {
|
||||||
|
AssertMainBrowser(browser);
|
||||||
|
AssertMainFrame(frame);
|
||||||
|
|
||||||
|
if (test_type_ == SUCCESS) {
|
||||||
|
EXPECT_STREQ("success", message.c_str());
|
||||||
|
} else if (test_type_ == FAILURE) {
|
||||||
|
EXPECT_STREQ("failure", message.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
got_notify_.yes();
|
||||||
|
|
||||||
|
DestroyTestIfDone();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExecuteCallback() {
|
||||||
|
EXPECT_TRUE(callback_.get());
|
||||||
|
if (test_type_ == SUCCESS) {
|
||||||
|
callback_->Success(kSingleQueryResponse);
|
||||||
|
} else {
|
||||||
|
callback_->Failure(kSingleQueryErrorCode, kSingleQueryErrorMessage);
|
||||||
|
callback_ = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OnQuery(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
int64 query_id,
|
||||||
|
const CefString& request,
|
||||||
|
bool persistent,
|
||||||
|
CefRefPtr<Callback> callback) override {
|
||||||
|
AssertMainBrowser(browser);
|
||||||
|
AssertMainFrame(frame);
|
||||||
|
EXPECT_NE(0, query_id);
|
||||||
|
EXPECT_TRUE(persistent);
|
||||||
|
EXPECT_STREQ(kSingleQueryRequest, request.ToString().c_str());
|
||||||
|
|
||||||
|
got_on_query_.yes();
|
||||||
|
|
||||||
|
query_id_ = query_id;
|
||||||
|
callback_ = callback;
|
||||||
|
|
||||||
|
int repeat =
|
||||||
|
(test_type_ == SUCCESS ? kSinglePersistentQueryResponseCount : 1);
|
||||||
|
|
||||||
|
for (int i = 0; i < repeat; ++i) {
|
||||||
|
if (sync_callback_) {
|
||||||
|
ExecuteCallback();
|
||||||
|
} else {
|
||||||
|
CefPostTask(
|
||||||
|
TID_UI,
|
||||||
|
base::BindOnce(&SinglePersistentQueryTestHandler::ExecuteCallback,
|
||||||
|
this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnQueryCanceled(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
int64 query_id) override {
|
||||||
|
AssertMainBrowser(browser);
|
||||||
|
AssertMainFrame(frame);
|
||||||
|
EXPECT_EQ(query_id_, query_id);
|
||||||
|
EXPECT_TRUE(got_on_query_);
|
||||||
|
EXPECT_TRUE(callback_.get());
|
||||||
|
|
||||||
|
got_on_query_canceled_.yes();
|
||||||
|
callback_ = nullptr;
|
||||||
|
|
||||||
|
DestroyTestIfDone();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyTestIfDone() {
|
||||||
|
bool destroy_test = false;
|
||||||
|
if (test_type_ == SUCCESS) {
|
||||||
|
if (got_on_query_ && got_on_query_canceled_ && got_notify_)
|
||||||
|
destroy_test = true;
|
||||||
|
} else if (got_on_query_ && got_notify_) {
|
||||||
|
destroy_test = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (destroy_test)
|
||||||
|
DestroyTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyTest() override {
|
||||||
|
EXPECT_TRUE(got_notify_);
|
||||||
|
EXPECT_TRUE(got_on_query_);
|
||||||
|
EXPECT_FALSE(callback_.get());
|
||||||
|
|
||||||
|
if (test_type_ == SUCCESS)
|
||||||
|
EXPECT_TRUE(got_on_query_canceled_);
|
||||||
|
else
|
||||||
|
EXPECT_FALSE(got_on_query_canceled_);
|
||||||
|
|
||||||
|
TestHandler::DestroyTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const TestType test_type_;
|
||||||
|
const bool sync_callback_;
|
||||||
|
|
||||||
|
int64 query_id_;
|
||||||
|
CefRefPtr<Callback> callback_;
|
||||||
|
|
||||||
|
TrackCallback got_on_query_;
|
||||||
|
TrackCallback got_on_query_canceled_;
|
||||||
|
TrackCallback got_notify_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// Test that a single query with successful result delivered synchronously.
|
||||||
|
TEST(MessageRouterTest, SinglePersistentQuerySuccessSyncCallback) {
|
||||||
|
CefRefPtr<SinglePersistentQueryTestHandler> handler =
|
||||||
|
new SinglePersistentQueryTestHandler(
|
||||||
|
SinglePersistentQueryTestHandler::SUCCESS, true);
|
||||||
|
handler->ExecuteTest();
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that a single query with successful result delivered asynchronously.
|
||||||
|
TEST(MessageRouterTest, SinglePersistentQuerySuccessAsyncCallback) {
|
||||||
|
CefRefPtr<SinglePersistentQueryTestHandler> handler =
|
||||||
|
new SinglePersistentQueryTestHandler(
|
||||||
|
SinglePersistentQueryTestHandler::SUCCESS, false);
|
||||||
|
handler->ExecuteTest();
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that a single query with failure result delivered synchronously.
|
||||||
|
TEST(MessageRouterTest, SinglePersistentQueryFailureSyncCallback) {
|
||||||
|
CefRefPtr<SinglePersistentQueryTestHandler> handler =
|
||||||
|
new SinglePersistentQueryTestHandler(
|
||||||
|
SinglePersistentQueryTestHandler::FAILURE, true);
|
||||||
|
handler->ExecuteTest();
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that a single query with failure result delivered asynchronously.
|
||||||
|
TEST(MessageRouterTest, SinglePersistentQueryFailureAsyncCallback) {
|
||||||
|
CefRefPtr<SinglePersistentQueryTestHandler> handler =
|
||||||
|
new SinglePersistentQueryTestHandler(
|
||||||
|
SinglePersistentQueryTestHandler::FAILURE, false);
|
||||||
|
handler->ExecuteTest();
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Test a single unhandled query in a single page load.
|
||||||
|
class SingleUnhandledQueryTestHandler : public SingleLoadTestHandler {
|
||||||
|
public:
|
||||||
|
SingleUnhandledQueryTestHandler() {}
|
||||||
|
|
||||||
|
std::string GetMainHTML() override {
|
||||||
|
std::string html;
|
||||||
|
|
||||||
|
html =
|
||||||
|
"<html><body><script>\n"
|
||||||
|
// No requests should exist.
|
||||||
|
"window.mrtAssertTotalCount(" LINESTR
|
||||||
|
",0);\n"
|
||||||
|
"window.mrtAssertBrowserCount(" LINESTR
|
||||||
|
",0);\n"
|
||||||
|
"window.mrtAssertContextCount(" LINESTR
|
||||||
|
",0);\n"
|
||||||
|
// Keep track of the number of responses.
|
||||||
|
"var count = 0;\n"
|
||||||
|
// Send the query.
|
||||||
|
"var request_id = window.mrtQuery({\n"
|
||||||
|
" request: '" +
|
||||||
|
std::string(kSingleQueryRequest) +
|
||||||
|
"',\n"
|
||||||
|
" persistent: false,\n"
|
||||||
|
" onSuccess: function(response) {\n"
|
||||||
|
" window.mrtNotify('error-onSuccess');\n"
|
||||||
|
" },\n"
|
||||||
|
" onFailure: function(error_code, error_message) {\n"
|
||||||
|
// Request should be removed before callback is executed.
|
||||||
|
" window.mrtAssertTotalCount(" LINESTR
|
||||||
|
",0);\n"
|
||||||
|
" window.mrtAssertBrowserCount(" LINESTR
|
||||||
|
",0);\n"
|
||||||
|
" window.mrtAssertContextCount(" LINESTR
|
||||||
|
",0);\n"
|
||||||
|
" if (error_code == -1 && "
|
||||||
|
"error_message == 'The query has been canceled') {\n"
|
||||||
|
" window.mrtNotify('failure');\n"
|
||||||
|
" } else {\n"
|
||||||
|
" window.mrtNotify('error-onFailure');\n"
|
||||||
|
" }\n"
|
||||||
|
" }\n"
|
||||||
|
"});\n"
|
||||||
|
// Request should exist.
|
||||||
|
"window.mrtAssertTotalCount(" LINESTR
|
||||||
|
",1);\n"
|
||||||
|
"window.mrtAssertBrowserCount(" LINESTR
|
||||||
|
",1);\n"
|
||||||
|
"window.mrtAssertContextCount(" LINESTR ",1);\n";
|
||||||
|
|
||||||
|
html += "</script></body></html>";
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnNotify(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
const std::string& message) override {
|
||||||
|
AssertMainBrowser(browser);
|
||||||
|
AssertMainFrame(frame);
|
||||||
|
EXPECT_STREQ("failure", message.c_str());
|
||||||
|
|
||||||
|
got_notify_.yes();
|
||||||
|
|
||||||
|
DestroyTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OnQuery(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
int64 query_id,
|
||||||
|
const CefString& request,
|
||||||
|
bool persistent,
|
||||||
|
CefRefPtr<Callback> callback) override {
|
||||||
|
AssertMainBrowser(browser);
|
||||||
|
AssertMainFrame(frame);
|
||||||
|
EXPECT_NE(0, query_id);
|
||||||
|
EXPECT_FALSE(persistent);
|
||||||
|
EXPECT_STREQ(kSingleQueryRequest, request.ToString().c_str());
|
||||||
|
|
||||||
|
got_on_query_.yes();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnQueryCanceled(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
int64 query_id) override {
|
||||||
|
EXPECT_FALSE(true); // Not reached.
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyTest() override {
|
||||||
|
EXPECT_TRUE(got_on_query_);
|
||||||
|
EXPECT_TRUE(got_notify_);
|
||||||
|
|
||||||
|
TestHandler::DestroyTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TrackCallback got_on_query_;
|
||||||
|
TrackCallback got_notify_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// Test that a single unhandled query results in a call to onFailure.
|
||||||
|
TEST(MessageRouterTest, SingleUnhandledQuery) {
|
||||||
|
CefRefPtr<SingleUnhandledQueryTestHandler> handler =
|
||||||
|
new SingleUnhandledQueryTestHandler();
|
||||||
|
handler->ExecuteTest();
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
222
tests/ceftests/message_router_threshold_unittest.cc
Normal file
222
tests/ceftests/message_router_threshold_unittest.cc
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
// Copyright (c) 2022 The Chromium Embedded Framework Authors. All rights
|
||||||
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "tests/ceftests/message_router_unittest_utils.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr int kSingleQueryErrorCode = 5;
|
||||||
|
constexpr size_t kMessageSizeThreshold = 16000;
|
||||||
|
|
||||||
|
enum class TestType { SUCCESS, FAILURE };
|
||||||
|
|
||||||
|
CefString GenerateResponse(size_t size, char ch) {
|
||||||
|
return CefString(std::string(size, ch));
|
||||||
|
}
|
||||||
|
|
||||||
|
CefString GenerateResponse(size_t size, wchar_t ch) {
|
||||||
|
return CefString(std::wstring(size, ch));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharType>
|
||||||
|
class ThresholdTestHandler final : public SingleLoadTestHandler {
|
||||||
|
public:
|
||||||
|
ThresholdTestHandler(TestType type, size_t message_size, CharType symbol)
|
||||||
|
: test_type_(type),
|
||||||
|
message_size_(message_size),
|
||||||
|
message_size_str_(std::to_string(message_size)),
|
||||||
|
symbol_(symbol) {}
|
||||||
|
|
||||||
|
std::string GetMainHTML() override {
|
||||||
|
const std::string& errorCodeStr = std::to_string(kSingleQueryErrorCode);
|
||||||
|
|
||||||
|
std::string html =
|
||||||
|
"<html><body><script>\n"
|
||||||
|
// Send the query.
|
||||||
|
"var request_id = window." +
|
||||||
|
std::string(kJSQueryFunc) + "({\n request: '" + message_size_str_ +
|
||||||
|
"',\n persistent: false,\n"
|
||||||
|
" onSuccess: function(response) {\n"
|
||||||
|
" window.mrtNotify(response);\n"
|
||||||
|
" },\n"
|
||||||
|
" onFailure: function(error_code, error_message) {\n"
|
||||||
|
" if (error_code == " +
|
||||||
|
errorCodeStr +
|
||||||
|
")\n"
|
||||||
|
" window.mrtNotify(error_message);\n"
|
||||||
|
" else\n"
|
||||||
|
" window.mrtNotify('error-onFailure');\n"
|
||||||
|
" }\n"
|
||||||
|
"});\n</script></body></html>";
|
||||||
|
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnNotify(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
const std::string& message) override {
|
||||||
|
AssertMainBrowser(browser);
|
||||||
|
AssertMainFrame(frame);
|
||||||
|
|
||||||
|
// OnNotify only be called once.
|
||||||
|
EXPECT_FALSE(got_notify_);
|
||||||
|
got_notify_.yes();
|
||||||
|
|
||||||
|
auto expected = GenerateResponse(message_size_, symbol_);
|
||||||
|
|
||||||
|
switch (test_type_) {
|
||||||
|
case TestType::SUCCESS:
|
||||||
|
EXPECT_EQ(expected, message);
|
||||||
|
break;
|
||||||
|
case TestType::FAILURE:
|
||||||
|
EXPECT_EQ(expected, message);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ADD_FAILURE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DestroyTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExecuteCallback(size_t response_size) {
|
||||||
|
auto response = GenerateResponse(response_size, symbol_);
|
||||||
|
|
||||||
|
EXPECT_TRUE(callback_.get());
|
||||||
|
switch (test_type_) {
|
||||||
|
case TestType::SUCCESS:
|
||||||
|
callback_->Success(response);
|
||||||
|
break;
|
||||||
|
case TestType::FAILURE:
|
||||||
|
callback_->Failure(kSingleQueryErrorCode, response);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ADD_FAILURE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
callback_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OnQuery(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
int64 query_id,
|
||||||
|
const CefString& request,
|
||||||
|
bool persistent,
|
||||||
|
CefRefPtr<Callback> callback) override {
|
||||||
|
AssertMainBrowser(browser);
|
||||||
|
AssertMainFrame(frame);
|
||||||
|
EXPECT_NE(0, query_id);
|
||||||
|
EXPECT_FALSE(persistent);
|
||||||
|
EXPECT_EQ(message_size_str_, request.ToString());
|
||||||
|
|
||||||
|
const size_t message_size =
|
||||||
|
static_cast<size_t>(std::stoi(request.ToString()));
|
||||||
|
got_on_query_.yes();
|
||||||
|
|
||||||
|
callback_ = callback;
|
||||||
|
ExecuteCallback(message_size);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyTest() override {
|
||||||
|
EXPECT_TRUE(got_notify_);
|
||||||
|
EXPECT_TRUE(got_on_query_);
|
||||||
|
EXPECT_FALSE(callback_.get());
|
||||||
|
|
||||||
|
TestHandler::DestroyTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const TestType test_type_;
|
||||||
|
const size_t message_size_;
|
||||||
|
const std::string message_size_str_;
|
||||||
|
const CharType symbol_;
|
||||||
|
|
||||||
|
CefRefPtr<Callback> callback_;
|
||||||
|
|
||||||
|
TrackCallback got_on_query_;
|
||||||
|
TrackCallback got_notify_;
|
||||||
|
};
|
||||||
|
|
||||||
|
using CharTestHandler = CefRefPtr<ThresholdTestHandler<char>>;
|
||||||
|
using WCharTestHandler = CefRefPtr<ThresholdTestHandler<wchar_t>>;
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST(MessageRouterTest, ThresholdMessageUnderSuccessCallback) {
|
||||||
|
const auto UnderThreshold = kMessageSizeThreshold - 1;
|
||||||
|
CharTestHandler handler =
|
||||||
|
new ThresholdTestHandler(TestType::SUCCESS, UnderThreshold, 'A');
|
||||||
|
handler->SetMessageSizeThreshold(kMessageSizeThreshold);
|
||||||
|
|
||||||
|
handler->ExecuteTest();
|
||||||
|
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MessageRouterTest, ThresholMessageExactdSuccessCallback) {
|
||||||
|
CharTestHandler handler =
|
||||||
|
new ThresholdTestHandler(TestType::SUCCESS, kMessageSizeThreshold, 'A');
|
||||||
|
handler->SetMessageSizeThreshold(kMessageSizeThreshold);
|
||||||
|
|
||||||
|
handler->ExecuteTest();
|
||||||
|
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MessageRouterTest, ThresholdMessageOverSuccessCallback) {
|
||||||
|
const auto OverThreshold = kMessageSizeThreshold + 1;
|
||||||
|
CharTestHandler handler =
|
||||||
|
new ThresholdTestHandler(TestType::SUCCESS, OverThreshold, 'A');
|
||||||
|
handler->SetMessageSizeThreshold(kMessageSizeThreshold);
|
||||||
|
|
||||||
|
handler->ExecuteTest();
|
||||||
|
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MessageRouterTest, ThresholdMessageUnderFailureCallback) {
|
||||||
|
const auto UnderThreshold = kMessageSizeThreshold - 1;
|
||||||
|
CharTestHandler handler =
|
||||||
|
new ThresholdTestHandler(TestType::FAILURE, UnderThreshold, 'A');
|
||||||
|
handler->SetMessageSizeThreshold(kMessageSizeThreshold);
|
||||||
|
|
||||||
|
handler->ExecuteTest();
|
||||||
|
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MessageRouterTest, ThresholMessageOverdFailureCallback) {
|
||||||
|
const auto OverThreshold = kMessageSizeThreshold + 1;
|
||||||
|
CharTestHandler handler =
|
||||||
|
new ThresholdTestHandler(TestType::FAILURE, OverThreshold, 'A');
|
||||||
|
handler->SetMessageSizeThreshold(kMessageSizeThreshold);
|
||||||
|
|
||||||
|
handler->ExecuteTest();
|
||||||
|
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MessageRouterTest, ThresholdUtf8MessageUnderSuccessCallback) {
|
||||||
|
const auto UnderThreshold = kMessageSizeThreshold - 1;
|
||||||
|
WCharTestHandler handler =
|
||||||
|
new ThresholdTestHandler(TestType::SUCCESS, UnderThreshold, L'\u304B');
|
||||||
|
handler->SetMessageSizeThreshold(kMessageSizeThreshold);
|
||||||
|
|
||||||
|
handler->ExecuteTest();
|
||||||
|
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MessageRouterTest, ThresholdUtf8MessageOverSuccessCallback) {
|
||||||
|
const auto OverThreshold = kMessageSizeThreshold + 1;
|
||||||
|
WCharTestHandler handler =
|
||||||
|
new ThresholdTestHandler(TestType::SUCCESS, OverThreshold, L'\u304B');
|
||||||
|
handler->SetMessageSizeThreshold(kMessageSizeThreshold);
|
||||||
|
|
||||||
|
handler->ExecuteTest();
|
||||||
|
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
256
tests/ceftests/message_router_unittest_utils.cc
Normal file
256
tests/ceftests/message_router_unittest_utils.cc
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
// Copyright (c) 2022 The Chromium Embedded Framework Authors. All rights
|
||||||
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "tests/ceftests/message_router_unittest_utils.h"
|
||||||
|
|
||||||
|
extern const char kJSQueryFunc[] = "mrtQuery";
|
||||||
|
extern const char kJSQueryCancelFunc[] = "mrtQueryCancel";
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const char kTestDomainRoot[] = "http://tests-mr";
|
||||||
|
const char kDoneMessageName[] = "mrtNotifyMsg";
|
||||||
|
const char kJSNotifyFunc[] = "mrtNotify";
|
||||||
|
const char kJSAssertTotalCountFunc[] = "mrtAssertTotalCount";
|
||||||
|
const char kJSAssertBrowserCountFunc[] = "mrtAssertBrowserCount";
|
||||||
|
const char kJSAssertContextCountFunc[] = "mrtAssertContextCount";
|
||||||
|
|
||||||
|
void SetRouterConfig(CefMessageRouterConfig& config) {
|
||||||
|
config.js_query_function = kJSQueryFunc;
|
||||||
|
config.js_cancel_function = kJSQueryCancelFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// Entry point for creating the test delegate.
|
||||||
|
// Called from client_app_delegates.cc.
|
||||||
|
void CreateMessageRouterRendererTests(
|
||||||
|
ClientAppRenderer::DelegateSet& delegates) {
|
||||||
|
delegates.insert(new MRRenderDelegate);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MRRenderDelegate::V8HandlerImpl::Execute(const CefString& name,
|
||||||
|
CefRefPtr<CefV8Value> object,
|
||||||
|
const CefV8ValueList& arguments,
|
||||||
|
CefRefPtr<CefV8Value>& retval,
|
||||||
|
CefString& exception) {
|
||||||
|
const std::string& message_name = name;
|
||||||
|
if (message_name == kJSNotifyFunc) {
|
||||||
|
EXPECT_EQ(1U, arguments.size());
|
||||||
|
EXPECT_TRUE(arguments[0]->IsString());
|
||||||
|
|
||||||
|
const CefString& msg = arguments[0]->GetStringValue();
|
||||||
|
CefRefPtr<CefV8Context> context = CefV8Context::GetCurrentContext();
|
||||||
|
CefRefPtr<CefFrame> frame = context->GetFrame();
|
||||||
|
|
||||||
|
CefRefPtr<CefProcessMessage> message =
|
||||||
|
CefProcessMessage::Create(kDoneMessageName);
|
||||||
|
CefRefPtr<CefListValue> args = message->GetArgumentList();
|
||||||
|
args->SetString(0, msg);
|
||||||
|
frame->SendProcessMessage(PID_BROWSER, message);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
EXPECT_EQ(2U, arguments.size());
|
||||||
|
EXPECT_TRUE(arguments[0]->IsInt());
|
||||||
|
EXPECT_TRUE(arguments[1]->IsInt());
|
||||||
|
|
||||||
|
const int line_no = arguments[0]->GetIntValue();
|
||||||
|
const int expected_count = arguments[1]->GetIntValue();
|
||||||
|
int actual_count = -1;
|
||||||
|
|
||||||
|
CefRefPtr<CefV8Context> context = CefV8Context::GetCurrentContext();
|
||||||
|
CefRefPtr<CefBrowser> browser = context->GetBrowser();
|
||||||
|
|
||||||
|
if (name == kJSAssertTotalCountFunc) {
|
||||||
|
actual_count =
|
||||||
|
delegate_->message_router_->GetPendingCount(nullptr, nullptr);
|
||||||
|
} else if (name == kJSAssertBrowserCountFunc) {
|
||||||
|
actual_count =
|
||||||
|
delegate_->message_router_->GetPendingCount(browser, nullptr);
|
||||||
|
} else if (name == kJSAssertContextCountFunc) {
|
||||||
|
actual_count =
|
||||||
|
delegate_->message_router_->GetPendingCount(browser, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expected_count != actual_count) {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << message_name << " failed (line " << line_no << "); expected "
|
||||||
|
<< expected_count << ", got " << actual_count;
|
||||||
|
exception = ss.str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MRRenderDelegate::OnWebKitInitialized(CefRefPtr<ClientAppRenderer> app) {
|
||||||
|
// Create the renderer-side router for query handling.
|
||||||
|
CefMessageRouterConfig config;
|
||||||
|
SetRouterConfig(config);
|
||||||
|
message_router_ = CefMessageRouterRendererSide::Create(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MRRenderDelegate::OnContextCreated(CefRefPtr<ClientAppRenderer> app,
|
||||||
|
CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
CefRefPtr<CefV8Context> context) {
|
||||||
|
const std::string& url = frame->GetURL();
|
||||||
|
if (url.find(kTestDomainRoot) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
message_router_->OnContextCreated(browser, frame, context);
|
||||||
|
|
||||||
|
// Register function handlers with the 'window' object.
|
||||||
|
CefRefPtr<CefV8Value> window = context->GetGlobal();
|
||||||
|
|
||||||
|
CefRefPtr<V8HandlerImpl> handler = new V8HandlerImpl(this);
|
||||||
|
CefV8Value::PropertyAttribute attributes =
|
||||||
|
static_cast<CefV8Value::PropertyAttribute>(
|
||||||
|
V8_PROPERTY_ATTRIBUTE_READONLY | V8_PROPERTY_ATTRIBUTE_DONTENUM |
|
||||||
|
V8_PROPERTY_ATTRIBUTE_DONTDELETE);
|
||||||
|
|
||||||
|
CefRefPtr<CefV8Value> notify_func =
|
||||||
|
CefV8Value::CreateFunction(kJSNotifyFunc, handler.get());
|
||||||
|
window->SetValue(kJSNotifyFunc, notify_func, attributes);
|
||||||
|
|
||||||
|
CefRefPtr<CefV8Value> total_count_func =
|
||||||
|
CefV8Value::CreateFunction(kJSAssertTotalCountFunc, handler.get());
|
||||||
|
window->SetValue(kJSAssertTotalCountFunc, total_count_func, attributes);
|
||||||
|
|
||||||
|
CefRefPtr<CefV8Value> browser_count_func =
|
||||||
|
CefV8Value::CreateFunction(kJSAssertBrowserCountFunc, handler.get());
|
||||||
|
window->SetValue(kJSAssertBrowserCountFunc, browser_count_func, attributes);
|
||||||
|
|
||||||
|
CefRefPtr<CefV8Value> context_count_func =
|
||||||
|
CefV8Value::CreateFunction(kJSAssertContextCountFunc, handler.get());
|
||||||
|
window->SetValue(kJSAssertContextCountFunc, context_count_func, attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MRRenderDelegate::OnContextReleased(CefRefPtr<ClientAppRenderer> app,
|
||||||
|
CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
CefRefPtr<CefV8Context> context) {
|
||||||
|
const std::string& url = frame->GetURL();
|
||||||
|
if (url.find(kTestDomainRoot) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
message_router_->OnContextReleased(browser, frame, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MRRenderDelegate::OnProcessMessageReceived(
|
||||||
|
CefRefPtr<ClientAppRenderer> app,
|
||||||
|
CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
CefProcessId source_process,
|
||||||
|
CefRefPtr<CefProcessMessage> message) {
|
||||||
|
const std::string& url = frame->GetURL();
|
||||||
|
if (url.find(kTestDomainRoot) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return message_router_->OnProcessMessageReceived(browser, frame,
|
||||||
|
source_process, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MRTestHandler::RunTest() {
|
||||||
|
RunMRTest();
|
||||||
|
|
||||||
|
// Time out the test after a reasonable period of time.
|
||||||
|
SetTestTimeout(10000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MRTestHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
|
||||||
|
if (!message_router_.get()) {
|
||||||
|
// Create the browser-side router for query handling.
|
||||||
|
CefMessageRouterConfig config;
|
||||||
|
|
||||||
|
SetRouterConfig(config);
|
||||||
|
if (message_size_threshold_)
|
||||||
|
config.message_size_threshold = message_size_threshold_;
|
||||||
|
|
||||||
|
message_router_ = CefMessageRouterBrowserSide::Create(config);
|
||||||
|
AddHandlers(message_router_);
|
||||||
|
}
|
||||||
|
TestHandler::OnAfterCreated(browser);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MRTestHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
||||||
|
message_router_->OnBeforeClose(browser);
|
||||||
|
TestHandler::OnBeforeClose(browser);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MRTestHandler::OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
|
||||||
|
TerminationStatus status) {
|
||||||
|
message_router_->OnRenderProcessTerminated(browser);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MRTestHandler::OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
CefRefPtr<CefRequest> request,
|
||||||
|
bool user_gesture,
|
||||||
|
bool is_redirect) {
|
||||||
|
message_router_->OnBeforeBrowse(browser, frame);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if the router handled the navigation.
|
||||||
|
bool MRTestHandler::OnProcessMessageReceived(
|
||||||
|
CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
CefProcessId source_process,
|
||||||
|
CefRefPtr<CefProcessMessage> message) {
|
||||||
|
const std::string& message_name = message->GetName();
|
||||||
|
if (message_name == kDoneMessageName) {
|
||||||
|
CefRefPtr<CefListValue> args = message->GetArgumentList();
|
||||||
|
EXPECT_EQ(1U, args->GetSize());
|
||||||
|
EXPECT_EQ(VTYPE_STRING, args->GetType(0));
|
||||||
|
OnNotify(browser, frame, args->GetString(0));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return message_router_->OnProcessMessageReceived(browser, frame,
|
||||||
|
source_process, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
CefRefPtr<CefMessageRouterBrowserSide> MRTestHandler::GetRouter() const {
|
||||||
|
return message_router_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MRTestHandler::SetMessageSizeThreshold(size_t message_size_threshold) {
|
||||||
|
message_size_threshold_ = message_size_threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MRTestHandler::AssertQueryCount(
|
||||||
|
CefRefPtr<CefBrowser> browser,
|
||||||
|
CefMessageRouterBrowserSide::Handler* handler,
|
||||||
|
int expected_count) {
|
||||||
|
int actual_count = message_router_->GetPendingCount(browser, handler);
|
||||||
|
EXPECT_EQ(expected_count, actual_count);
|
||||||
|
return (expected_count == actual_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MRTestHandler::AssertMainBrowser(CefRefPtr<CefBrowser> browser) {
|
||||||
|
EXPECT_TRUE(browser.get());
|
||||||
|
EXPECT_EQ(GetBrowserId(), browser->GetIdentifier());
|
||||||
|
}
|
||||||
|
|
||||||
|
SingleLoadTestHandler::SingleLoadTestHandler()
|
||||||
|
: main_url_("http://tests-mr.com/main.html") {}
|
||||||
|
|
||||||
|
void SingleLoadTestHandler::RunMRTest() {
|
||||||
|
AddOtherResources();
|
||||||
|
AddResource(main_url_, GetMainHTML(), "text/html");
|
||||||
|
|
||||||
|
CreateBrowser(main_url_, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SingleLoadTestHandler::AddHandlers(
|
||||||
|
CefRefPtr<CefMessageRouterBrowserSide> message_router) {
|
||||||
|
message_router->AddHandler(this, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SingleLoadTestHandler::AssertMainFrame(CefRefPtr<CefFrame> frame) {
|
||||||
|
EXPECT_TRUE(frame.get());
|
||||||
|
EXPECT_TRUE(frame->IsMain());
|
||||||
|
EXPECT_STREQ(main_url_.c_str(), frame->GetURL().ToString().c_str());
|
||||||
|
}
|
137
tests/ceftests/message_router_unittest_utils.h
Normal file
137
tests/ceftests/message_router_unittest_utils.h
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
// Copyright (c) 2022 The Chromium Embedded Framework Authors. All rights
|
||||||
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef CEF_TESTS_CEFTESTS_MESSAGE_ROUTER_UNITTEST_UTILS_H_
|
||||||
|
#define CEF_TESTS_CEFTESTS_MESSAGE_ROUTER_UNITTEST_UTILS_H_
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#include "include/base/cef_callback.h"
|
||||||
|
#include "include/base/cef_weak_ptr.h"
|
||||||
|
#include "include/cef_v8.h"
|
||||||
|
#include "include/wrapper/cef_closure_task.h"
|
||||||
|
#include "tests/ceftests/routing_test_handler.h"
|
||||||
|
#include "tests/ceftests/test_util.h"
|
||||||
|
#include "tests/gtest/include/gtest/gtest.h"
|
||||||
|
#include "tests/shared/renderer/client_app_renderer.h"
|
||||||
|
|
||||||
|
using client::ClientAppRenderer;
|
||||||
|
|
||||||
|
extern const char kJSQueryFunc[];
|
||||||
|
extern const char kJSQueryCancelFunc[];
|
||||||
|
|
||||||
|
#define S1(N) #N
|
||||||
|
#define S2(N) S1(N)
|
||||||
|
#define LINESTR S2(__LINE__)
|
||||||
|
|
||||||
|
// Handle the renderer side of the routing implementation.
|
||||||
|
class MRRenderDelegate : public ClientAppRenderer::Delegate {
|
||||||
|
public:
|
||||||
|
class V8HandlerImpl : public CefV8Handler {
|
||||||
|
public:
|
||||||
|
explicit V8HandlerImpl(CefRefPtr<MRRenderDelegate> delegate)
|
||||||
|
: delegate_(delegate) {}
|
||||||
|
|
||||||
|
bool Execute(const CefString& name,
|
||||||
|
CefRefPtr<CefV8Value> object,
|
||||||
|
const CefV8ValueList& arguments,
|
||||||
|
CefRefPtr<CefV8Value>& retval,
|
||||||
|
CefString& exception) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
CefRefPtr<MRRenderDelegate> delegate_;
|
||||||
|
|
||||||
|
IMPLEMENT_REFCOUNTING(V8HandlerImpl);
|
||||||
|
};
|
||||||
|
|
||||||
|
void OnWebKitInitialized(CefRefPtr<ClientAppRenderer> app) override;
|
||||||
|
|
||||||
|
void OnContextCreated(CefRefPtr<ClientAppRenderer> app,
|
||||||
|
CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
CefRefPtr<CefV8Context> context) override;
|
||||||
|
|
||||||
|
void OnContextReleased(CefRefPtr<ClientAppRenderer> app,
|
||||||
|
CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
CefRefPtr<CefV8Context> context) override;
|
||||||
|
|
||||||
|
bool OnProcessMessageReceived(CefRefPtr<ClientAppRenderer> app,
|
||||||
|
CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
CefProcessId source_process,
|
||||||
|
CefRefPtr<CefProcessMessage> message) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
CefRefPtr<CefMessageRouterRendererSide> message_router_;
|
||||||
|
|
||||||
|
IMPLEMENT_REFCOUNTING(MRRenderDelegate);
|
||||||
|
};
|
||||||
|
|
||||||
|
class MRTestHandler : public TestHandler {
|
||||||
|
public:
|
||||||
|
void RunTest() override;
|
||||||
|
void OnAfterCreated(CefRefPtr<CefBrowser> browser) override;
|
||||||
|
void OnBeforeClose(CefRefPtr<CefBrowser> browser) override;
|
||||||
|
void OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
|
||||||
|
TerminationStatus status) override;
|
||||||
|
|
||||||
|
// Only call this method if the navigation isn't canceled.
|
||||||
|
bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
CefRefPtr<CefRequest> request,
|
||||||
|
bool user_gesture,
|
||||||
|
bool is_redirect) override;
|
||||||
|
// Returns true if the router handled the navigation.
|
||||||
|
bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
CefProcessId source_process,
|
||||||
|
CefRefPtr<CefProcessMessage> message) override;
|
||||||
|
|
||||||
|
CefRefPtr<CefMessageRouterBrowserSide> GetRouter() const;
|
||||||
|
void SetMessageSizeThreshold(size_t message_size_treshold);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void RunMRTest() = 0;
|
||||||
|
|
||||||
|
virtual void AddHandlers(
|
||||||
|
CefRefPtr<CefMessageRouterBrowserSide> message_router) = 0;
|
||||||
|
|
||||||
|
virtual void OnNotify(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
const std::string& message) = 0;
|
||||||
|
|
||||||
|
bool AssertQueryCount(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefMessageRouterBrowserSide::Handler* handler,
|
||||||
|
int expected_count);
|
||||||
|
void AssertMainBrowser(CefRefPtr<CefBrowser> browser);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CefRefPtr<CefMessageRouterBrowserSide> message_router_;
|
||||||
|
size_t message_size_threshold_ = 0;
|
||||||
|
|
||||||
|
IMPLEMENT_REFCOUNTING(MRTestHandler);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Implementation of MRTestHandler that loads a single page.
|
||||||
|
class SingleLoadTestHandler : public MRTestHandler,
|
||||||
|
public CefMessageRouterBrowserSide::Handler {
|
||||||
|
public:
|
||||||
|
SingleLoadTestHandler();
|
||||||
|
const std::string& GetMainURL() { return main_url_; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void RunMRTest() override;
|
||||||
|
void AddHandlers(
|
||||||
|
CefRefPtr<CefMessageRouterBrowserSide> message_router) override;
|
||||||
|
virtual void AddOtherResources() {}
|
||||||
|
virtual std::string GetMainHTML() = 0;
|
||||||
|
void AssertMainFrame(CefRefPtr<CefFrame> frame);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::string main_url_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CEF_TESTS_CEFTESTS_MESSAGE_ROUTER_UNITTEST_UTILS_H_
|
172
tests/ceftests/send_shared_process_message_unittest.cc
Normal file
172
tests/ceftests/send_shared_process_message_unittest.cc
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
// Copyright (c) 2022 The Chromium Embedded Framework Authors. All rights
|
||||||
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "include/base/cef_callback.h"
|
||||||
|
#include "include/cef_shared_process_message_builder.h"
|
||||||
|
#include "include/cef_task.h"
|
||||||
|
#include "include/wrapper/cef_closure_task.h"
|
||||||
|
#include "tests/ceftests/test_handler.h"
|
||||||
|
#include "tests/gtest/include/gtest/gtest.h"
|
||||||
|
#include "tests/shared/renderer/client_app_renderer.h"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
using client::ClientAppRenderer;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct TestData {
|
||||||
|
bool flag = true;
|
||||||
|
int value = 1;
|
||||||
|
double d_value = 77.77;
|
||||||
|
std::array<size_t, 50> buffer{};
|
||||||
|
};
|
||||||
|
|
||||||
|
const char kSharedMessageUrl[] = "http://tests/SendSharedProcessMessageTest";
|
||||||
|
const char kSharedMessageName[] = "SendSharedProcessMessageTest";
|
||||||
|
|
||||||
|
CefRefPtr<CefProcessMessage> CreateTestMessage(const TestData& data) {
|
||||||
|
auto builder = CefSharedProcessMessageBuilder::Create(kSharedMessageName, sizeof(data));
|
||||||
|
std::memcpy(builder->Memory(), reinterpret_cast<const void*>(&data), sizeof(data));
|
||||||
|
return builder->Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Renderer side.
|
||||||
|
class SharedMessageRendererTest final : public ClientAppRenderer::Delegate {
|
||||||
|
public:
|
||||||
|
bool OnProcessMessageReceived(CefRefPtr<ClientAppRenderer> app,
|
||||||
|
CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
CefProcessId source_process,
|
||||||
|
CefRefPtr<CefProcessMessage> message) override {
|
||||||
|
if (message->GetName() == kSharedMessageName) {
|
||||||
|
EXPECT_TRUE(browser.get());
|
||||||
|
EXPECT_TRUE(frame.get());
|
||||||
|
EXPECT_EQ(PID_BROWSER, source_process);
|
||||||
|
EXPECT_TRUE(message.get());
|
||||||
|
EXPECT_TRUE(message->IsValid());
|
||||||
|
EXPECT_TRUE(message->IsReadOnly());
|
||||||
|
EXPECT_EQ(message->GetArgumentList(), nullptr);
|
||||||
|
|
||||||
|
const std::string& url = frame->GetURL();
|
||||||
|
if (url == kSharedMessageUrl) {
|
||||||
|
// Echo the message back to the sender natively.
|
||||||
|
frame->SendProcessMessage(PID_BROWSER, message);
|
||||||
|
EXPECT_FALSE(message->IsValid());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_REFCOUNTING(SharedMessageRendererTest);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Browser side.
|
||||||
|
class SharedMessageTestHandler final : public TestHandler {
|
||||||
|
public:
|
||||||
|
explicit SharedMessageTestHandler(cef_thread_id_t send_thread)
|
||||||
|
: send_thread_(send_thread) {}
|
||||||
|
|
||||||
|
void RunTest() override {
|
||||||
|
AddResource(kSharedMessageUrl, "<html><body>TEST</body></html>",
|
||||||
|
"text/html");
|
||||||
|
CreateBrowser(kSharedMessageUrl);
|
||||||
|
|
||||||
|
// Time out the test after a reasonable period of time.
|
||||||
|
SetTestTimeout();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
int httpStatusCode) override {
|
||||||
|
EXPECT_TRUE(CefCurrentlyOn(TID_UI));
|
||||||
|
|
||||||
|
// Send the message to the renderer process.
|
||||||
|
if (!CefCurrentlyOn(send_thread_)) {
|
||||||
|
CefPostTask(send_thread_,
|
||||||
|
base::BindOnce(&SharedMessageTestHandler::SendProcessMessage,
|
||||||
|
this, browser, frame));
|
||||||
|
} else {
|
||||||
|
SendProcessMessage(browser, frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
CefProcessId source_process,
|
||||||
|
CefRefPtr<CefProcessMessage> message) override {
|
||||||
|
EXPECT_TRUE(CefCurrentlyOn(TID_UI));
|
||||||
|
EXPECT_TRUE(browser.get());
|
||||||
|
EXPECT_TRUE(frame.get());
|
||||||
|
EXPECT_EQ(PID_RENDERER, source_process);
|
||||||
|
EXPECT_TRUE(message.get());
|
||||||
|
EXPECT_TRUE(message->IsValid());
|
||||||
|
EXPECT_TRUE(message->IsReadOnly());
|
||||||
|
EXPECT_EQ(message->GetArgumentList(), nullptr);
|
||||||
|
|
||||||
|
// Verify that the recieved message is the same as the sent message.
|
||||||
|
auto region = message->GetSharedMemoryRegion();
|
||||||
|
const TestData* received = static_cast<const TestData*>(region->Memory());
|
||||||
|
EXPECT_EQ(data_.flag, received->flag);
|
||||||
|
EXPECT_EQ(data_.value, received->value);
|
||||||
|
EXPECT_EQ(data_.d_value, received->d_value);
|
||||||
|
|
||||||
|
got_message_.yes();
|
||||||
|
|
||||||
|
// Test is complete.
|
||||||
|
DestroyTest();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void DestroyTest() override {
|
||||||
|
EXPECT_TRUE(got_message_);
|
||||||
|
TestHandler::DestroyTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SendProcessMessage(const CefRefPtr<CefBrowser>& browser,
|
||||||
|
const CefRefPtr<CefFrame>& frame) {
|
||||||
|
EXPECT_TRUE(CefCurrentlyOn(send_thread_));
|
||||||
|
|
||||||
|
auto message = CreateTestMessage(data_);
|
||||||
|
frame->SendProcessMessage(PID_RENDERER, message);
|
||||||
|
|
||||||
|
// The message is invalidated immediately
|
||||||
|
EXPECT_FALSE(message->IsValid());
|
||||||
|
}
|
||||||
|
|
||||||
|
cef_thread_id_t send_thread_;
|
||||||
|
TrackCallback got_message_;
|
||||||
|
const TestData data_;
|
||||||
|
|
||||||
|
IMPLEMENT_REFCOUNTING(SharedMessageTestHandler);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST(SendSharedProcessMessageTest, CanSendAndReceiveFromUiThread) {
|
||||||
|
CefRefPtr<SharedMessageTestHandler> handler =
|
||||||
|
new SharedMessageTestHandler(TID_UI);
|
||||||
|
handler->ExecuteTest();
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SendSharedProcessMessageTest, CanSendAndReceiveFromIoThread) {
|
||||||
|
CefRefPtr<SharedMessageTestHandler> handler =
|
||||||
|
new SharedMessageTestHandler(TID_IO);
|
||||||
|
handler->ExecuteTest();
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Entry point for creating shared process message renderer test objects.
|
||||||
|
// Called from client_app_delegates.cc.
|
||||||
|
void CreateSharedProcessMessageTests(
|
||||||
|
ClientAppRenderer::DelegateSet& delegates) {
|
||||||
|
delegates.insert(new SharedMessageRendererTest());
|
||||||
|
}
|
94
tests/ceftests/shared_process_message_unittest.cc
Normal file
94
tests/ceftests/shared_process_message_unittest.cc
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
// Copyright (c) 2022 The Chromium Embedded Framework Authors. All rights
|
||||||
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "include/cef_shared_process_message_builder.h"
|
||||||
|
|
||||||
|
#include "testing/gtest/include/gtest/gtest.h"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr bool kTestFlag = true;
|
||||||
|
constexpr int kTestValue = 42;
|
||||||
|
constexpr double kTestDoubleValue = 123.456;
|
||||||
|
|
||||||
|
struct TestData {
|
||||||
|
bool flag = kTestFlag;
|
||||||
|
int value = kTestValue;
|
||||||
|
double doubleValue = kTestDoubleValue;
|
||||||
|
std::array<size_t, 50> buffer{};
|
||||||
|
};
|
||||||
|
|
||||||
|
const char kSharedMessageName[] = "SharedProcessMessageTest";
|
||||||
|
|
||||||
|
CefRefPtr<CefSharedProcessMessageBuilder> CreateTestBuilder() {
|
||||||
|
auto builder = CefSharedProcessMessageBuilder::Create(kSharedMessageName,
|
||||||
|
sizeof(TestData));
|
||||||
|
EXPECT_NE(builder, nullptr);
|
||||||
|
EXPECT_TRUE(builder->IsValid());
|
||||||
|
|
||||||
|
auto data = static_cast<TestData*>(builder->Memory());
|
||||||
|
EXPECT_NE(data, nullptr);
|
||||||
|
|
||||||
|
data->value = kTestValue;
|
||||||
|
data->doubleValue = kTestDoubleValue;
|
||||||
|
data->flag = kTestFlag;
|
||||||
|
for (size_t i = 0; i < data->buffer.size(); ++i) {
|
||||||
|
data->buffer[i] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST(SharedProcessMessageTest, CanBuildSharedMessageUsingBuilder) {
|
||||||
|
auto builder = CreateTestBuilder();
|
||||||
|
|
||||||
|
auto message = builder->Build();
|
||||||
|
EXPECT_FALSE(builder->IsValid());
|
||||||
|
EXPECT_NE(message, nullptr);
|
||||||
|
EXPECT_TRUE(message->IsValid());
|
||||||
|
EXPECT_TRUE(message->IsReadOnly());
|
||||||
|
|
||||||
|
auto region = message->GetSharedMemoryRegion();
|
||||||
|
EXPECT_TRUE(region->IsValid());
|
||||||
|
auto read_data = static_cast<const TestData*>(region->Memory());
|
||||||
|
|
||||||
|
EXPECT_EQ(read_data->flag, kTestFlag);
|
||||||
|
EXPECT_EQ(read_data->value, kTestValue);
|
||||||
|
EXPECT_EQ(read_data->doubleValue, kTestDoubleValue);
|
||||||
|
for (size_t i = 0; i < read_data->buffer.size(); ++i) {
|
||||||
|
EXPECT_EQ(read_data->buffer[i], i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SharedProcessMessageTest, CopyingIsNotSupportedBySharedMessage) {
|
||||||
|
auto builder = CefSharedProcessMessageBuilder::Create(kSharedMessageName,
|
||||||
|
sizeof(TestData));
|
||||||
|
CefRefPtr<CefProcessMessage> message = builder->Build();
|
||||||
|
CefRefPtr<CefProcessMessage> message_copy = message->Copy();
|
||||||
|
EXPECT_EQ(message_copy, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SharedProcessMessageTest,
|
||||||
|
RegionRemainsValidAfterSharedMessageDestruction) {
|
||||||
|
CefRefPtr<CefSharedMemoryRegion> region;
|
||||||
|
{
|
||||||
|
auto builder = CreateTestBuilder();
|
||||||
|
auto message = builder->Build();
|
||||||
|
region = message->GetSharedMemoryRegion();
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_TRUE(region->IsValid());
|
||||||
|
auto read_data = static_cast<const TestData*>(region->Memory());
|
||||||
|
|
||||||
|
EXPECT_EQ(read_data->flag, kTestFlag);
|
||||||
|
EXPECT_EQ(read_data->value, kTestValue);
|
||||||
|
EXPECT_EQ(read_data->doubleValue, kTestDoubleValue);
|
||||||
|
for (size_t i = 0; i < read_data->buffer.size(); ++i) {
|
||||||
|
EXPECT_EQ(read_data->buffer[i], i);
|
||||||
|
}
|
||||||
|
}
|
44
tests/shared/common/binary_value_utils.cc
Normal file
44
tests/shared/common/binary_value_utils.cc
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// Copyright (c) 2022 The Chromium Embedded Framework Authors. All rights
|
||||||
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "tests/shared/common/binary_value_utils.h"
|
||||||
|
|
||||||
|
namespace bv_utils {
|
||||||
|
|
||||||
|
const char kTestSendProcessMessage[] = "testSendProcessMessage";
|
||||||
|
const char kTestSendSMRProcessMessage[] = "testSendSMRProcessMessage";
|
||||||
|
|
||||||
|
TimePoint Now() {
|
||||||
|
return std::chrono::high_resolution_clock::now();
|
||||||
|
}
|
||||||
|
|
||||||
|
CefRefPtr<CefBinaryValue> CreateCefBinaryValue(
|
||||||
|
const std::vector<uint8_t>& data) {
|
||||||
|
return CefBinaryValue::Create(data.data(), data.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
RendererMessage GetRendererMsgFromBinary(
|
||||||
|
const CefRefPtr<CefBinaryValue>& value) {
|
||||||
|
DCHECK_GE(value->GetSize(), sizeof(RendererMessage));
|
||||||
|
std::vector<uint8_t> data(value->GetSize());
|
||||||
|
value->GetData(data.data(), data.size(), 0);
|
||||||
|
return *reinterpret_cast<const RendererMessage*>(data.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
BrowserMessage GetBrowserMsgFromBinary(const CefRefPtr<CefBinaryValue>& value) {
|
||||||
|
DCHECK_GE(value->GetSize(), sizeof(BrowserMessage));
|
||||||
|
std::vector<uint8_t> data(value->GetSize());
|
||||||
|
value->GetData(data.data(), data.size(), 0);
|
||||||
|
return *reinterpret_cast<const BrowserMessage*>(data.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ToMilliString(const Duration& duration) {
|
||||||
|
const auto ms =
|
||||||
|
std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(
|
||||||
|
duration);
|
||||||
|
|
||||||
|
return std::to_string(ms.count());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace bv_utils
|
47
tests/shared/common/binary_value_utils.h
Normal file
47
tests/shared/common/binary_value_utils.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// Copyright (c) 2022 The Chromium Embedded Framework Authors. All rights
|
||||||
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef CEF_TESTS_SHARED_COMMON_BINARY_VALUE_UTILS
|
||||||
|
#define CEF_TESTS_SHARED_COMMON_BINARY_VALUE_UTILS
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
#include "include/cef_values.h"
|
||||||
|
|
||||||
|
namespace bv_utils {
|
||||||
|
|
||||||
|
extern const char kTestSendProcessMessage[];
|
||||||
|
extern const char kTestSendSMRProcessMessage[];
|
||||||
|
|
||||||
|
using TimePoint = std::chrono::high_resolution_clock::time_point;
|
||||||
|
using Duration = std::chrono::high_resolution_clock::duration;
|
||||||
|
|
||||||
|
struct RendererMessage {
|
||||||
|
int test_id;
|
||||||
|
TimePoint start_time;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BrowserMessage {
|
||||||
|
int test_id;
|
||||||
|
Duration duration;
|
||||||
|
TimePoint start_time;
|
||||||
|
};
|
||||||
|
|
||||||
|
TimePoint Now();
|
||||||
|
|
||||||
|
CefRefPtr<CefBinaryValue> CreateCefBinaryValue(
|
||||||
|
const std::vector<uint8_t>& data);
|
||||||
|
|
||||||
|
RendererMessage GetRendererMsgFromBinary(
|
||||||
|
const CefRefPtr<CefBinaryValue>& value);
|
||||||
|
|
||||||
|
BrowserMessage GetBrowserMsgFromBinary(const CefRefPtr<CefBinaryValue>& value);
|
||||||
|
|
||||||
|
std::string ToMilliString(const Duration& duration);
|
||||||
|
|
||||||
|
} // namespace bv_utils
|
||||||
|
|
||||||
|
#endif // CEF_TESTS_SHARED_COMMON_BINARY_VALUE_UTILS
|
Reference in New Issue
Block a user