- Expose tracing functionality via new cef_trace.h and cef_trace_event.h headers (issue #711).

- Add about:tracing UI support (issue #711).
- Avoid unnecessary string type conversions for values and process messages.
- Add support for a 'note' attribute in patch.cfg.

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@865 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2012-10-17 22:45:49 +00:00
parent eda69594ef
commit e1f2be1785
41 changed files with 2680 additions and 72 deletions

View File

@ -259,6 +259,7 @@
'tests/unittests/test_suite.h',
'tests/unittests/test_util.cc',
'tests/unittests/test_util.h',
'tests/unittests/tracing_unittest.cc',
'tests/unittests/url_unittest.cc',
'tests/unittests/urlrequest_unittest.cc',
'tests/unittests/v8_unittest.cc',
@ -841,6 +842,9 @@
'libcef/browser/sqlite_diagnostics_stub.cc',
'libcef/browser/stream_impl.cc',
'libcef/browser/stream_impl.h',
'libcef/browser/trace_impl.cc',
'libcef/browser/trace_subscriber.cc',
'libcef/browser/trace_subscriber.h',
'libcef/browser/thread_util.h',
'libcef/browser/url_network_delegate.cc',
'libcef/browser/url_network_delegate.h',
@ -899,6 +903,8 @@
'libcef/common/values_impl.h',
'libcef/renderer/browser_impl.cc',
'libcef/renderer/browser_impl.h',
'libcef/renderer/chrome_bindings.cc',
'libcef/renderer/chrome_bindings.h',
'libcef/renderer/content_renderer_client.cc',
'libcef/renderer/content_renderer_client.h',
'libcef/renderer/dom_document_impl.cc',
@ -1190,6 +1196,7 @@
'tests/unittests/test_suite.h',
'tests/unittests/test_util.cc',
'tests/unittests/test_util.h',
'tests/unittests/tracing_unittest.cc',
'tests/unittests/v8_unittest.cc',
],
# TODO(mark): Come up with a fancier way to do this. It should only

View File

@ -48,6 +48,7 @@
'include/cef_stream.h',
'include/cef_string_visitor.h',
'include/cef_task.h',
'include/cef_trace.h',
'include/cef_url.h',
'include/cef_urlrequest.h',
'include/cef_v8.h',
@ -93,6 +94,7 @@
'include/capi/cef_stream_capi.h',
'include/capi/cef_string_visitor_capi.h',
'include/capi/cef_task_capi.h',
'include/capi/cef_trace_capi.h',
'include/capi/cef_url_capi.h',
'include/capi/cef_urlrequest_capi.h',
'include/capi/cef_v8_capi.h',
@ -214,6 +216,8 @@
'libcef_dll/ctocpp/string_visitor_ctocpp.h',
'libcef_dll/ctocpp/task_ctocpp.cc',
'libcef_dll/ctocpp/task_ctocpp.h',
'libcef_dll/ctocpp/trace_client_ctocpp.cc',
'libcef_dll/ctocpp/trace_client_ctocpp.h',
'libcef_dll/cpptoc/urlrequest_cpptoc.cc',
'libcef_dll/cpptoc/urlrequest_cpptoc.h',
'libcef_dll/ctocpp/urlrequest_client_ctocpp.cc',
@ -358,6 +362,8 @@
'libcef_dll/cpptoc/string_visitor_cpptoc.h',
'libcef_dll/cpptoc/task_cpptoc.cc',
'libcef_dll/cpptoc/task_cpptoc.h',
'libcef_dll/cpptoc/trace_client_cpptoc.cc',
'libcef_dll/cpptoc/trace_client_cpptoc.h',
'libcef_dll/ctocpp/urlrequest_ctocpp.cc',
'libcef_dll/ctocpp/urlrequest_ctocpp.h',
'libcef_dll/cpptoc/urlrequest_client_cpptoc.cc',

View File

@ -13,6 +13,7 @@
'include/cef_pack_resources.h',
'include/cef_pack_strings.h',
'include/cef_runnable.h',
'include/cef_trace_event.h',
'include/cef_version.h',
'include/internal/cef_build.h',
'include/internal/cef_export.h',

View File

@ -0,0 +1,129 @@
// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool and should not edited
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
#ifndef CEF_INCLUDE_CAPI_CEF_TRACE_CAPI_H_
#define CEF_INCLUDE_CAPI_CEF_TRACE_CAPI_H_
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "include/capi/cef_base_capi.h"
///
// Start tracing events on all processes. Tracing begins immediately locally,
// and asynchronously on child processes as soon as they receive the
// BeginTracing request.
//
// If CefBeginTracing was called previously, or if a CefEndTracingAsync call is
// pending, CefBeginTracing will fail and return false (0).
//
// |categories| is a comma-delimited list of category wildcards. A category can
// have an optional '-' prefix to make it an excluded category. Having both
// included and excluded categories in the same list is not supported.
//
// Example: "test_MyTest*" Example: "test_MyTest*,test_OtherStuff" Example:
// "-excluded_category1,-excluded_category2"
//
// This function must be called on the browser process UI thread.
///
CEF_EXPORT int cef_begin_tracing(struct _cef_trace_client_t* client,
const cef_string_t* categories);
///
// Get the maximum trace buffer percent full state across all processes.
//
// cef_trace_client_t::OnTraceBufferPercentFullReply will be called
// asynchronously after the value is determibed. When any child process reaches
// 100% full tracing will end automatically and
// cef_trace_client_t::OnEndTracingComplete will be called. This function fails
// and returns false (0) if trace is ending or disabled, no cef_trace_client_t
// was passed to CefBeginTracing, or if a previous call to
// CefGetTraceBufferPercentFullAsync is pending.
//
// This function must be called on the browser process UI thread.
///
CEF_EXPORT int cef_get_trace_buffer_percent_full_async();
///
// Stop tracing events on all processes.
//
// This function will fail and return false (0) if a previous call to
// CefEndTracingAsync is already pending or if CefBeginTracing was not called.
//
// This function must be called on the browser process UI thread.
///
CEF_EXPORT int cef_end_tracing_async();
///
// Implement this structure to receive trace notifications. The functions of
// this structure will be called on the browser process UI thread.
///
typedef struct _cef_trace_client_t {
///
// Base structure.
///
cef_base_t base;
///
// Called 0 or more times between CefBeginTracing and OnEndTracingComplete
// with a UTF8 JSON |fragment| of the specified |fragment_size|. Do not keep a
// reference to |fragment|.
///
void (CEF_CALLBACK *on_trace_data_collected)(struct _cef_trace_client_t* self,
const char* fragment, size_t fragment_size);
///
// Called in response to CefGetTraceBufferPercentFullAsync.
///
void (CEF_CALLBACK *on_trace_buffer_percent_full_reply)(
struct _cef_trace_client_t* self, float percent_full);
///
// Called after all processes have sent their trace data.
///
void (CEF_CALLBACK *on_end_tracing_complete)(
struct _cef_trace_client_t* self);
} cef_trace_client_t;
#ifdef __cplusplus
}
#endif
#endif // CEF_INCLUDE_CAPI_CEF_TRACE_CAPI_H_

124
include/cef_trace.h Normal file
View File

@ -0,0 +1,124 @@
// Copyright (c) 2012 Marshall A. Greenblatt. Portons copyright (c) 2012
// Google Inc. 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.
//
// See cef_trace_event.h for trace macros and additonal documentation.
#ifndef CEF_INCLUDE_CEF_TRACE_H_
#define CEF_INCLUDE_CEF_TRACE_H_
#pragma once
#include "include/cef_base.h"
///
// Implement this interface to receive trace notifications. The methods of this
// class will be called on the browser process UI thread.
///
/*--cef(source=client)--*/
class CefTraceClient : public virtual CefBase {
public:
///
// Called 0 or more times between CefBeginTracing and OnEndTracingComplete
// with a UTF8 JSON |fragment| of the specified |fragment_size|. Do not keep
// a reference to |fragment|.
///
/*--cef()--*/
virtual void OnTraceDataCollected(const char* fragment,
size_t fragment_size) {}
///
// Called in response to CefGetTraceBufferPercentFullAsync.
///
/*--cef()--*/
virtual void OnTraceBufferPercentFullReply(float percent_full) {}
///
// Called after all processes have sent their trace data.
///
/*--cef()--*/
virtual void OnEndTracingComplete() {}
};
///
// Start tracing events on all processes. Tracing begins immediately locally,
// and asynchronously on child processes as soon as they receive the
// BeginTracing request.
//
// If CefBeginTracing was called previously, or if a CefEndTracingAsync call is
// pending, CefBeginTracing will fail and return false.
//
// |categories| is a comma-delimited list of category wildcards. A category can
// have an optional '-' prefix to make it an excluded category. Having both
// included and excluded categories in the same list is not supported.
//
// Example: "test_MyTest*"
// Example: "test_MyTest*,test_OtherStuff"
// Example: "-excluded_category1,-excluded_category2"
//
// This function must be called on the browser process UI thread.
///
/*--cef(optional_param=client,optional_param=categories)--*/
bool CefBeginTracing(CefRefPtr<CefTraceClient> client,
const CefString& categories);
///
// Get the maximum trace buffer percent full state across all processes.
//
// CefTraceClient::OnTraceBufferPercentFullReply will be called asynchronously
// after the value is determibed. When any child process reaches 100% full
// tracing will end automatically and CefTraceClient::OnEndTracingComplete
// will be called. This function fails and returns false if trace is ending or
// disabled, no CefTraceClient was passed to CefBeginTracing, or if a previous
// call to CefGetTraceBufferPercentFullAsync is pending.
//
// This function must be called on the browser process UI thread.
///
/*--cef()--*/
bool CefGetTraceBufferPercentFullAsync();
///
// Stop tracing events on all processes.
//
// This function will fail and return false if a previous call to
// CefEndTracingAsync is already pending or if CefBeginTracing was not called.
//
// This function must be called on the browser process UI thread.
///
/*--cef()--*/
bool CefEndTracingAsync();
#endif // CEF_INCLUDE_CEF_TRACE_H_

465
include/cef_trace_event.h Normal file
View File

@ -0,0 +1,465 @@
// Copyright (c) 2012 Marshall A. Greenblatt. Portions copyright (c) 2012
// Google Inc. 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.
///
// Trace events are for tracking application performance and resource usage.
// Macros are provided to track:
// Begin and end of function calls
// Counters
//
// Events are issued against categories. Whereas LOG's categories are statically
// defined, TRACE categories are created implicitly with a string. For example:
// CEF_TRACE_EVENT_INSTANT0("MY_SUBSYSTEM", "SomeImportantEvent")
//
// Events can be INSTANT, or can be pairs of BEGIN and END in the same scope:
// CEF_TRACE_EVENT_BEGIN0("MY_SUBSYSTEM", "SomethingCostly")
// doSomethingCostly()
// CEF_TRACE_EVENT_END0("MY_SUBSYSTEM", "SomethingCostly")
// Note: Our tools can't always determine the correct BEGIN/END pairs unless
// these are used in the same scope. Use ASYNC_BEGIN/ASYNC_END macros if you
// need them to be in separate scopes.
//
// A common use case is to trace entire function scopes. This issues a trace
// BEGIN and END automatically:
// void doSomethingCostly() {
// CEF_TRACE_EVENT0("MY_SUBSYSTEM", "doSomethingCostly");
// ...
// }
//
// Additional parameters can be associated with an event:
// void doSomethingCostly2(int howMuch) {
// CEF_TRACE_EVENT1("MY_SUBSYSTEM", "doSomethingCostly",
// "howMuch", howMuch);
// ...
// }
//
// The trace system will automatically add to this information the current
// process id, thread id, and a timestamp in microseconds.
//
// To trace an asynchronous procedure such as an IPC send/receive, use
// ASYNC_BEGIN and ASYNC_END:
// [single threaded sender code]
// static int send_count = 0;
// ++send_count;
// CEF_TRACE_EVENT_ASYNC_BEGIN0("ipc", "message", send_count);
// Send(new MyMessage(send_count));
// [receive code]
// void OnMyMessage(send_count) {
// CEF_TRACE_EVENT_ASYNC_END0("ipc", "message", send_count);
// }
// The third parameter is a unique ID to match ASYNC_BEGIN/ASYNC_END pairs.
// ASYNC_BEGIN and ASYNC_END can occur on any thread of any traced process.
// Pointers can be used for the ID parameter, and they will be mangled
// internally so that the same pointer on two different processes will not
// match. For example:
// class MyTracedClass {
// public:
// MyTracedClass() {
// CEF_TRACE_EVENT_ASYNC_BEGIN0("category", "MyTracedClass", this);
// }
// ~MyTracedClass() {
// CEF_TRACE_EVENT_ASYNC_END0("category", "MyTracedClass", this);
// }
// }
//
// The trace event also supports counters, which is a way to track a quantity
// as it varies over time. Counters are created with the following macro:
// CEF_TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter", g_myCounterValue);
//
// Counters are process-specific. The macro itself can be issued from any
// thread, however.
//
// Sometimes, you want to track two counters at once. You can do this with two
// counter macros:
// CEF_TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter0", g_myCounterValue[0]);
// CEF_TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter1", g_myCounterValue[1]);
// Or you can do it with a combined macro:
// CEF_TRACE_COUNTER2("MY_SUBSYSTEM", "myCounter",
// "bytesPinned", g_myCounterValue[0],
// "bytesAllocated", g_myCounterValue[1]);
// This indicates to the tracing UI that these counters should be displayed
// in a single graph, as a summed area chart.
//
// Since counters are in a global namespace, you may want to disembiguate with a
// unique ID, by using the CEF_TRACE_COUNTER_ID* variations.
//
// By default, trace collection is compiled in, but turned off at runtime.
// Collecting trace data is the responsibility of the embedding application. In
// CEF's case, calling BeginTracing will turn on tracing on all active
// processes.
//
//
// Memory scoping note:
// Tracing copies the pointers, not the string content, of the strings passed
// in for category, name, and arg_names. Thus, the following code will cause
// problems:
// char* str = strdup("impprtantName");
// CEF_TRACE_EVENT_INSTANT0("SUBSYSTEM", str); // BAD!
// free(str); // Trace system now has dangling pointer
//
// To avoid this issue with the |name| and |arg_name| parameters, use the
// CEF_TRACE_EVENT_COPY_XXX overloads of the macros at additional runtime
// overhead.
// Notes: The category must always be in a long-lived char* (i.e. static const).
// The |arg_values|, when used, are always deep copied with the _COPY
// macros.
//
//
// Thread Safety:
// All macros are thread safe and can be used from any process.
///
#ifndef CEF_INCLUDE_CEF_TRACE_EVENT_H_
#define CEF_INCLUDE_CEF_TRACE_EVENT_H_
#pragma once
#include "include/internal/cef_export.h"
#include "include/internal/cef_types.h"
#ifdef __cplusplus
extern "C" {
#endif
// Functions for tracing counters and functions; called from macros.
// - |category| string must have application lifetime (static or literal). They
// may not include "(quotes) chars.
// - |argX_name|, |argX_val|, |valueX_name|, |valeX_val| are optional parameters
// and represent pairs of name and values of arguments
// - |copy| is used to avoid memory scoping issues with the |name| and
// |arg_name| parameters by copying them
// - |id| is used to disambiguate counters with the same name, or match async
// trace events
CEF_EXPORT void cef_trace_event(const char* category,
const char* name,
const char* arg1_name,
uint64 arg1_val,
const char* arg2_name,
uint64 arg2_val);
CEF_EXPORT void cef_trace_event_instant(const char* category,
const char* name,
const char* arg1_name,
uint64 arg1_val,
const char* arg2_name,
uint64 arg2_val,
int copy);
CEF_EXPORT void cef_trace_event_begin(const char* category,
const char* name,
const char* arg1_name,
uint64 arg1_val,
const char* arg2_name,
uint64 arg2_val,
int copy);
CEF_EXPORT void cef_trace_event_end(const char* category,
const char* name,
const char* arg1_name,
uint64 arg1_val,
const char* arg2_name,
uint64 arg2_val,
int copy);
CEF_EXPORT void cef_trace_event_if_longer_than(long long threshold_us,
const char* category,
const char* name,
const char* arg1_name,
uint64 arg1_val,
const char* arg2_name,
uint64 arg2_val);
CEF_EXPORT void cef_trace_counter(const char* category,
const char* name,
const char* value1_name,
uint64 value1_val,
const char* value2_name,
uint64 value2_val,
int copy);
CEF_EXPORT void cef_trace_counter_id(const char* category,
const char* name,
uint64 id,
const char* value1_name,
uint64 value1_val,
const char* value2_name,
uint64 value2_val,
int copy);
CEF_EXPORT void cef_trace_event_async_begin(const char* category,
const char* name,
uint64 id,
const char* arg1_name,
uint64 arg1_val,
const char* arg2_name,
uint64 arg2_val,
int copy);
CEF_EXPORT void cef_trace_event_async_step(const char* category,
const char* name,
uint64 id,
uint64 step,
const char* arg1_name,
uint64 arg1_val,
int copy);
CEF_EXPORT void cef_trace_event_async_end(const char* category,
const char* name,
uint64 id,
const char* arg1_name,
uint64 arg1_val,
const char* arg2_name,
uint64 arg2_val,
int copy);
#ifdef __cplusplus
}
#endif
// Records a pair of begin and end events called "name" for the current
// scope, with 0, 1 or 2 associated arguments. If the category is not
// enabled, then this does nothing.
// - category and name strings must have application lifetime (statics or
// literals). They may not include " chars.
#define CEF_TRACE_EVENT0(category, name) \
cef_trace_event(category, name, NULL, 0, NULL, 0)
#define CEF_TRACE_EVENT1(category, name, arg1_name, arg1_val) \
cef_trace_event(category, name, arg1_name, arg1_val, NULL, 0)
#define CEF_TRACE_EVENT2(category, name, arg1_name, arg1_val, arg2_name, \
arg2_val) \
cef_trace_event(category, name, arg1_name, arg1_val, arg2_name, arg2_val)
// Records a single event called "name" immediately, with 0, 1 or 2
// associated arguments. If the category is not enabled, then this
// does nothing.
// - category and name strings must have application lifetime (statics or
// literals). They may not include " chars.
#define CEF_TRACE_EVENT_INSTANT0(category, name) \
cef_trace_event_instant(category, name, NULL, 0, NULL, 0, false)
#define CEF_TRACE_EVENT_INSTANT1(category, name, arg1_name, arg1_val) \
cef_trace_event_instant(category, name, arg1_name, arg1_val, NULL, 0, false)
#define CEF_TRACE_EVENT_INSTANT2(category, name, arg1_name, arg1_val, \
arg2_name, arg2_val) \
cef_trace_event_instant(category, name, arg1_name, arg1_val, arg2_name, \
arg2_val, false)
#define CEF_TRACE_EVENT_COPY_INSTANT0(category, name) \
cef_trace_event_instant(category, name, NULL, 0, NULL, 0, true)
#define CEF_TRACE_EVENT_COPY_INSTANT1(category, name, arg1_name, arg1_val) \
cef_trace_event_instant(category, name, arg1_name, arg1_val, NULL, 0, true)
#define CEF_TRACE_EVENT_COPY_INSTANT2(category, name, arg1_name, arg1_val, \
arg2_name, arg2_val) \
cef_trace_event_instant(category, name, arg1_name, arg1_val, arg2_name, \
arg2_val, true)
// Records a single BEGIN event called "name" immediately, with 0, 1 or 2
// associated arguments. If the category is not enabled, then this
// does nothing.
// - category and name strings must have application lifetime (statics or
// literals). They may not include " chars.
#define CEF_TRACE_EVENT_BEGIN0(category, name) \
cef_trace_event_begin(category, name, NULL, 0, NULL, 0, false)
#define CEF_TRACE_EVENT_BEGIN1(category, name, arg1_name, arg1_val) \
cef_trace_event_begin(category, name, arg1_name, arg1_val, NULL, 0, false)
#define CEF_TRACE_EVENT_BEGIN2(category, name, arg1_name, arg1_val, \
arg2_name, arg2_val) \
cef_trace_event_begin(category, name, arg1_name, arg1_val, arg2_name, \
arg2_val, false)
#define CEF_TRACE_EVENT_COPY_BEGIN0(category, name) \
cef_trace_event_begin(category, name, NULL, 0, NULL, 0, true)
#define CEF_TRACE_EVENT_COPY_BEGIN1(category, name, arg1_name, arg1_val) \
cef_trace_event_begin(category, name, arg1_name, arg1_val, NULL, 0, true)
#define CEF_TRACE_EVENT_COPY_BEGIN2(category, name, arg1_name, arg1_val, \
arg2_name, arg2_val) \
cef_trace_event_begin(category, name, arg1_name, arg1_val, arg2_name, \
arg2_val, true)
// Records a single END event for "name" immediately. If the category
// is not enabled, then this does nothing.
// - category and name strings must have application lifetime (statics or
// literals). They may not include " chars.
#define CEF_TRACE_EVENT_END0(category, name) \
cef_trace_event_end(category, name, NULL, 0, NULL, 0, false)
#define CEF_TRACE_EVENT_END1(category, name, arg1_name, arg1_val) \
cef_trace_event_end(category, name, arg1_name, arg1_val, NULL, 0, false)
#define CEF_TRACE_EVENT_END2(category, name, arg1_name, arg1_val, \
arg2_name, arg2_val) \
cef_trace_event_end(category, name, arg1_name, arg1_val, arg2_name, \
arg2_val, false)
#define CEF_TRACE_EVENT_COPY_END0(category, name) \
cef_trace_event_end(category, name, NULL, 0, NULL, 0, true)
#define CEF_TRACE_EVENT_COPY_END1(category, name, arg1_name, arg1_val) \
cef_trace_event_end(category, name, arg1_name, arg1_val, NULL, 0, true)
#define CEF_TRACE_EVENT_COPY_END2(category, name, arg1_name, arg1_val, \
arg2_name, arg2_val) \
cef_trace_event_end(category, name, arg1_name, arg1_val, arg2_name, \
arg2_val, true)
// Time threshold event:
// Only record the event if the duration is greater than the specified
// threshold_us (time in microseconds).
// Records a pair of begin and end events called "name" for the current
// scope, with 0, 1 or 2 associated arguments. If the category is not
// enabled, then this does nothing.
// - category and name strings must have application lifetime (statics or
// literals). They may not include " chars.
#define CEF_TRACE_EVENT_IF_LONGER_THAN0(threshold_us, category, name) \
cef_trace_event_if_longer_than(threshold_us, category, name, NULL, 0, NULL, 0)
#define CEF_TRACE_EVENT_IF_LONGER_THAN1(threshold_us, category, name, \
arg1_name, arg1_val) \
cef_trace_event_if_longer_than(threshold_us, category, name, arg1_name, \
arg1_val, NULL, 0)
#define CEF_TRACE_EVENT_IF_LONGER_THAN2(threshold_us, category, name, \
arg1_name, arg1_val, arg2_name, arg2_val) \
cef_trace_event_if_longer_than(threshold_us, category, name, arg1_name, \
arg1_val, arg2_name, arg2_val)
// Records the value of a counter called "name" immediately. Value
// must be representable as a 32 bit integer.
// - category and name strings must have application lifetime (statics or
// literals). They may not include " chars.
#define CEF_TRACE_COUNTER1(category, name, value) \
cef_trace_counter(category, name, NULL, value, NULL, 0, false)
#define CEF_TRACE_COPY_COUNTER1(category, name, value) \
cef_trace_counter(category, name, NULL, value, NULL, 0, true)
// Records the values of a multi-parted counter called "name" immediately.
// The UI will treat value1 and value2 as parts of a whole, displaying their
// values as a stacked-bar chart.
// - category and name strings must have application lifetime (statics or
// literals). They may not include " chars.
#define CEF_TRACE_COUNTER2(category, name, value1_name, value1_val, \
value2_name, value2_val) \
cef_trace_counter(category, name, value1_name, value1_val, value2_name, \
value2_val, false)
#define CEF_TRACE_COPY_COUNTER2(category, name, value1_name, value1_val, \
value2_name, value2_val) \
cef_trace_counter(category, name, value1_name, value1_val, value2_name, \
value2_val, true)
// Records the value of a counter called "name" immediately. Value
// must be representable as a 32 bit integer.
// - category and name strings must have application lifetime (statics or
// literals). They may not include " chars.
// - |id| is used to disambiguate counters with the same name. It must either
// be a pointer or an integer value up to 64 bits. If it's a pointer, the
// bits will be xored with a hash of the process ID so that the same pointer
// on two different processes will not collide.
#define CEF_TRACE_COUNTER_ID1(category, name, id, value) \
cef_trace_counter_id(category, name, id, NULL, value, NULL, 0, false)
#define CEF_TRACE_COPY_COUNTER_ID1(category, name, id, value) \
cef_trace_counter_id(category, name, id, NULL, value, NULL, 0, true)
// Records the values of a multi-parted counter called "name" immediately.
// The UI will treat value1 and value2 as parts of a whole, displaying their
// values as a stacked-bar chart.
// - category and name strings must have application lifetime (statics or
// literals). They may not include " chars.
// - |id| is used to disambiguate counters with the same name. It must either
// be a pointer or an integer value up to 64 bits. If it's a pointer, the
// bits will be xored with a hash of the process ID so that the same pointer
// on two different processes will not collide.
#define CEF_TRACE_COUNTER_ID2(category, name, id, value1_name, value1_val, \
value2_name, value2_val) \
cef_trace_counter_id(category, name, id, value1_name, value1_val, \
value2_name, value2_val, false)
#define CEF_TRACE_COPY_COUNTER_ID2(category, name, id, value1_name, \
value1_val, value2_name, value2_val) \
cef_trace_counter_id(category, name, id, value1_name, value1_val, \
value2_name, value2_val, true)
// Records a single ASYNC_BEGIN event called "name" immediately, with 0, 1 or 2
// associated arguments. If the category is not enabled, then this
// does nothing.
// - category and name strings must have application lifetime (statics or
// literals). They may not include " chars.
// - |id| is used to match the ASYNC_BEGIN event with the ASYNC_END event.
// ASYNC events are considered to match if their category, name and id values
// all match. |id| must either be a pointer or an integer value up to 64
// bits. If it's a pointer, the bits will be xored with a hash of the process
// ID sothat the same pointer on two different processes will not collide.
// An asynchronous operation can consist of multiple phases. The first phase is
// defined by the ASYNC_BEGIN calls. Additional phases can be defined using the
// ASYNC_STEP_BEGIN macros. When the operation completes, call ASYNC_END.
// An async operation can span threads and processes, but all events in that
// operation must use the same |name| and |id|. Each event can have its own
// args.
#define CEF_TRACE_EVENT_ASYNC_BEGIN0(category, name, id) \
cef_trace_event_async_begin(category, name, id, NULL, 0, NULL, 0, false)
#define CEF_TRACE_EVENT_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val) \
cef_trace_event_async_begin(category, name, id, arg1_name, arg1_val, NULL, \
0, false)
#define CEF_TRACE_EVENT_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val, \
arg2_name, arg2_val) \
cef_trace_event_async_begin(category, name, id, arg1_name, arg1_val, \
arg2_name, arg2_val, false)
#define CEF_TRACE_EVENT_COPY_ASYNC_BEGIN0(category, name, id) \
cef_trace_event_async_begin(category, name, id, NULL, 0, NULL, 0, true)
#define CEF_TRACE_EVENT_COPY_ASYNC_BEGIN1(category, name, id, arg1_name, \
arg1_val) \
cef_trace_event_async_begin(category, name, id, arg1_name, arg1_val, NULL, \
0, true)
#define CEF_TRACE_EVENT_COPY_ASYNC_BEGIN2(category, name, id, arg1_name, \
arg1_val, arg2_name, arg2_val) \
cef_trace_event_async_begin(category, name, id, arg1_name, arg1_val, \
arg2_name, arg2_val, true)
// Records a single ASYNC_STEP event for |step| immediately. If the category
// is not enabled, then this does nothing. The |name| and |id| must match the
// ASYNC_BEGIN event above. The |step| param identifies this step within the
// async event. This should be called at the beginning of the next phase of an
// asynchronous operation.
#define CEF_TRACE_EVENT_ASYNC_STEP0(category, name, id, step) \
cef_trace_event_async_step(category, name, id, step, NULL, 0, false)
#define CEF_TRACE_EVENT_ASYNC_STEP1(category, name, id, step, \
arg1_name, arg1_val) \
cef_trace_event_async_step(category, name, id, step, arg1_name, arg1_val, \
false)
#define CEF_TRACE_EVENT_COPY_ASYNC_STEP0(category, name, id, step) \
cef_trace_event_async_step(category, name, id, step, NULL, 0, true)
#define CEF_TRACE_EVENT_COPY_ASYNC_STEP1(category, name, id, step, \
arg1_name, arg1_val) \
cef_trace_event_async_step(category, name, id, step, arg1_name, arg1_val, \
true)
// Records a single ASYNC_END event for "name" immediately. If the category
// is not enabled, then this does nothing.
#define CEF_TRACE_EVENT_ASYNC_END0(category, name, id) \
cef_trace_event_async_end(category, name, id, NULL, 0, NULL, 0, false)
#define CEF_TRACE_EVENT_ASYNC_END1(category, name, id, arg1_name, arg1_val) \
cef_trace_event_async_end(category, name, id, arg1_name, arg1_val, NULL, 0, \
false)
#define CEF_TRACE_EVENT_ASYNC_END2(category, name, id, arg1_name, arg1_val, \
arg2_name, arg2_val) \
cef_trace_event_async_end(category, name, id, arg1_name, arg1_val, \
arg2_name, arg2_val, false)
#define CEF_TRACE_EVENT_COPY_ASYNC_END0(category, name, id) \
cef_trace_event_async_end(category, name, id, NULL, 0, NULL, 0, true)
#define CEF_TRACE_EVENT_COPY_ASYNC_END1(category, name, id, arg1_name, \
arg1_val) \
cef_trace_event_async_end(category, name, id, arg1_name, arg1_val, NULL, 0, \
true)
#define CEF_TRACE_EVENT_COPY_ASYNC_END2(category, name, id, arg1_name, \
arg1_val, arg2_name, arg2_val) \
cef_trace_event_async_end(category, name, id, arg1_name, arg1_val, \
arg2_name, arg2_val, true)
#endif // CEF_INCLUDE_CEF_TRACE_EVENT_H_

View File

@ -422,6 +422,18 @@ class CefStringBase {
traits::clear(string_);
}
///
// Swap this string's contents with the specified string.
///
void swap(CefStringBase& str) {
struct_type* tmp_string = string_;
bool tmp_owner = owner_;
string_ = str.string_;
owner_ = str.owner_;
str.string_ = tmp_string;
str.owner_ = tmp_owner;
}
// The following methods are unique to CEF string template types.

View File

@ -9,6 +9,7 @@
#include <utility>
#include "libcef/browser/browser_context.h"
#include "libcef/browser/chrome_scheme_handler.h"
#include "libcef/browser/context.h"
#include "libcef/browser/devtools_delegate.h"
#include "libcef/browser/navigate_params.h"
@ -651,21 +652,14 @@ void CefBrowserHostImpl::GetFrameNames(std::vector<CefString>& names) {
bool CefBrowserHostImpl::SendProcessMessage(
CefProcessId target_process,
CefRefPtr<CefProcessMessage> message) {
DCHECK_EQ(PID_RENDERER, target_process);
DCHECK(message.get());
Cef_Request_Params params;
CefProcessMessageImpl* impl =
static_cast<CefProcessMessageImpl*>(message.get());
if (impl->CopyTo(params)) {
DCHECK(!params.name.empty());
params.frame_id = -1;
params.user_initiated = true;
params.request_id = -1;
params.expect_response = false;
return Send(new CefMsg_Request(routing_id(), params));
return SendProcessMessage(target_process, params.name, &params.arguments,
true);
}
return false;
@ -836,8 +830,8 @@ void CefBrowserHostImpl::LoadURL(int64 frame_id, const std::string& url) {
}
}
void CefBrowserHostImpl::LoadString(int64 frame_id, const CefString& string,
const CefString& url) {
void CefBrowserHostImpl::LoadString(int64 frame_id, const std::string& string,
const std::string& url) {
// Only known frame ids or kMainFrameId are supported.
DCHECK(frame_id >= CefFrameHostImpl::kMainFrameId);
@ -848,15 +842,15 @@ void CefBrowserHostImpl::LoadString(int64 frame_id, const CefString& string,
params.request_id = -1;
params.expect_response = false;
params.arguments.Append(base::Value::CreateStringValue(string.ToString16()));
params.arguments.Append(base::Value::CreateStringValue(url.ToString16()));
params.arguments.Append(base::Value::CreateStringValue(string));
params.arguments.Append(base::Value::CreateStringValue(url));
Send(new CefMsg_Request(routing_id(), params));
}
void CefBrowserHostImpl::SendCommand(
int64 frame_id,
const CefString& command,
const std::string& command,
CefRefPtr<CefResponseManager::Handler> responseHandler) {
// Only known frame ids are supported.
DCHECK(frame_id > CefFrameHostImpl::kMainFrameId);
@ -877,8 +871,7 @@ void CefBrowserHostImpl::SendCommand(
params.expect_response = false;
}
params.arguments.Append(
base::Value::CreateStringValue(command.ToString16()));
params.arguments.Append(base::Value::CreateStringValue(command));
Send(new CefMsg_Request(routing_id(), params));
} else {
@ -891,8 +884,8 @@ void CefBrowserHostImpl::SendCommand(
void CefBrowserHostImpl::SendCode(
int64 frame_id,
bool is_javascript,
const CefString& code,
const CefString& script_url,
const std::string& code,
const std::string& script_url,
int script_start_line,
CefRefPtr<CefResponseManager::Handler> responseHandler) {
// Only known frame ids are supported.
@ -916,9 +909,8 @@ void CefBrowserHostImpl::SendCode(
}
params.arguments.Append(base::Value::CreateBooleanValue(is_javascript));
params.arguments.Append(base::Value::CreateStringValue(code.ToString16()));
params.arguments.Append(
base::Value::CreateStringValue(script_url.ToString16()));
params.arguments.Append(base::Value::CreateStringValue(code));
params.arguments.Append(base::Value::CreateStringValue(script_url));
params.arguments.Append(base::Value::CreateIntegerValue(script_start_line));
Send(new CefMsg_Request(routing_id(), params));
@ -929,6 +921,25 @@ void CefBrowserHostImpl::SendCode(
}
}
bool CefBrowserHostImpl::SendProcessMessage(CefProcessId target_process,
const std::string& name,
base::ListValue* arguments,
bool user_initiated) {
DCHECK_EQ(PID_RENDERER, target_process);
DCHECK(!name.empty());
Cef_Request_Params params;
params.name = name;
if (arguments)
params.arguments.Swap(arguments);
params.frame_id = -1;
params.user_initiated = user_initiated;
params.request_id = -1;
params.expect_response = false;
return Send(new CefMsg_Request(routing_id(), params));
}
bool CefBrowserHostImpl::ViewText(const std::string& text) {
return PlatformViewText(text);
}
@ -1433,6 +1444,8 @@ void CefBrowserHostImpl::OnRequest(const Cef_Request_Params& params) {
message.get());
message->Detach(NULL);
}
} else if (params.name == scheme::kChromeProcessMessage) {
scheme::OnChromeProcessMessage(this, params.arguments);
} else {
// Invalid request.
NOTREACHED();

View File

@ -167,18 +167,23 @@ class CefBrowserHostImpl : public CefBrowserHost,
void LoadURL(int64 frame_id, const std::string& url);
// Load the specified string.
void LoadString(int64 frame_id, const CefString& string,
const CefString& url);
void LoadString(int64 frame_id, const std::string& string,
const std::string& url);
// Send a command to the renderer for execution.
void SendCommand(int64 frame_id, const CefString& command,
void SendCommand(int64 frame_id, const std::string& command,
CefRefPtr<CefResponseManager::Handler> responseHandler);
// Send code to the renderer for execution.
void SendCode(int64 frame_id, bool is_javascript, const CefString& code,
const CefString& script_url, int script_start_line,
void SendCode(int64 frame_id, bool is_javascript, const std::string& code,
const std::string& script_url, int script_start_line,
CefRefPtr<CefResponseManager::Handler> responseHandler);
bool SendProcessMessage(CefProcessId target_process,
const std::string& name,
base::ListValue* arguments,
bool user_initiated);
// Open the specified text in the default text editor.
bool ViewText(const std::string& text);

View File

@ -1,21 +1,32 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that can
// be found in the LICENSE file.
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/chrome_scheme_handler.h"
#include <map>
#include <string>
#include "include/cef_trace.h"
#include "include/cef_version.h"
#include "include/cef_web_plugin.h"
#include "libcef/browser/context.h"
#include "libcef/browser/frame_host_impl.h"
#include "libcef/browser/internal_scheme_handler.h"
#include "libcef/browser/thread_util.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "content/public/common/content_client.h"
#include "grit/cef_resources.h"
#include "ipc/ipc_channel.h"
#include "v8/include/v8.h"
#include "webkit/user_agent/user_agent_util.h"
@ -23,17 +34,20 @@ namespace scheme {
const char kChromeScheme[] = "chrome";
const char kChromeURL[] = "chrome://";
const char kChromeProcessMessage[] = "chrome.send";
namespace {
const char kChromeCreditsDomain[] = "credits";
const char kChromeLicenseDomain[] = "license";
const char kChromeTracingDomain[] = "tracing";
const char kChromeVersionDomain[] = "version";
enum ChromeDomain {
CHROME_UNKNOWN = 0,
CHROME_CREDITS,
CHROME_LICENSE,
CHROME_TRACING,
CHROME_VERSION,
};
@ -44,6 +58,7 @@ ChromeDomain GetChromeDomain(const std::string& domain_name) {
} domains[] = {
{ kChromeCreditsDomain, CHROME_CREDITS },
{ kChromeLicenseDomain, CHROME_LICENSE },
{ kChromeTracingDomain, CHROME_TRACING },
{ kChromeVersionDomain, CHROME_VERSION },
};
@ -184,6 +199,9 @@ class Delegate : public InternalHandlerDelegate {
case CHROME_LICENSE:
handled = OnLicense(action);
break;
case CHROME_TRACING:
handled = OnTracing(path, action);
break;
case CHROME_VERSION:
handled = OnVersion(action);
break;
@ -192,6 +210,8 @@ class Delegate : public InternalHandlerDelegate {
}
if (!handled && domain != CHROME_VERSION) {
DLOG(INFO) << "Reguest for unknown chrome resource: " <<
url.spec().c_str();
action->redirect_url =
GURL(std::string(kChromeURL) + kChromeVersionDomain);
}
@ -230,6 +250,16 @@ class Delegate : public InternalHandlerDelegate {
return true;
}
bool OnTracing(const std::string& path, Action* action) {
if (path == "tracing.js") {
action->resource_id = IDR_CEF_TRACING_JS;
} else {
action->mime_type = "text/html";
action->resource_id = IDR_CEF_TRACING_HTML;
}
return true;
}
bool OnVersion(Action* action) {
base::StringPiece piece = content::GetContentClient()->GetDataResource(
IDR_CEF_VERSION_HTML, ui::SCALE_FACTOR_NONE);
@ -308,6 +338,262 @@ void DidFinishChromeVersionLoad(CefRefPtr<CefFrame> frame) {
CefVisitWebPluginInfo(new Visitor(frame));
}
// Test that the tracing browser window hasn't closed or navigated elsewhere.
bool IsTraceFrameValid(CefRefPtr<CefFrameHostImpl> frame) {
if (!frame->IsValid())
return false;
std::string tracing_url(kChromeURL);
tracing_url += kChromeTracingDomain;
std::string url = frame->GetURL();
if (url.find(tracing_url.c_str()) != 0)
return false;
return true;
}
void LoadTraceFile(CefRefPtr<CefFrameHostImpl> frame, const FilePath& path) {
CEF_REQUIRE_FILET();
if (!IsTraceFrameValid(frame))
return;
std::string file_contents;
if (!file_util::ReadFileToString(path, &file_contents)) {
frame->SendJavaScript(
"tracingController.onLoadTraceFileCanceled();", std::string(), 0);
return;
}
// We need to escape the file contents, because it will go into a javascript
// quoted string in LoadTraceFileSuccess. We need to escape control characters
// (to have well-formed javascript statements), as well as \ and ' (the only
// special characters in a ''-quoted string). Do the escaping on this thread,
// it may take a little while for big files and we don't want to block the UI
// during that time. Also do the UTF-16 conversion here.
// Note: we're using UTF-16 because we'll need to cut the string into slices
// to give to Javascript, and it's easier to cut than UTF-8 (since JS strings
// are arrays of 16-bit values, UCS-2 really, whereas we can't cut inside of a
// multibyte UTF-8 codepoint).
size_t size = file_contents.size();
std::string escaped_contents;
escaped_contents.reserve(size);
for (size_t i = 0; i < size; ++i) {
char c = file_contents[i];
if (c < ' ') {
escaped_contents += base::StringPrintf("\\u%04x", c);
continue;
}
if (c == '\\' || c == '\'')
escaped_contents.push_back('\\');
escaped_contents.push_back(c);
}
file_contents.clear();
const string16& contents16 = UTF8ToUTF16(escaped_contents);
// We need to pass contents to tracingController.onLoadTraceFileComplete, but
// that may be arbitrarily big, and IPC messages are limited in size. So we
// need to cut it into pieces and rebuild the string in Javascript.
// IPC::Channel::kMaximumMessageSize is in bytes, and we need to account for
// overhead.
static const size_t kMaxSize = IPC::Channel::kMaximumMessageSize / 2 - 128;
const string16& first_prefix = ASCIIToUTF16("window.traceData = '");
const string16& prefix = ASCIIToUTF16("window.traceData += '");
const string16& suffix = ASCIIToUTF16("';");
for (size_t i = 0; i < contents16.size(); i += kMaxSize) {
string16 javascript = i == 0 ? first_prefix : prefix;
javascript += contents16.substr(i, kMaxSize) + suffix;
frame->SendJavaScript(UTF16ToUTF8(javascript), std::string(), 0);
}
frame->SendJavaScript(
"tracingController.onLoadTraceFileComplete(JSON.parse(window.traceData));"
"delete window.traceData;",
std::string(), 0);
}
void SaveTraceFile(CefRefPtr<CefFrameHostImpl> frame,
const FilePath& path,
scoped_ptr<std::string> contents) {
CEF_REQUIRE_FILET();
if (!IsTraceFrameValid(frame))
return;
if (file_util::WriteFile(path, contents->c_str(), contents->size())) {
frame->SendJavaScript(
"tracingController.onSaveTraceFileComplete();",
std::string(), 0);
} else {
frame->SendJavaScript(
"tracingController.onSaveTraceFileCanceled();",
std::string(), 0);
}
}
void OnChromeTracingProcessMessage(CefRefPtr<CefBrowser> browser,
const std::string& action,
const base::ListValue* arguments) {
CefRefPtr<CefFrameHostImpl> frame =
static_cast<CefFrameHostImpl*>(browser->GetMainFrame().get());
if (action == "tracingControllerInitialized") {
// Send the client info to the tracingController.
} else if (action == "beginTracing") {
if (!arguments || arguments->GetSize() != 2) {
NOTREACHED() << "Invalid arguments to " << action.c_str();
return;
}
class Client : public CefTraceClient {
public:
explicit Client(CefRefPtr<CefFrameHostImpl> frame)
: frame_(frame),
ended_(false) {
}
virtual void OnTraceDataCollected(const char* fragment,
size_t fragment_size) OVERRIDE {
const std::string& prefix = "tracingController.onTraceDataCollected([";
const std::string& suffix = "]);";
std::string str;
str.reserve(prefix.size() + fragment_size + suffix.size() + 1);
str.append(prefix);
str.append(fragment, fragment_size);
str.append(suffix);
Execute(str);
}
virtual void OnTraceBufferPercentFullReply(float percent_full) OVERRIDE {
Execute(base::StringPrintf(
"tracingController.onRequestBufferPercentFullComplete(%f);",
percent_full));
}
virtual void OnEndTracingComplete() OVERRIDE {
ended_ = true;
Execute("tracingController.onEndTracingComplete();");
}
private:
void Execute(const std::string& code) {
if (!IsTraceFrameValid(frame_) && !ended_) {
ended_ = true;
CefEndTracingAsync();
return;
}
frame_->SendJavaScript(code, std::string(), 0);
}
CefRefPtr<CefFrameHostImpl> frame_;
bool ended_;
IMPLEMENT_REFCOUNTING(Callback);
};
std::string categories;
arguments->GetString(1, &categories);
CefRefPtr<CefTraceClient> client = new Client(frame);
// Tracing may already be running, in which case the previous client will
// continue handling it.
CefBeginTracing(client, categories);
} else if (action == "endTracingAsync") {
if (!CefEndTracingAsync()) {
// We weren't really tracing to begin with.
frame->SendJavaScript(
"tracingController.onEndTracingComplete();",
std::string(), 0);
}
} else if (action == "beginRequestBufferPercentFull") {
CefGetTraceBufferPercentFullAsync();
} else if (action == "loadTraceFile") {
class Callback : public CefRunFileDialogCallback {
public:
explicit Callback(CefRefPtr<CefFrameHostImpl> frame)
: frame_(frame) {
}
virtual void OnFileDialogDismissed(
CefRefPtr<CefBrowserHost> browser_host,
const std::vector<CefString>& file_paths) OVERRIDE {
if (!IsTraceFrameValid(frame_))
return;
if (!file_paths.empty()) {
CEF_POST_TASK(CEF_FILET,
base::Bind(LoadTraceFile, frame_,
FilePath(file_paths.front())));
} else {
frame_->SendJavaScript(
"tracingController.onLoadTraceFileCanceled();",
std::string(), 0);
}
}
private:
CefRefPtr<CefFrameHostImpl> frame_;
IMPLEMENT_REFCOUNTING(Callback);
};
browser->GetHost()->RunFileDialog(FILE_DIALOG_OPEN, CefString(),
CefString(), std::vector<CefString>(), new Callback(frame));
} else if (action == "saveTraceFile") {
if (!arguments || arguments->GetSize() != 1) {
NOTREACHED() << "Invalid arguments to " << action.c_str();
return;
}
class Callback : public CefRunFileDialogCallback {
public:
Callback(CefRefPtr<CefFrameHostImpl> frame,
scoped_ptr<std::string> contents)
: frame_(frame),
contents_(contents.Pass()) {
}
virtual void OnFileDialogDismissed(
CefRefPtr<CefBrowserHost> browser_host,
const std::vector<CefString>& file_paths) OVERRIDE {
if (!IsTraceFrameValid(frame_))
return;
if (!file_paths.empty()) {
CEF_POST_TASK(CEF_FILET,
base::Bind(SaveTraceFile, frame_,
FilePath(file_paths.front()),
base::Passed(contents_.Pass())));
} else {
frame_->SendJavaScript(
"tracingController.onSaveTraceFileCanceled();",
std::string(), 0);
}
}
private:
CefRefPtr<CefFrameHostImpl> frame_;
scoped_ptr<std::string> contents_;
IMPLEMENT_REFCOUNTING(Callback);
};
std::string contents_str;
arguments->GetString(0, &contents_str);
scoped_ptr<std::string> contents(new std::string());
contents_str.swap(*contents);
browser->GetHost()->RunFileDialog(FILE_DIALOG_SAVE, CefString(),
CefString(), std::vector<CefString>(),
new Callback(frame, contents.Pass()));
} else {
NOTREACHED() << "Unknown trace action: " << action.c_str();
}
}
} // namespace
void RegisterChromeHandler() {
@ -341,4 +627,26 @@ void DidFinishChromeLoad(CefRefPtr<CefFrame> frame,
}
}
void OnChromeProcessMessage(CefRefPtr<CefBrowser> browser,
const base::ListValue& arguments) {
std::string action;
const base::ListValue* args = NULL;
size_t size = arguments.GetSize();
if (size > 0) {
arguments.GetString(0, &action);
if (size > 1)
arguments.GetList(1, &args);
}
GURL url = GURL(browser->GetMainFrame()->GetURL().ToString());
ChromeDomain domain = GetChromeDomain(url.host());
switch (domain) {
case CHROME_TRACING:
OnChromeTracingProcessMessage(browser, action, args);
default:
break;
}
}
} // namespace scheme

View File

@ -7,9 +7,15 @@
#pragma once
#include <string>
#include "include/cef_browser.h"
#include "include/cef_frame.h"
#include "include/cef_process_message.h"
#include "googleurl/src/gurl.h"
namespace base {
class ListValue;
}
namespace content {
class BrowserContext;
}
@ -18,6 +24,7 @@ namespace scheme {
extern const char kChromeScheme[];
extern const char kChromeURL[];
extern const char kChromeProcessMessage[];
// Register the chrome scheme handler.
void RegisterChromeHandler();
@ -30,6 +37,10 @@ bool WillHandleBrowserAboutURL(GURL* url,
void DidFinishChromeLoad(CefRefPtr<CefFrame> frame,
const GURL& validated_url);
// Used to execute messages from render process bindings.
void OnChromeProcessMessage(CefRefPtr<CefBrowser> browser,
const base::ListValue& arguments);
} // namespace scheme
#endif // CEF_LIBCEF_BROWSER_CHROME_SCHEME_HANDLER_H_

View File

@ -10,6 +10,7 @@
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/scheme_registration.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/trace_subscriber.h"
#include "libcef/common/main_delegate.h"
#include "base/bind.h"
@ -356,6 +357,15 @@ CefDevToolsDelegate* CefContext::devtools_delegate() const {
devtools_delegate();
}
CefTraceSubscriber* CefContext::GetTraceSubscriber() {
CEF_REQUIRE_UIT();
if (shutting_down_)
return NULL;
if (!trace_subscriber_.get())
trace_subscriber_.reset(new CefTraceSubscriber());
return trace_subscriber_.get();
}
void CefContext::OnContextInitialized() {
CEF_REQUIRE_UIT();
@ -393,6 +403,9 @@ void CefContext::FinishShutdownOnUIThread(
(*it)->DestroyBrowser();
}
if (trace_subscriber_.get())
trace_subscriber_.reset(NULL);
if (uithread_shutdown_event)
uithread_shutdown_event->Signal();
}

View File

@ -30,6 +30,7 @@ class CefBrowserContext;
class CefBrowserHostImpl;
class CefDevToolsDelegate;
class CefMainDelegate;
class CefTraceSubscriber;
class CefContext : public CefBase {
public:
@ -69,6 +70,8 @@ class CefContext : public CefBase {
CefBrowserContext* browser_context() const;
CefDevToolsDelegate* devtools_delegate() const;
CefTraceSubscriber* GetTraceSubscriber();
private:
void OnContextInitialized();
@ -98,6 +101,7 @@ class CefContext : public CefBase {
scoped_ptr<CefMainDelegate> main_delegate_;
scoped_ptr<content::ContentMainRunner> main_runner_;
scoped_ptr<CefTraceSubscriber> trace_subscriber_;
IMPLEMENT_REFCOUNTING(CefContext);
IMPLEMENT_LOCKING(CefContext);

View File

@ -153,16 +153,7 @@ void CefFrameHostImpl::LoadString(const CefString& string,
void CefFrameHostImpl::ExecuteJavaScript(const CefString& jsCode,
const CefString& scriptUrl,
int startLine) {
if (jsCode.empty())
return;
if (startLine < 0)
startLine = 0;
base::AutoLock lock_scope(state_lock_);
if (browser_) {
browser_->SendCode((is_main_frame_ ? kMainFrameId : frame_id_), true,
jsCode, scriptUrl, startLine, NULL);
}
SendJavaScript(jsCode, scriptUrl, startLine);
}
bool CefFrameHostImpl::IsMain() {
@ -234,6 +225,22 @@ void CefFrameHostImpl::VisitDOM(CefRefPtr<CefDOMVisitor> visitor) {
NOTREACHED() << "VisitDOM cannot be called from the browser process";
}
void CefFrameHostImpl::SendJavaScript(
const std::string& jsCode,
const std::string& scriptUrl,
int startLine) {
if (jsCode.empty())
return;
if (startLine < 0)
startLine = 0;
base::AutoLock lock_scope(state_lock_);
if (browser_) {
browser_->SendCode((is_main_frame_ ? kMainFrameId : frame_id_), true,
jsCode, scriptUrl, startLine, NULL);
}
}
void CefFrameHostImpl::Detach() {
base::AutoLock lock_scope(state_lock_);
browser_ = NULL;

View File

@ -56,6 +56,11 @@ class CefFrameHostImpl : public CefFrame {
void SetName(const CefString& name);
void SetParentId(int64 frame_id);
// Avoids unnecessary string type conversions.
void SendJavaScript(const std::string& jsCode,
const std::string& scriptUrl,
int startLine);
// Detach the frame from the browser.
void Detach();

View File

@ -0,0 +1,370 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that can
// be found in the LICENSE file.
#include "include/cef_trace.h"
#include "include/cef_trace_event.h"
#include "libcef/browser/trace_subscriber.h"
#include "libcef/browser/context.h"
#include "libcef/browser/thread_util.h"
#include "base/debug/trace_event.h"
bool CefBeginTracing(CefRefPtr<CefTraceClient> client,
const CefString& categories) {
if (!CONTEXT_STATE_VALID()) {
NOTREACHED() << "context not valid";
return false;
}
if (!CEF_CURRENTLY_ON_UIT()) {
NOTREACHED() << "called on invalid thread";
return false;
}
CefTraceSubscriber* subscriber = _Context->GetTraceSubscriber();
if (!subscriber)
return false;
return subscriber->BeginTracing(client, categories);
}
bool CefGetTraceBufferPercentFullAsync() {
if (!CONTEXT_STATE_VALID()) {
NOTREACHED() << "context not valid";
return false;
}
if (!CEF_CURRENTLY_ON_UIT()) {
NOTREACHED() << "called on invalid thread";
return false;
}
CefTraceSubscriber* subscriber = _Context->GetTraceSubscriber();
if (!subscriber)
return false;
return subscriber->GetTraceBufferPercentFullAsync();
}
bool CefEndTracingAsync() {
if (!CONTEXT_STATE_VALID()) {
NOTREACHED() << "context not valid";
return false;
}
if (!CEF_CURRENTLY_ON_UIT()) {
NOTREACHED() << "called on invalid thread";
return false;
}
CefTraceSubscriber* subscriber = _Context->GetTraceSubscriber();
if (!subscriber)
return false;
return subscriber->EndTracingAsync();
}
// The below functions can be called from any process.
CEF_EXPORT void cef_trace_event(const char* category,
const char* name,
const char* arg1_name,
uint64 arg1_val,
const char* arg2_name,
uint64 arg2_val) {
DCHECK(category);
DCHECK(name);
if (!category || !name)
return;
if (arg1_name == NULL && arg2_name == NULL) {
TRACE_EVENT0(category, name);
} else if (arg2_name == NULL) {
TRACE_EVENT1(category, name, arg1_name, arg1_val);
} else {
TRACE_EVENT2(category, name, arg1_name, arg1_val,
arg2_name, arg2_val);
}
}
CEF_EXPORT void cef_trace_event_instant(const char* category,
const char* name,
const char* arg1_name,
uint64 arg1_val,
const char* arg2_name,
uint64 arg2_val,
int copy) {
DCHECK(category);
DCHECK(name);
if (!category || !name)
return;
if (copy) {
if (arg1_name == NULL && arg2_name == NULL) {
TRACE_EVENT_COPY_INSTANT0(category, name);
} else if (arg2_name == NULL) {
TRACE_EVENT_COPY_INSTANT1(category, name, arg1_name, arg1_val);
} else {
TRACE_EVENT_COPY_INSTANT2(category, name, arg1_name, arg1_val,
arg2_name, arg2_val);
}
} else {
if (arg1_name == NULL && arg2_name == NULL) {
TRACE_EVENT_INSTANT0(category, name);
} else if (arg2_name == NULL) {
TRACE_EVENT_INSTANT1(category, name, arg1_name, arg1_val);
} else {
TRACE_EVENT_INSTANT2(category, name, arg1_name, arg1_val,
arg2_name, arg2_val);
}
}
}
CEF_EXPORT void cef_trace_event_begin(const char* category,
const char* name,
const char* arg1_name,
uint64 arg1_val,
const char* arg2_name,
uint64 arg2_val,
int copy) {
DCHECK(category);
DCHECK(name);
if (!category || !name)
return;
if (copy) {
if (arg1_name == NULL && arg2_name == NULL) {
TRACE_EVENT_COPY_BEGIN0(category, name);
} else if (arg2_name == NULL) {
TRACE_EVENT_COPY_BEGIN1(category, name, arg1_name, arg1_val);
} else {
TRACE_EVENT_COPY_BEGIN2(category, name, arg1_name, arg1_val,
arg2_name, arg2_val);
}
} else {
if (arg1_name == NULL && arg2_name == NULL) {
TRACE_EVENT_BEGIN0(category, name);
} else if (arg2_name == NULL) {
TRACE_EVENT_BEGIN1(category, name, arg1_name, arg1_val);
} else {
TRACE_EVENT_BEGIN2(category, name, arg1_name, arg1_val,
arg2_name, arg2_val);
}
}
}
CEF_EXPORT void cef_trace_event_end(const char* category,
const char* name,
const char* arg1_name,
uint64 arg1_val,
const char* arg2_name,
uint64 arg2_val,
int copy) {
DCHECK(category);
DCHECK(name);
if (!category || !name)
return;
if (copy) {
if (arg1_name == NULL && arg2_name == NULL) {
TRACE_EVENT_COPY_END0(category, name);
} else if (arg2_name == NULL) {
TRACE_EVENT_COPY_END1(category, name, arg1_name, arg1_val);
} else {
TRACE_EVENT_COPY_END2(category, name, arg1_name, arg1_val,
arg2_name, arg2_val);
}
} else {
if (arg1_name == NULL && arg2_name == NULL) {
TRACE_EVENT_END0(category, name);
} else if (arg2_name == NULL) {
TRACE_EVENT_END1(category, name, arg1_name, arg1_val);
} else {
TRACE_EVENT_END2(category, name, arg1_name, arg1_val,
arg2_name, arg2_val);
}
}
}
CEF_EXPORT void cef_trace_event_if_longer_than(int64 threshold_us,
const char* category,
const char* name,
const char* arg1_name,
uint64 arg1_val,
const char* arg2_name,
uint64 arg2_val) {
DCHECK(category);
DCHECK(name);
if (!category || !name)
return;
if (arg1_name == NULL && arg2_name == NULL) {
TRACE_EVENT_IF_LONGER_THAN0(threshold_us, category, name);
} else if (arg2_name == NULL) {
TRACE_EVENT_IF_LONGER_THAN1(threshold_us, category, name,
arg1_name, arg1_val);
} else {
TRACE_EVENT_IF_LONGER_THAN2(threshold_us, category, name, arg1_name,
arg1_val, arg2_name, arg2_val);
}
}
CEF_EXPORT void cef_trace_counter(const char* category,
const char* name,
const char* value1_name,
uint64 value1_val,
const char* value2_name,
uint64 value2_val,
int copy) {
DCHECK(category);
DCHECK(name);
if (!category || !name)
return;
if (copy) {
if (value1_name == NULL && value2_name == NULL) {
TRACE_COPY_COUNTER1(category, name, value1_val);
} else {
TRACE_COPY_COUNTER2(category, name, value1_name, value1_val,
value2_name, value2_val);
}
} else {
if (value1_name == NULL && value2_name == NULL) {
TRACE_COUNTER1(category, name, value1_val);
} else {
TRACE_COUNTER2(category, name, value1_name, value1_val,
value2_name, value2_val);
}
}
}
CEF_EXPORT void cef_trace_counter_id(const char* category,
const char* name,
uint64 id,
const char* value1_name,
uint64 value1_val,
const char* value2_name,
uint64 value2_val,
int copy) {
DCHECK(category);
DCHECK(name);
if (!category || !name)
return;
if (copy) {
if (value1_name == NULL && value2_name == NULL) {
TRACE_COPY_COUNTER_ID1(category, name, id, value1_val);
} else {
TRACE_COPY_COUNTER_ID2(category, name, id, value1_name,
value1_val, value2_name, value2_val);
}
} else {
if (value1_name == NULL && value2_name == NULL) {
TRACE_COUNTER_ID1(category, name, id, value1_val);
} else {
TRACE_COUNTER_ID2(category, name, id, value1_name, value1_val,
value2_name, value2_val);
}
}
}
CEF_EXPORT void cef_trace_event_async_begin(const char* category,
const char* name,
uint64 id,
const char* arg1_name,
uint64 arg1_val,
const char* arg2_name,
uint64 arg2_val,
int copy) {
DCHECK(category);
DCHECK(name);
if (!category || !name)
return;
if (copy) {
if (arg1_name == NULL && arg2_name == NULL) {
TRACE_EVENT_COPY_ASYNC_BEGIN0(category, name, id);
} else if (arg2_name == NULL) {
TRACE_EVENT_COPY_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val);
} else {
TRACE_EVENT_COPY_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val,
arg2_name, arg2_val);
}
} else {
if (arg1_name == NULL && arg2_name == NULL) {
TRACE_EVENT_ASYNC_BEGIN0(category, name, id);
} else if (arg2_name == NULL) {
TRACE_EVENT_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val);
} else {
TRACE_EVENT_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val,
arg2_name, arg2_val);
}
}
}
CEF_EXPORT void cef_trace_event_async_step(const char* category,
const char* name,
uint64 id,
uint64 step,
const char* arg1_name,
uint64 arg1_val,
int copy) {
DCHECK(category);
DCHECK(name);
if (!category || !name)
return;
if (copy) {
if (arg1_name == NULL) {
TRACE_EVENT_COPY_ASYNC_STEP0(category, name, id, step);
} else {
TRACE_EVENT_COPY_ASYNC_STEP1(category, name, id, step,
arg1_name, arg1_val);
}
} else {
if (arg1_name == NULL) {
TRACE_EVENT_ASYNC_STEP0(category, name, id, step);
} else {
TRACE_EVENT_ASYNC_STEP1(category, name, id, step,
arg1_name, arg1_val);
}
}
}
CEF_EXPORT void cef_trace_event_async_end(const char* category,
const char* name,
uint64 id,
const char* arg1_name,
uint64 arg1_val,
const char* arg2_name,
uint64 arg2_val,
int copy) {
DCHECK(category);
DCHECK(name);
if (!category || !name)
return;
if (copy) {
if (arg1_name == NULL && arg2_name == NULL) {
TRACE_EVENT_COPY_ASYNC_END0(category, name, id);
} else if (arg2_name == NULL) {
TRACE_EVENT_COPY_ASYNC_END1(category, name, id, arg1_name,
arg1_val);
} else {
TRACE_EVENT_COPY_ASYNC_END2(category, name, id, arg1_name,
arg1_val, arg2_name, arg2_val);
}
} else {
if (arg1_name == NULL && arg2_name == NULL) {
TRACE_EVENT_ASYNC_END0(category, name, id);
} else if (arg2_name == NULL) {
TRACE_EVENT_ASYNC_END1(category, name, id, arg1_name,
arg1_val);
} else {
TRACE_EVENT_ASYNC_END2(category, name, id, arg1_name,
arg1_val, arg2_name, arg2_val);
}
}
}

View File

@ -0,0 +1,78 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that can
// be found in the LICENSE file.
#include "libcef/browser/trace_subscriber.h"
#include "include/cef_trace.h"
#include "libcef/browser/thread_util.h"
#include "content/public/browser/trace_controller.h"
CefTraceSubscriber::CefTraceSubscriber()
: collecting_trace_data_(false) {
CEF_REQUIRE_UIT();
}
CefTraceSubscriber::~CefTraceSubscriber() {
CEF_REQUIRE_UIT();
if (collecting_trace_data_)
content::TraceController::GetInstance()->CancelSubscriber(this);
}
bool CefTraceSubscriber::BeginTracing(CefRefPtr<CefTraceClient> client,
const std::string& categories) {
CEF_REQUIRE_UIT();
if (collecting_trace_data_)
return false;
collecting_trace_data_ = true;
client_ = client;
return content::TraceController::GetInstance()->BeginTracing(
this, categories);
}
bool CefTraceSubscriber::EndTracingAsync() {
CEF_REQUIRE_UIT();
if (!collecting_trace_data_)
return false;
return content::TraceController::GetInstance()->EndTracingAsync(this);
}
bool CefTraceSubscriber::GetTraceBufferPercentFullAsync() {
CEF_REQUIRE_UIT();
if (!collecting_trace_data_ || !client_.get())
return false;
return content::TraceController::GetInstance()->
GetTraceBufferPercentFullAsync(this);
}
void CefTraceSubscriber::OnTraceDataCollected(
const scoped_refptr<base::RefCountedString>& trace_fragment) {
CEF_REQUIRE_UIT();
DCHECK(collecting_trace_data_);
if (client_.get()) {
client_->OnTraceDataCollected(trace_fragment->data().c_str(),
trace_fragment->data().size());
}
}
void CefTraceSubscriber::OnTraceBufferPercentFullReply(float percent_full) {
CEF_REQUIRE_UIT();
DCHECK(collecting_trace_data_);
DCHECK(client_.get());
client_->OnTraceBufferPercentFullReply(percent_full);
}
void CefTraceSubscriber::OnEndTracingComplete() {
CEF_REQUIRE_UIT();
DCHECK(collecting_trace_data_);
collecting_trace_data_ = false;
if (client_.get())
client_->OnEndTracingComplete();
}

View File

@ -0,0 +1,38 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that can
// be found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_TRACE_SUBSCRIBER_H_
#define CEF_LIBCEF_BROWSER_TRACE_SUBSCRIBER_H_
#pragma once
#include "include/cef_trace.h"
#include "base/debug/trace_event.h"
#include "base/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "content/public/browser/trace_subscriber.h"
// May only be accessed on the browser process UI thread.
class CefTraceSubscriber : public content::TraceSubscriber {
public:
CefTraceSubscriber();
virtual ~CefTraceSubscriber();
bool BeginTracing(CefRefPtr<CefTraceClient> client,
const std::string& categories);
bool GetTraceBufferPercentFullAsync();
bool EndTracingAsync();
private:
// content::TraceSubscriber methods:
virtual void OnTraceDataCollected(
const scoped_refptr<base::RefCountedString>& trace_fragment) OVERRIDE;
virtual void OnTraceBufferPercentFullReply(float percent_full) OVERRIDE;
virtual void OnEndTracingComplete() OVERRIDE;
bool collecting_trace_data_;
CefRefPtr<CefTraceClient> client_;
};
#endif // CEF_LIBCEF_BROWSER_TRACE_SUBSCRIBER_H_

View File

@ -291,7 +291,7 @@ CefString CefDictionaryValueImpl::GetString(const CefString& key) {
CEF_VALUE_VERIFY_RETURN(false, CefString());
const base::Value* out_value = NULL;
string16 ret_value;
std::string ret_value;
if (const_value().GetWithoutPathExpansion(key, &out_value))
out_value->GetAsString(&ret_value);
@ -392,7 +392,7 @@ bool CefDictionaryValueImpl::SetString(const CefString& key,
CEF_VALUE_VERIFY_RETURN(true, false);
RemoveInternal(key);
mutable_value()->SetWithoutPathExpansion(key,
base::Value::CreateStringValue(value.ToString16()));
base::Value::CreateStringValue(value.ToString()));
return true;
}
@ -630,7 +630,7 @@ CefString CefListValueImpl::GetString(int index) {
CEF_VALUE_VERIFY_RETURN(false, CefString());
const base::Value* out_value = NULL;
string16 ret_value;
std::string ret_value;
if (const_value().Get(index, &out_value))
out_value->GetAsString(&ret_value);
@ -735,7 +735,7 @@ bool CefListValueImpl::SetDouble(int index, double value) {
bool CefListValueImpl::SetString(int index, const CefString& value) {
CEF_VALUE_VERIFY_RETURN(true, false);
base::Value* new_value = base::Value::CreateStringValue(value.ToString16());
base::Value* new_value = base::Value::CreateStringValue(value.ToString());
if (RemoveInternal(index))
mutable_value()->Insert(index, new_value);
else

View File

@ -234,21 +234,12 @@ void CefBrowserImpl::GetFrameNames(std::vector<CefString>& names) {
bool CefBrowserImpl::SendProcessMessage(CefProcessId target_process,
CefRefPtr<CefProcessMessage> message) {
DCHECK_EQ(PID_BROWSER, target_process);
DCHECK(message.get());
Cef_Request_Params params;
CefProcessMessageImpl* impl =
static_cast<CefProcessMessageImpl*>(message.get());
if (impl->CopyTo(params)) {
DCHECK(!params.name.empty());
params.frame_id = -1;
params.user_initiated = true;
params.request_id = -1;
params.expect_response = false;
return Send(new CefHostMsg_Request(routing_id(), params));
return SendProcessMessage(target_process, params.name, &params.arguments,
true);
}
return false;
@ -342,6 +333,25 @@ void CefBrowserImpl::LoadRequest(const CefMsg_LoadRequest_Params& params) {
web_frame->loadRequest(request);
}
bool CefBrowserImpl::SendProcessMessage(CefProcessId target_process,
const std::string& name,
base::ListValue* arguments,
bool user_initiated) {
DCHECK_EQ(PID_BROWSER, target_process);
DCHECK(!name.empty());
Cef_Request_Params params;
params.name = name;
if (arguments)
params.arguments.Swap(arguments);
params.frame_id = -1;
params.user_initiated = user_initiated;
params.request_id = -1;
params.expect_response = false;
return Send(new CefHostMsg_Request(routing_id(), params));
}
CefRefPtr<CefFrameImpl> CefBrowserImpl::GetWebFrameImpl(
WebKit::WebFrame* frame) {
DCHECK(frame);
@ -597,7 +607,7 @@ void CefBrowserImpl::OnRequest(const Cef_Request_Params& params) {
DCHECK_EQ(params.arguments.GetSize(), (size_t)4);
bool is_javascript = false;
string16 code, script_url;
std::string code, script_url;
int script_start_line = 0;
params.arguments.GetBoolean(0, &is_javascript);
@ -609,8 +619,8 @@ void CefBrowserImpl::OnRequest(const Cef_Request_Params& params) {
if (is_javascript) {
web_frame->executeScript(
WebScriptSource(code,
GURL(UTF16ToUTF8(script_url)),
WebScriptSource(UTF8ToUTF16(code),
GURL(script_url),
script_start_line));
success = true;
} else {
@ -627,7 +637,7 @@ void CefBrowserImpl::OnRequest(const Cef_Request_Params& params) {
if (web_frame) {
DCHECK_EQ(params.arguments.GetSize(), (size_t)1);
string16 command;
std::string command;
params.arguments.GetString(0, &command);
DCHECK(!command.empty());
@ -638,7 +648,7 @@ void CefBrowserImpl::OnRequest(const Cef_Request_Params& params) {
} else if (LowerCaseEqualsASCII(command, "gettext")) {
response = UTF16ToUTF8(webkit_glue::DumpDocumentText(web_frame));
success = true;
} else if (web_frame->executeCommand(command)) {
} else if (web_frame->executeCommand(UTF8ToUTF16(command))) {
success = true;
}
}
@ -651,12 +661,12 @@ void CefBrowserImpl::OnRequest(const Cef_Request_Params& params) {
if (web_frame) {
DCHECK_EQ(params.arguments.GetSize(), (size_t)2);
string16 string, url;
std::string string, url;
params.arguments.GetString(0, &string);
params.arguments.GetString(1, &url);
web_frame->loadHTMLString(UTF16ToUTF8(string), GURL(UTF16ToUTF8(url)));
web_frame->loadHTMLString(string, GURL(url));
}
}
} else {

View File

@ -81,6 +81,12 @@ class CefBrowserImpl : public CefBrowser,
void LoadRequest(const CefMsg_LoadRequest_Params& params);
// Avoids unnecessary string type conversions.
bool SendProcessMessage(CefProcessId target_process,
const std::string& name,
base::ListValue* arguments,
bool user_initiated);
// Returns the matching CefFrameImpl reference or creates a new one.
CefRefPtr<CefFrameImpl> GetWebFrameImpl(WebKit::WebFrame* frame);
CefRefPtr<CefFrameImpl> GetWebFrameImpl(int64 frame_id);

View File

@ -0,0 +1,116 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "libcef/renderer/chrome_bindings.h"
#include "libcef/renderer/browser_impl.h"
#include <string>
#include "base/logging.h"
#include "base/values.h"
namespace scheme {
namespace {
void SetList(CefRefPtr<CefV8Value> source, base::ListValue* target);
// Transfer a V8 value to a List index.
void SetListValue(base::ListValue* list, int index,
CefRefPtr<CefV8Value> value) {
if (value->IsArray()) {
base::ListValue* new_list = new base::ListValue();
SetList(value, new_list);
list->Set(index, new_list);
} else if (value->IsString()) {
list->Set(index,
base::Value::CreateStringValue(value->GetStringValue().ToString()));
} else if (value->IsBool()) {
list->Set(index, base::Value::CreateBooleanValue(value->GetBoolValue()));
} else if (value->IsInt()) {
list->Set(index, base::Value::CreateIntegerValue(value->GetIntValue()));
} else if (value->IsDouble()) {
list->Set(index, base::Value::CreateDoubleValue(value->GetDoubleValue()));
}
}
// Transfer a V8 array to a List.
void SetList(CefRefPtr<CefV8Value> source, base::ListValue* target) {
DCHECK(source->IsArray());
int arg_length = source->GetArrayLength();
if (arg_length == 0)
return;
for (int i = 0; i < arg_length; ++i)
SetListValue(target, i, source->GetValue(i));
}
class V8Handler : public CefV8Handler {
public:
V8Handler() {}
virtual bool Execute(const CefString& name,
CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments,
CefRefPtr<CefV8Value>& retval,
CefString& exception) OVERRIDE {
std::string nameStr = name;
if (nameStr == "send") {
if (arguments.size() > 0 && arguments.size() <= 2 &&
arguments[0]->IsString()) {
base::ListValue args;
SetListValue(&args, 0, arguments[0]);
if (arguments.size() > 1)
SetListValue(&args, 1, arguments[1]);
CefRefPtr<CefBrowserImpl> browser = static_cast<CefBrowserImpl*>(
CefV8Context::GetCurrentContext()->GetBrowser().get());
browser->SendProcessMessage(PID_BROWSER, kChromeProcessMessage, &args,
false);
retval = CefV8Value::CreateBool(true);
} else {
exception = "Invalid number of arguments or argument format";
}
return true;
} else if (nameStr == "bind") {
// Return the "send" object.
DCHECK(object->GetFunctionName() == "send");
retval = object;
return true;
}
NOTREACHED();
return false;
}
IMPLEMENT_REFCOUNTING(V8Handler);
};
} // namespace
void OnContextCreated(CefRefPtr<CefBrowserImpl> browser,
CefRefPtr<CefFrameImpl> frame,
CefRefPtr<CefV8Context> context) {
GURL url = GURL(frame->GetURL().ToString());
if (url.scheme() != kChromeScheme)
return;
CefRefPtr<CefV8Value> global = context->GetGlobal();
CefRefPtr<CefV8Handler> handler = new V8Handler();
// Add "chrome".
CefRefPtr<CefV8Value> chrome = CefV8Value::CreateObject(NULL);
global->SetValue("chrome", chrome, V8_PROPERTY_ATTRIBUTE_NONE);
// Add "chrome.send".
CefRefPtr<CefV8Value> send = CefV8Value::CreateFunction("send", handler);
chrome->SetValue("send", send, V8_PROPERTY_ATTRIBUTE_NONE);
// Add "chrome.send.bind".
CefRefPtr<CefV8Value> bind = CefV8Value::CreateFunction("bind", handler);
send->SetValue("bind", bind, V8_PROPERTY_ATTRIBUTE_NONE);
}
} // namespace scheme

View File

@ -0,0 +1,24 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#ifndef CEF_LIBCEF_RENDERER_CHROME_BINDINGS_H_
#define CEF_LIBCEF_RENDERER_CHROME_BINDINGS_H_
#pragma once
#include "include/cef_v8.h"
#include "libcef/renderer/browser_impl.h"
#include "libcef/renderer/frame_impl.h"
namespace scheme {
extern const char kChromeScheme[];
extern const char kChromeProcessMessage[];
void OnContextCreated(CefRefPtr<CefBrowserImpl> browser,
CefRefPtr<CefFrameImpl> frame,
CefRefPtr<CefV8Context> context);
} // namespace scheme
#endif // CEF_LIBCEF_RENDERER_CHROME_BINDINGS_H_

View File

@ -16,6 +16,7 @@ MSVC_POP_WARNING();
#include "libcef/common/cef_messages.h"
#include "libcef/common/content_client.h"
#include "libcef/renderer/browser_impl.h"
#include "libcef/renderer/chrome_bindings.h"
#include "libcef/renderer/render_process_observer.h"
#include "libcef/renderer/thread_util.h"
#include "libcef/renderer/v8_impl.h"
@ -179,16 +180,6 @@ void CefContentRendererClient::RenderViewCreated(
void CefContentRendererClient::DidCreateScriptContext(
WebKit::WebFrame* frame, v8::Handle<v8::Context> context,
int extension_group, int world_id) {
// Notify the render process handler.
CefRefPtr<CefApp> application = CefContentClient::Get()->application();
if (!application.get())
return;
CefRefPtr<CefRenderProcessHandler> handler =
application->GetRenderProcessHandler();
if (!handler.get())
return;
CefRefPtr<CefBrowserImpl> browserPtr =
CefBrowserImpl::GetBrowserForMainFrame(frame->top());
DCHECK(browserPtr.get());
@ -204,8 +195,17 @@ void CefContentRendererClient::DidCreateScriptContext(
CefRefPtr<CefV8Context> contextPtr(new CefV8ContextImpl(context));
scheme::OnContextCreated(browserPtr, framePtr, contextPtr);
// Notify the render process handler.
CefRefPtr<CefApp> application = CefContentClient::Get()->application();
if (application.get()) {
CefRefPtr<CefRenderProcessHandler> handler =
application->GetRenderProcessHandler();
if (handler.get())
handler->OnContextCreated(browserPtr.get(), framePtr.get(), contextPtr);
}
}
void CefContentRendererClient::WillReleaseScriptContext(
WebKit::WebFrame* frame, v8::Handle<v8::Context> context, int world_id) {

View File

@ -15,6 +15,8 @@
<include name="IDR_CEF_CREDITS_SWIFTSHADER_JPG" file="..\..\..\chrome\browser\resources\swiftshader.jpg" type="BINDATA" />
<include name="IDR_CEF_LICENSE_TXT" file="..\..\LICENSE.txt" type="BINDATA" />
<include name="IDR_CEF_VERSION_HTML" file="about_version.html" type="BINDATA" />
<include name="IDR_CEF_TRACING_HTML" file="..\..\..\third_party\trace-viewer\src\about_tracing.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
<include name="IDR_CEF_TRACING_JS" file="..\..\..\third_party\trace-viewer\src\about_tracing.js" flattenhtml="true" type="BINDATA" />
</includes>
</release>
</grit>

View File

@ -0,0 +1,79 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
#include "libcef_dll/cpptoc/trace_client_cpptoc.h"
// MEMBER FUNCTIONS - Body may be edited by hand.
void CEF_CALLBACK trace_client_on_trace_data_collected(
struct _cef_trace_client_t* self, const char* fragment,
size_t fragment_size) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: fragment; type: simple_byaddr
DCHECK(fragment);
if (!fragment)
return;
// Execute
CefTraceClientCppToC::Get(self)->OnTraceDataCollected(
fragment,
fragment_size);
}
void CEF_CALLBACK trace_client_on_trace_buffer_percent_full_reply(
struct _cef_trace_client_t* self, float percent_full) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Execute
CefTraceClientCppToC::Get(self)->OnTraceBufferPercentFullReply(
percent_full);
}
void CEF_CALLBACK trace_client_on_end_tracing_complete(
struct _cef_trace_client_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Execute
CefTraceClientCppToC::Get(self)->OnEndTracingComplete();
}
// CONSTRUCTOR - Do not edit by hand.
CefTraceClientCppToC::CefTraceClientCppToC(CefTraceClient* cls)
: CefCppToC<CefTraceClientCppToC, CefTraceClient, cef_trace_client_t>(cls) {
struct_.struct_.on_trace_data_collected =
trace_client_on_trace_data_collected;
struct_.struct_.on_trace_buffer_percent_full_reply =
trace_client_on_trace_buffer_percent_full_reply;
struct_.struct_.on_end_tracing_complete =
trace_client_on_end_tracing_complete;
}
#ifndef NDEBUG
template<> long CefCppToC<CefTraceClientCppToC, CefTraceClient,
cef_trace_client_t>::DebugObjCt = 0;
#endif

View File

@ -0,0 +1,37 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
#ifndef CEF_LIBCEF_DLL_CPPTOC_TRACE_CLIENT_CPPTOC_H_
#define CEF_LIBCEF_DLL_CPPTOC_TRACE_CLIENT_CPPTOC_H_
#pragma once
#ifndef USING_CEF_SHARED
#pragma message("Warning: "__FILE__" may be accessed wrapper-side only")
#else // USING_CEF_SHARED
#include "include/cef_trace.h"
#include "include/capi/cef_trace_capi.h"
#include "libcef_dll/cpptoc/cpptoc.h"
// Wrap a C++ class with a C structure.
// This class may be instantiated and accessed wrapper-side only.
class CefTraceClientCppToC
: public CefCppToC<CefTraceClientCppToC, CefTraceClient,
cef_trace_client_t> {
public:
explicit CefTraceClientCppToC(CefTraceClient* cls);
virtual ~CefTraceClientCppToC() {}
};
#endif // USING_CEF_SHARED
#endif // CEF_LIBCEF_DLL_CPPTOC_TRACE_CLIENT_CPPTOC_H_

View File

@ -0,0 +1,62 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
#include "libcef_dll/ctocpp/trace_client_ctocpp.h"
// VIRTUAL METHODS - Body may be edited by hand.
void CefTraceClientCToCpp::OnTraceDataCollected(const char* fragment,
size_t fragment_size) {
if (CEF_MEMBER_MISSING(struct_, on_trace_data_collected))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: fragment; type: simple_byaddr
DCHECK(fragment);
if (!fragment)
return;
// Execute
struct_->on_trace_data_collected(struct_,
fragment,
fragment_size);
}
void CefTraceClientCToCpp::OnTraceBufferPercentFullReply(float percent_full) {
if (CEF_MEMBER_MISSING(struct_, on_trace_buffer_percent_full_reply))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
struct_->on_trace_buffer_percent_full_reply(struct_,
percent_full);
}
void CefTraceClientCToCpp::OnEndTracingComplete() {
if (CEF_MEMBER_MISSING(struct_, on_end_tracing_complete))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
struct_->on_end_tracing_complete(struct_);
}
#ifndef NDEBUG
template<> long CefCToCpp<CefTraceClientCToCpp, CefTraceClient,
cef_trace_client_t>::DebugObjCt = 0;
#endif

View File

@ -0,0 +1,45 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_TRACE_CLIENT_CTOCPP_H_
#define CEF_LIBCEF_DLL_CTOCPP_TRACE_CLIENT_CTOCPP_H_
#pragma once
#ifndef BUILDING_CEF_SHARED
#pragma message("Warning: "__FILE__" may be accessed DLL-side only")
#else // BUILDING_CEF_SHARED
#include "include/cef_trace.h"
#include "include/capi/cef_trace_capi.h"
#include "libcef_dll/ctocpp/ctocpp.h"
// Wrap a C structure with a C++ class.
// This class may be instantiated and accessed DLL-side only.
class CefTraceClientCToCpp
: public CefCToCpp<CefTraceClientCToCpp, CefTraceClient,
cef_trace_client_t> {
public:
explicit CefTraceClientCToCpp(cef_trace_client_t* str)
: CefCToCpp<CefTraceClientCToCpp, CefTraceClient, cef_trace_client_t>(
str) {}
virtual ~CefTraceClientCToCpp() {}
// CefTraceClient methods
virtual void OnTraceDataCollected(const char* fragment,
size_t fragment_size) OVERRIDE;
virtual void OnTraceBufferPercentFullReply(float percent_full) OVERRIDE;
virtual void OnEndTracingComplete() OVERRIDE;
};
#endif // BUILDING_CEF_SHARED
#endif // CEF_LIBCEF_DLL_CTOCPP_TRACE_CLIENT_CTOCPP_H_

View File

@ -22,6 +22,8 @@
#include "include/capi/cef_scheme_capi.h"
#include "include/cef_task.h"
#include "include/capi/cef_task_capi.h"
#include "include/cef_trace.h"
#include "include/capi/cef_trace_capi.h"
#include "include/cef_url.h"
#include "include/capi/cef_url_capi.h"
#include "include/cef_v8.h"
@ -88,6 +90,7 @@
#include "libcef_dll/ctocpp/scheme_handler_factory_ctocpp.h"
#include "libcef_dll/ctocpp/string_visitor_ctocpp.h"
#include "libcef_dll/ctocpp/task_ctocpp.h"
#include "libcef_dll/ctocpp/trace_client_ctocpp.h"
#include "libcef_dll/ctocpp/urlrequest_client_ctocpp.h"
#include "libcef_dll/ctocpp/v8accessor_ctocpp.h"
#include "libcef_dll/ctocpp/v8handler_ctocpp.h"
@ -212,6 +215,7 @@ CEF_EXPORT void cef_shutdown() {
DCHECK_EQ(CefStreamWriterCppToC::DebugObjCt, 0);
DCHECK_EQ(CefStringVisitorCToCpp::DebugObjCt, 0);
DCHECK_EQ(CefTaskCToCpp::DebugObjCt, 0);
DCHECK_EQ(CefTraceClientCToCpp::DebugObjCt, 0);
DCHECK_EQ(CefURLRequestClientCToCpp::DebugObjCt, 0);
DCHECK_EQ(CefURLRequestCppToC::DebugObjCt, 0);
DCHECK_EQ(CefV8AccessorCToCpp::DebugObjCt, 0);
@ -428,6 +432,41 @@ CEF_EXPORT int cef_post_delayed_task(cef_thread_id_t threadId,
return _retval;
}
CEF_EXPORT int cef_begin_tracing(struct _cef_trace_client_t* client,
const cef_string_t* categories) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Unverified params: client, categories
// Execute
bool _retval = CefBeginTracing(
CefTraceClientCToCpp::Wrap(client),
CefString(categories));
// Return type: bool
return _retval;
}
CEF_EXPORT int cef_get_trace_buffer_percent_full_async() {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
bool _retval = CefGetTraceBufferPercentFullAsync();
// Return type: bool
return _retval;
}
CEF_EXPORT int cef_end_tracing_async() {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
bool _retval = CefEndTracingAsync();
// Return type: bool
return _retval;
}
CEF_EXPORT int cef_parse_url(const cef_string_t* url,
struct _cef_urlparts_t* parts) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

View File

@ -22,6 +22,8 @@
#include "include/capi/cef_scheme_capi.h"
#include "include/cef_task.h"
#include "include/capi/cef_task_capi.h"
#include "include/cef_trace.h"
#include "include/capi/cef_trace_capi.h"
#include "include/cef_url.h"
#include "include/capi/cef_url_capi.h"
#include "include/cef_v8.h"
@ -54,6 +56,7 @@
#include "libcef_dll/cpptoc/scheme_handler_factory_cpptoc.h"
#include "libcef_dll/cpptoc/string_visitor_cpptoc.h"
#include "libcef_dll/cpptoc/task_cpptoc.h"
#include "libcef_dll/cpptoc/trace_client_cpptoc.h"
#include "libcef_dll/cpptoc/urlrequest_client_cpptoc.h"
#include "libcef_dll/cpptoc/v8accessor_cpptoc.h"
#include "libcef_dll/cpptoc/v8handler_cpptoc.h"
@ -204,6 +207,7 @@ CEF_GLOBAL void CefShutdown() {
DCHECK_EQ(CefStreamWriterCToCpp::DebugObjCt, 0);
DCHECK_EQ(CefStringVisitorCppToC::DebugObjCt, 0);
DCHECK_EQ(CefTaskCppToC::DebugObjCt, 0);
DCHECK_EQ(CefTraceClientCppToC::DebugObjCt, 0);
DCHECK_EQ(CefURLRequestCToCpp::DebugObjCt, 0);
DCHECK_EQ(CefURLRequestClientCppToC::DebugObjCt, 0);
DCHECK_EQ(CefV8AccessorCppToC::DebugObjCt, 0);
@ -411,6 +415,41 @@ CEF_GLOBAL bool CefPostDelayedTask(CefThreadId threadId,
return _retval?true:false;
}
CEF_GLOBAL bool CefBeginTracing(CefRefPtr<CefTraceClient> client,
const CefString& categories) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Unverified params: client, categories
// Execute
int _retval = cef_begin_tracing(
CefTraceClientCppToC::Wrap(client),
categories.GetStruct());
// Return type: bool
return _retval?true:false;
}
CEF_GLOBAL bool CefGetTraceBufferPercentFullAsync() {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
int _retval = cef_get_trace_buffer_percent_full_async();
// Return type: bool
return _retval?true:false;
}
CEF_GLOBAL bool CefEndTracingAsync() {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
int _retval = cef_end_tracing_async();
// Return type: bool
return _retval?true:false;
}
CEF_GLOBAL bool CefParseURL(const CefString& url, CefURLParts& parts) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

View File

@ -83,6 +83,8 @@ BEGIN
MENUITEM "Zoom In", ID_TESTS_ZOOM_IN
MENUITEM "Zoom Out", ID_TESTS_ZOOM_OUT
MENUITEM "Zoom Reset", ID_TESTS_ZOOM_RESET
MENUITEM "Begin Tracing", ID_TESTS_BEGIN_TRACING
MENUITEM "End Tracing", ID_TESTS_END_TRACING
END
END

View File

@ -190,6 +190,22 @@ gboolean ZoomResetActivated(GtkWidget* widget) {
return FALSE; // Don't stop this message.
}
// Callback for Debug > Begin Tracing menu item.
gboolean BeginTracingActivated(GtkWidget* widget) {
if (g_handler.get())
g_handler->BeginTracing();
return FALSE; // Don't stop this message.
}
// Callback for Debug > End Tracing menu item.
gboolean EndTracingActivated(GtkWidget* widget) {
if (g_handler.get())
g_handler->EndTracing();
return FALSE; // Don't stop this message.
}
// Callback for when you click the back button.
void BackButtonClicked(GtkButton* button) {
if (g_handler.get() && g_handler->GetBrowserId())
@ -283,6 +299,10 @@ GtkWidget* CreateMenuBar() {
G_CALLBACK(ZoomOutActivated));
AddMenuEntry(debug_menu, "Zoom Reset",
G_CALLBACK(ZoomResetActivated));
AddMenuEntry(debug_menu, "Begin Tracing",
G_CALLBACK(BeginTracingActivated));
AddMenuEntry(debug_menu, "End Tracing",
G_CALLBACK(EndTracingActivated));
return menu_bar;
}

View File

@ -207,6 +207,8 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
- (IBAction)testZoomIn:(id)sender;
- (IBAction)testZoomOut:(id)sender;
- (IBAction)testZoomReset:(id)sender;
- (IBAction)testBeginTracing:(id)sender;
- (IBAction)testEndTracing:(id)sender;
@end
@implementation ClientAppDelegate
@ -282,6 +284,12 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
[testMenu addItemWithTitle:@"Zoom Reset"
action:@selector(testZoomReset:)
keyEquivalent:@""];
[testMenu addItemWithTitle:@"Begin Tracing"
action:@selector(testBeginTracing:)
keyEquivalent:@""];
[testMenu addItemWithTitle:@"End Tracing"
action:@selector(testEndTracing:)
keyEquivalent:@""];
[testItem setSubmenu:testMenu];
[menubar addItem:testItem];
@ -474,6 +482,15 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
}
}
- (IBAction)testBeginTracing:(id)sender {
if (g_handler.get())
g_handler->BeginTracing();
}
- (IBAction)testEndTracing:(id)sender {
if (g_handler.get())
g_handler->EndTracing();
}
// Sent by the default notification center immediately before the application
// terminates.

View File

@ -444,6 +444,12 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
if (browser.get())
browser->GetHost()->SetZoomLevel(0.0);
return 0;
case ID_TESTS_BEGIN_TRACING:
g_handler->BeginTracing();
return 0;
case ID_TESTS_END_TRACING:
g_handler->EndTracing();
return 0;
}
break;
}

View File

@ -12,6 +12,7 @@
#include "include/cef_path_util.h"
#include "include/cef_process_util.h"
#include "include/cef_runnable.h"
#include "include/cef_trace.h"
#include "include/wrapper/cef_stream_resource_handler.h"
#include "cefclient/binding_test.h"
#include "cefclient/cefclient.h"
@ -487,6 +488,80 @@ void ClientHandler::LaunchExternalBrowser(const std::string& url) {
}
}
void ClientHandler::BeginTracing() {
if (CefCurrentlyOn(TID_UI)) {
class Client : public CefTraceClient,
public CefRunFileDialogCallback {
public:
explicit Client(CefRefPtr<ClientHandler> handler)
: handler_(handler),
trace_data_("{\"traceEvents\":["),
first_(true) {
}
virtual void OnTraceDataCollected(const char* fragment,
size_t fragment_size) OVERRIDE {
if (first_)
first_ = false;
else
trace_data_.append(",");
trace_data_.append(fragment, fragment_size);
}
virtual void OnEndTracingComplete() OVERRIDE {
REQUIRE_UI_THREAD();
trace_data_.append("]}");
static const char kDefaultFileName[] = "trace.txt";
std::string path = handler_->GetDownloadPath(kDefaultFileName);
if (path.empty())
path = kDefaultFileName;
handler_->GetBrowser()->GetHost()->RunFileDialog(
FILE_DIALOG_SAVE, CefString(), path, std::vector<CefString>(),
this);
}
virtual void OnFileDialogDismissed(
CefRefPtr<CefBrowserHost> browser_host,
const std::vector<CefString>& file_paths) OVERRIDE {
if (!file_paths.empty())
handler_->Save(file_paths.front(), trace_data_);
}
private:
CefRefPtr<ClientHandler> handler_;
std::string trace_data_;
bool first_;
IMPLEMENT_REFCOUNTING(Callback);
};
CefBeginTracing(new Client(this), CefString());
} else {
CefPostTask(TID_UI,
NewCefRunnableMethod(this, &ClientHandler::BeginTracing));
}
}
void ClientHandler::EndTracing() {
if (CefCurrentlyOn(TID_UI)) {
CefEndTracingAsync();
} else {
CefPostTask(TID_UI,
NewCefRunnableMethod(this, &ClientHandler::BeginTracing));
}
}
bool ClientHandler::Save(const std::string& path, const std::string& data) {
FILE* f = fopen(path.c_str(), "w");
if (!f)
return false;
fwrite(data.c_str(), data.size(), 1, f);
fclose(f);
return true;
}
// static
void ClientHandler::CreateProcessMessageDelegates(
ProcessMessageDelegateSet& delegates) {

View File

@ -214,6 +214,11 @@ class ClientHandler : public CefClient,
// Create an external browser window that loads the specified URL.
static void LaunchExternalBrowser(const std::string& url);
void BeginTracing();
void EndTracing();
bool Save(const std::string& path, const std::string& data);
protected:
void SetLoading(bool isLoading);
void SetNavState(bool canGoBack, bool canGoForward);

View File

@ -44,6 +44,8 @@
#define ID_TESTS_ZOOM_IN 32777
#define ID_TESTS_ZOOM_OUT 32778
#define ID_TESTS_ZOOM_RESET 32779
#define ID_TESTS_BEGIN_TRACING 32780
#define ID_TESTS_END_TRACING 32781
#define IDC_STATIC -1
#define IDS_BINDING 1000
#define IDS_DIALOGS 1001

View File

@ -0,0 +1,419 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "base/synchronization/waitable_event.h"
#include "include/cef_task.h"
#include "include/cef_trace.h"
#include "include/cef_trace_event.h"
#include "tests/unittests/test_handler.h"
#include "testing/gtest/include/gtest/gtest.h"
enum TracingTestType {
CEF_TRACE_EVENT0,
CEF_TRACE_EVENT1,
CEF_TRACE_EVENT2,
CEF_TRACE_EVENT_INSTANT0,
CEF_TRACE_EVENT_INSTANT1,
CEF_TRACE_EVENT_INSTANT2,
CEF_TRACE_EVENT_COPY_INSTANT0,
CEF_TRACE_EVENT_COPY_INSTANT1,
CEF_TRACE_EVENT_COPY_INSTANT2,
CEF_TRACE_EVENT_BEGIN0,
CEF_TRACE_EVENT_BEGIN1,
CEF_TRACE_EVENT_BEGIN2,
CEF_TRACE_EVENT_COPY_BEGIN0,
CEF_TRACE_EVENT_COPY_BEGIN1,
CEF_TRACE_EVENT_COPY_BEGIN2,
CEF_TRACE_EVENT_END0,
CEF_TRACE_EVENT_END1,
CEF_TRACE_EVENT_END2,
CEF_TRACE_EVENT_COPY_END0,
CEF_TRACE_EVENT_COPY_END1,
CEF_TRACE_EVENT_COPY_END2,
CEF_TRACE_EVENT_IF_LONGER_THAN0,
CEF_TRACE_EVENT_IF_LONGER_THAN1,
CEF_TRACE_EVENT_IF_LONGER_THAN2,
CEF_TRACE_COUNTER1,
CEF_TRACE_COPY_COUNTER1,
CEF_TRACE_COUNTER2,
CEF_TRACE_COPY_COUNTER2,
CEF_TRACE_COUNTER_ID1,
CEF_TRACE_COPY_COUNTER_ID1,
CEF_TRACE_COUNTER_ID2,
CEF_TRACE_COPY_COUNTER_ID2,
CEF_TRACE_EVENT_ASYNC_BEGIN0,
CEF_TRACE_EVENT_ASYNC_BEGIN1,
CEF_TRACE_EVENT_ASYNC_BEGIN2,
CEF_TRACE_EVENT_COPY_ASYNC_BEGIN0,
CEF_TRACE_EVENT_COPY_ASYNC_BEGIN1,
CEF_TRACE_EVENT_COPY_ASYNC_BEGIN2,
CEF_TRACE_EVENT_ASYNC_STEP0,
CEF_TRACE_EVENT_ASYNC_STEP1,
CEF_TRACE_EVENT_COPY_ASYNC_STEP0,
CEF_TRACE_EVENT_COPY_ASYNC_STEP1,
CEF_TRACE_EVENT_ASYNC_END0,
CEF_TRACE_EVENT_ASYNC_END1,
CEF_TRACE_EVENT_ASYNC_END2,
CEF_TRACE_EVENT_COPY_ASYNC_END0,
CEF_TRACE_EVENT_COPY_ASYNC_END1,
CEF_TRACE_EVENT_COPY_ASYNC_END2
};
const char kTraceTestCategory[] = "test_category";
// Used to test begin tracing on the UI thread.
class BeginTracingTask : public CefTask {
public:
explicit BeginTracingTask(CefRefPtr<CefTraceClient> client)
: client_(client) {
}
virtual void Execute(CefThreadId threadId) OVERRIDE {
EXPECT_TRUE(CefBeginTracing(client_, kTraceTestCategory));
}
private:
virtual ~BeginTracingTask() {}
CefRefPtr<CefTraceClient> client_;
IMPLEMENT_REFCOUNTING(BeginTracingTask);
};
// Used to test end tracing on the UI thread.
class EndTracingTask : public CefTask {
public:
EndTracingTask() {}
virtual void Execute(CefThreadId threadId) OVERRIDE {
EXPECT_TRUE(CefEndTracingAsync());
}
private:
virtual ~EndTracingTask() {}
IMPLEMENT_REFCOUNTING(EndTracingTask);
};
class TracingTestHandler : public CefTraceClient {
public:
TracingTestHandler(TracingTestType type, const char* trace_type)
: completion_event_(true, false),
trace_type_(trace_type),
type_(type) {
}
virtual void OnTraceDataCollected(const char* fragment,
size_t fragment_size) OVERRIDE {
if (!trace_data_.empty())
trace_data_.append(",");
trace_data_.append(fragment, fragment_size);
}
virtual void OnEndTracingComplete() OVERRIDE {
EXPECT_TRUE(!trace_data_.empty());
EXPECT_TRUE(trace_type_ != NULL);
EXPECT_TRUE(strstr(trace_data_.c_str(), trace_type_) != NULL);
completion_event_.Signal();
}
void RunTest() {
// BeginTracing works only on the UI thread.
CefPostTask(TID_UI, new BeginTracingTask(this));
WaitForUIThread();
switch (type_) {
case CEF_TRACE_EVENT0:
CEF_TRACE_EVENT0(kTraceTestCategory, "CEF_TRACE_EVENT0");
break;
case CEF_TRACE_EVENT1:
CEF_TRACE_EVENT1(kTraceTestCategory, "CEF_TRACE_EVENT1", "arg1", 1);
break;
case CEF_TRACE_EVENT2:
CEF_TRACE_EVENT2(kTraceTestCategory, "CEF_TRACE_EVENT2", "arg1", 1,
"arg2", 2);
break;
case CEF_TRACE_EVENT_INSTANT0:
CEF_TRACE_EVENT_INSTANT0(kTraceTestCategory,
"CEF_TRACE_EVENT_INSTANT0");
break;
case CEF_TRACE_EVENT_INSTANT1:
CEF_TRACE_EVENT_INSTANT1(kTraceTestCategory, "CEF_TRACE_EVENT_INSTANT1",
"arg1", 1);
break;
case CEF_TRACE_EVENT_INSTANT2:
CEF_TRACE_EVENT_INSTANT2(kTraceTestCategory, "CEF_TRACE_EVENT_INSTANT2",
"arg1", 1, "arg2", 2);
break;
case CEF_TRACE_EVENT_COPY_INSTANT0:
CEF_TRACE_EVENT_COPY_INSTANT0(kTraceTestCategory,
"CEF_TRACE_EVENT_COPY_INSTANT0");
break;
case CEF_TRACE_EVENT_COPY_INSTANT1:
CEF_TRACE_EVENT_COPY_INSTANT1(kTraceTestCategory,
"CEF_TRACE_EVENT_COPY_INSTANT1",
"arg1", 1);
break;
case CEF_TRACE_EVENT_COPY_INSTANT2:
CEF_TRACE_EVENT_COPY_INSTANT2(kTraceTestCategory,
"CEF_TRACE_EVENT_COPY_INSTANT2",
"arg1", 1, "arg2", 2);
break;
case CEF_TRACE_EVENT_BEGIN0:
CEF_TRACE_EVENT_BEGIN0(kTraceTestCategory, "CEF_TRACE_EVENT_BEGIN0");
break;
case CEF_TRACE_EVENT_BEGIN1:
CEF_TRACE_EVENT_BEGIN1(kTraceTestCategory, "CEF_TRACE_EVENT_BEGIN1",
"arg1", 1);
break;
case CEF_TRACE_EVENT_BEGIN2:
CEF_TRACE_EVENT_BEGIN2(kTraceTestCategory, "CEF_TRACE_EVENT_BEGIN2",
"arg1", 1, "arg2", 2);
break;
case CEF_TRACE_EVENT_COPY_BEGIN0:
CEF_TRACE_EVENT_COPY_BEGIN0(kTraceTestCategory,
"CEF_TRACE_EVENT_COPY_BEGIN0");
break;
case CEF_TRACE_EVENT_COPY_BEGIN1:
CEF_TRACE_EVENT_COPY_BEGIN1(kTraceTestCategory,
"CEF_TRACE_EVENT_COPY_BEGIN1",
"arg1", 1);
break;
case CEF_TRACE_EVENT_COPY_BEGIN2:
CEF_TRACE_EVENT_COPY_BEGIN2(kTraceTestCategory,
"CEF_TRACE_EVENT_COPY_BEGIN2",
"arg1", 1, "arg2", 2);
break;
case CEF_TRACE_EVENT_END0:
CEF_TRACE_EVENT_END0(kTraceTestCategory, "CEF_TRACE_EVENT_END0");
break;
case CEF_TRACE_EVENT_END1:
CEF_TRACE_EVENT_END1(kTraceTestCategory, "CEF_TRACE_EVENT_END1",
"arg1", 1);
break;
case CEF_TRACE_EVENT_END2:
CEF_TRACE_EVENT_END2(kTraceTestCategory, "CEF_TRACE_EVENT_END2",
"arg1", 1, "arg2", 2);
break;
case CEF_TRACE_EVENT_COPY_END0:
CEF_TRACE_EVENT_COPY_END0(kTraceTestCategory,
"CEF_TRACE_EVENT_COPY_END0");
break;
case CEF_TRACE_EVENT_COPY_END1:
CEF_TRACE_EVENT_COPY_END1(kTraceTestCategory,
"CEF_TRACE_EVENT_COPY_END1", "arg1", 1);
break;
case CEF_TRACE_EVENT_COPY_END2:
CEF_TRACE_EVENT_COPY_END2(kTraceTestCategory,
"CEF_TRACE_EVENT_COPY_END2", "arg1", 1,
"arg2", 2);
break;
case CEF_TRACE_EVENT_IF_LONGER_THAN0:
CEF_TRACE_EVENT_IF_LONGER_THAN0(0, kTraceTestCategory,
"CEF_TRACE_EVENT_IF_LONGER_THAN0");
break;
case CEF_TRACE_EVENT_IF_LONGER_THAN1:
CEF_TRACE_EVENT_IF_LONGER_THAN1(0, kTraceTestCategory,
"CEF_TRACE_EVENT_IF_LONGER_THAN1",
"arg1", 1);
case CEF_TRACE_EVENT_IF_LONGER_THAN2:
CEF_TRACE_EVENT_IF_LONGER_THAN2(0, kTraceTestCategory,
"CEF_TRACE_EVENT_IF_LONGER_THAN2",
"arg1", 1, "arg2", 2);
break;
case CEF_TRACE_COUNTER1:
CEF_TRACE_COUNTER1(kTraceTestCategory, "CEF_TRACE_COUNTER1", 5);
break;
case CEF_TRACE_COPY_COUNTER1:
CEF_TRACE_COPY_COUNTER1(kTraceTestCategory, "CEF_TRACE_COPY_COUNTER1",
5);
break;
case CEF_TRACE_COUNTER2:
CEF_TRACE_COUNTER2(kTraceTestCategory, "CEF_TRACE_COUNTER2", "val1", 5,
"val2", 10);
break;
case CEF_TRACE_COPY_COUNTER2:
CEF_TRACE_COPY_COUNTER2(kTraceTestCategory, "CEF_TRACE_COPY_COUNTER2",
"val1", 5, "val2", 10);
break;
case CEF_TRACE_COUNTER_ID1:
CEF_TRACE_COUNTER_ID1(kTraceTestCategory, "CEF_TRACE_COUNTER_ID1", 100,
5);
break;
case CEF_TRACE_COPY_COUNTER_ID1:
CEF_TRACE_COPY_COUNTER_ID1(kTraceTestCategory,
"CEF_TRACE_COPY_COUNTER_ID1", 100, 5);
break;
case CEF_TRACE_COUNTER_ID2:
CEF_TRACE_COUNTER_ID2(kTraceTestCategory, "CEF_TRACE_COUNTER_ID2", 100,
"val1", 5, "val2", 10);
break;
case CEF_TRACE_COPY_COUNTER_ID2:
CEF_TRACE_COPY_COUNTER_ID2(kTraceTestCategory,
"CEF_TRACE_COPY_COUNTER_ID2", 100,
"val1", 5, "val2", 10);
break;
case CEF_TRACE_EVENT_ASYNC_BEGIN0:
CEF_TRACE_EVENT_ASYNC_BEGIN0(kTraceTestCategory,
"CEF_TRACE_EVENT_ASYNC_BEGIN0", 100);
break;
case CEF_TRACE_EVENT_ASYNC_BEGIN1:
CEF_TRACE_EVENT_ASYNC_BEGIN1(kTraceTestCategory,
"CEF_TRACE_EVENT_ASYNC_BEGIN1", 100,
"arg1", 1);
break;
case CEF_TRACE_EVENT_ASYNC_BEGIN2:
CEF_TRACE_EVENT_ASYNC_BEGIN2(kTraceTestCategory,
"CEF_TRACE_EVENT_ASYNC_BEGIN2",
100, "arg1", 1, "arg2", 2);
break;
case CEF_TRACE_EVENT_COPY_ASYNC_BEGIN0:
CEF_TRACE_EVENT_COPY_ASYNC_BEGIN0(kTraceTestCategory,
"CEF_TRACE_EVENT_COPY_ASYNC_BEGIN0",
100);
break;
case CEF_TRACE_EVENT_COPY_ASYNC_BEGIN1:
CEF_TRACE_EVENT_COPY_ASYNC_BEGIN1(kTraceTestCategory,
"CEF_TRACE_EVENT_COPY_ASYNC_BEGIN1",
100, "arg1", 1);
break;
case CEF_TRACE_EVENT_COPY_ASYNC_BEGIN2:
CEF_TRACE_EVENT_COPY_ASYNC_BEGIN2(kTraceTestCategory,
"CEF_TRACE_EVENT_COPY_ASYNC_BEGIN2",
100, "arg1", 1, "arg2", 2);
break;
case CEF_TRACE_EVENT_ASYNC_STEP0:
CEF_TRACE_EVENT_ASYNC_STEP0(kTraceTestCategory,
"CEF_TRACE_EVENT_ASYNC_STEP0", 100,
1000);
break;
case CEF_TRACE_EVENT_ASYNC_STEP1:
CEF_TRACE_EVENT_ASYNC_STEP1(kTraceTestCategory,
"CEF_TRACE_EVENT_ASYNC_STEP1", 100,
1000, "arg1", 1);
break;
case CEF_TRACE_EVENT_COPY_ASYNC_STEP0:
CEF_TRACE_EVENT_COPY_ASYNC_STEP0(kTraceTestCategory,
"CEF_TRACE_EVENT_COPY_ASYNC_STEP0",
100, 1000);
break;
case CEF_TRACE_EVENT_COPY_ASYNC_STEP1:
CEF_TRACE_EVENT_COPY_ASYNC_STEP1(kTraceTestCategory,
"CEF_TRACE_EVENT_COPY_ASYNC_STEP1",
100, 1000, "arg1", 1);
break;
case CEF_TRACE_EVENT_ASYNC_END0:
CEF_TRACE_EVENT_ASYNC_END0(kTraceTestCategory,
"CEF_TRACE_EVENT_ASYNC_END0", 100);
break;
case CEF_TRACE_EVENT_ASYNC_END1:
CEF_TRACE_EVENT_ASYNC_END1(kTraceTestCategory,
"CEF_TRACE_EVENT_ASYNC_END1", 100,
"arg1", 1);
break;
case CEF_TRACE_EVENT_ASYNC_END2:
CEF_TRACE_EVENT_ASYNC_END2(kTraceTestCategory,
"CEF_TRACE_EVENT_ASYNC_END2", 100,
"arg1", 1, "arg2", 2);
case CEF_TRACE_EVENT_COPY_ASYNC_END0:
CEF_TRACE_EVENT_COPY_ASYNC_END0(kTraceTestCategory,
"CEF_TRACE_EVENT_COPY_ASYNC_END0",
100);
break;
case CEF_TRACE_EVENT_COPY_ASYNC_END1:
CEF_TRACE_EVENT_COPY_ASYNC_END1(kTraceTestCategory,
"CEF_TRACE_EVENT_COPY_ASYNC_END1",
100, "arg1", 1);
break;
case CEF_TRACE_EVENT_COPY_ASYNC_END2:
CEF_TRACE_EVENT_COPY_ASYNC_END2(kTraceTestCategory,
"CEF_TRACE_EVENT_COPY_ASYNC_END2",
100, "arg1", 1, "arg2", 2);
break;
}
// Run EndTracingAsync on the UI thread.
CefPostTask(TID_UI, new EndTracingTask());
WaitForUIThread();
}
void ExecuteTest() {
// Run the test.
RunTest();
// Wait for the test to complete.
completion_event_.Wait();
}
private:
virtual ~TracingTestHandler() {}
// Handle used to notify when the test is complete.
base::WaitableEvent completion_event_;
const char* trace_type_;
TracingTestType type_;
std::string trace_data_;
IMPLEMENT_REFCOUNTING(TracingTestHandler);
};
// Helper for defining tracing tests.
#define TRACING_TEST(name, test_type) \
TEST(TracingTest, name) { \
CefRefPtr<TracingTestHandler> handler = \
new TracingTestHandler(test_type, #test_type); \
handler->ExecuteTest(); \
}
// Define the tests.
TRACING_TEST(TraceEvent0, CEF_TRACE_EVENT0);
TRACING_TEST(TraceEvent1, CEF_TRACE_EVENT1);
TRACING_TEST(TraceEvent2, CEF_TRACE_EVENT2);
TRACING_TEST(TraceEventInstant0, CEF_TRACE_EVENT_INSTANT0);
TRACING_TEST(TraceEventInstant1, CEF_TRACE_EVENT_INSTANT1);
TRACING_TEST(TraceEventInstant2, CEF_TRACE_EVENT_INSTANT2);
TRACING_TEST(TraceEventCopyInstant0, CEF_TRACE_EVENT_COPY_INSTANT0);
TRACING_TEST(TraceEventCopyInstant1, CEF_TRACE_EVENT_COPY_INSTANT1);
TRACING_TEST(TraceEventCopyInstant2, CEF_TRACE_EVENT_COPY_INSTANT2);
TRACING_TEST(TraceEventBegin0, CEF_TRACE_EVENT_BEGIN0);
TRACING_TEST(TraceEventBegin1, CEF_TRACE_EVENT_BEGIN1);
TRACING_TEST(TraceEventBegin2, CEF_TRACE_EVENT_BEGIN2);
TRACING_TEST(TraceEventCopyBegin0, CEF_TRACE_EVENT_COPY_BEGIN0);
TRACING_TEST(TraceEventCopyBegin1, CEF_TRACE_EVENT_COPY_BEGIN1);
TRACING_TEST(TraceEventCopyBegin2, CEF_TRACE_EVENT_COPY_BEGIN2);
TRACING_TEST(TraceEventEnd0, CEF_TRACE_EVENT_END0);
TRACING_TEST(TraceEventEnd1, CEF_TRACE_EVENT_END1);
TRACING_TEST(TraceEventEnd2, CEF_TRACE_EVENT_END2);
TRACING_TEST(TraceEventCopyEnd0, CEF_TRACE_EVENT_COPY_END0);
TRACING_TEST(TraceEventCopyEnd1, CEF_TRACE_EVENT_COPY_END1);
TRACING_TEST(TraceEventCopyEnd2, CEF_TRACE_EVENT_COPY_END1);
TRACING_TEST(TraceEventIfLongerThan0, CEF_TRACE_EVENT_IF_LONGER_THAN0);
TRACING_TEST(TraceEventIfLongerThan1, CEF_TRACE_EVENT_IF_LONGER_THAN1);
TRACING_TEST(TraceEventIfLongerThan2, CEF_TRACE_EVENT_IF_LONGER_THAN2);
TRACING_TEST(TraceCounter1, CEF_TRACE_COUNTER1);
TRACING_TEST(TraceCopyCounter1, CEF_TRACE_COPY_COUNTER1);
TRACING_TEST(TraceCounter2, CEF_TRACE_COUNTER2);
TRACING_TEST(TraceCopyCounter2, CEF_TRACE_COPY_COUNTER2);
TRACING_TEST(TraceCounterId1, CEF_TRACE_COUNTER_ID1);
TRACING_TEST(TraceCopyCounterId1, CEF_TRACE_COPY_COUNTER_ID1);
TRACING_TEST(TraceCounterId2, CEF_TRACE_COUNTER_ID2);
TRACING_TEST(TraceCopyCounterId2, CEF_TRACE_COPY_COUNTER_ID1);
TRACING_TEST(TraceTraceEventAsyncBegin0, CEF_TRACE_EVENT_ASYNC_BEGIN0);
TRACING_TEST(TraceTraceEventAsyncBegin1, CEF_TRACE_EVENT_ASYNC_BEGIN1);
TRACING_TEST(TraceTraceEventAsyncBegin2, CEF_TRACE_EVENT_ASYNC_BEGIN2);
TRACING_TEST(TraceTraceEventCopyAsyncBegin0,
CEF_TRACE_EVENT_COPY_ASYNC_BEGIN0);
TRACING_TEST(TraceTraceEventCopyAsyncBegin1,
CEF_TRACE_EVENT_COPY_ASYNC_BEGIN1);
TRACING_TEST(TraceTraceEventCopyAsyncBegin2,
CEF_TRACE_EVENT_COPY_ASYNC_BEGIN2);
TRACING_TEST(TraceTraceEventAsyncStep0, CEF_TRACE_EVENT_ASYNC_STEP0);
TRACING_TEST(TraceTraceEventAsyncStep1, CEF_TRACE_EVENT_ASYNC_STEP1);
TRACING_TEST(TraceEventCopyAsyncStep0, CEF_TRACE_EVENT_COPY_ASYNC_STEP0);
TRACING_TEST(TraceEventCopyAsyncStep1, CEF_TRACE_EVENT_COPY_ASYNC_STEP1);
TRACING_TEST(TraceEventAsyncEnd0, CEF_TRACE_EVENT_ASYNC_END0);
TRACING_TEST(TraceEventAsyncEnd1, CEF_TRACE_EVENT_ASYNC_END1);
TRACING_TEST(TraceEventAsyncEnd2, CEF_TRACE_EVENT_ASYNC_END2);
TRACING_TEST(TraceEventCopyAsyncEnd0, CEF_TRACE_EVENT_COPY_ASYNC_END0);

View File

@ -364,12 +364,14 @@ _simpletypes = {
'int64' : ['int64', '0'],
'uint64' : ['uint64', '0'],
'double' : ['double', '0'],
'float' : ['float', '0'],
'long' : ['long', '0'],
'unsigned long' : ['unsigned long', '0'],
'long long' : ['long long', '0'],
'size_t' : ['size_t', '0'],
'time_t' : ['time_t', '0'],
'bool' : ['int', '0'],
'char': ['char', '0'],
'char* const': ['char* const', 'NULL'],
'CefCursorHandle' : ['cef_cursor_handle_t', 'NULL'],
'CefEventHandle' : ['cef_event_handle_t', 'NULL'],

View File

@ -69,6 +69,11 @@ else:
dir = patch['path']
patchObj = from_file(file)
patchObj.apply(dir)
if 'note' in patch:
separator = '-' * 79 + '\n'
sys.stderr.write(separator)
sys.stderr.write('NOTE: '+patch['note']+'\n')
sys.stderr.write(separator)
# read the current include file, if any
incfile = patchdir + 'patch_state.h'