Chromium Code Reviews| Index: ppapi/proxy/plugin_main_nacl.cc |
| diff --git a/ppapi/proxy/plugin_main_nacl.cc b/ppapi/proxy/plugin_main_nacl.cc |
| index 8077bdf64566151062168f82c393d0c235392480..e94ddef9297bbedfb05c3892a654bd5b4781ee8e 100644 |
| --- a/ppapi/proxy/plugin_main_nacl.cc |
| +++ b/ppapi/proxy/plugin_main_nacl.cc |
| @@ -11,9 +11,11 @@ |
| // IPC_MESSAGE_MACROS_LOG_ENABLED so ppapi_messages.h will generate the |
| // ViewMsgLog et al. functions. |
| +#include "base/debug/trace_event.h" |
| #include "base/message_loop.h" |
| #include "base/synchronization/waitable_event.h" |
| #include "base/threading/thread.h" |
| +#include "content/components/tracing/tracing_messages.h" |
| #include "ipc/ipc_channel_handle.h" |
| #include "ipc/ipc_logging.h" |
| #include "ipc/ipc_message.h" |
| @@ -43,6 +45,7 @@ LogFunctionMap g_log_function_mapping; |
| // defined in sel_main_chrome.h |
| #define NACL_IPC_FD 6 |
| +using base::debug::TraceLog; |
| using ppapi::proxy::PluginDispatcher; |
| using ppapi::proxy::PluginGlobals; |
| using ppapi::proxy::PluginProxyDelegate; |
| @@ -51,6 +54,135 @@ using ppapi::proxy::SerializedHandle; |
| namespace { |
| +// This class sends and receives trace messages on child processes. |
|
bbudge
2012/12/05 02:22:28
This file has a bunch of different things already.
|
| +class PpapiTraceMessageFilter : public IPC::ChannelProxy::MessageFilter { |
| + public: |
| + PpapiTraceMessageFilter(base::MessageLoopProxy* ipc_message_loop); |
| + |
| + // IPC::ChannelProxy::MessageFilter implementation. |
| + virtual void OnFilterAdded(IPC::Channel* channel) OVERRIDE; |
| + virtual void OnFilterRemoved() OVERRIDE; |
| + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; |
| + |
| + protected: |
| + virtual ~PpapiTraceMessageFilter(); |
| + |
| + private: |
| + // Message handlers. |
| + void OnBeginTracing(const std::vector<std::string>& included_categories, |
| + const std::vector<std::string>& excluded_categories, |
| + base::TimeTicks browser_time); |
| + void OnEndTracing(); |
| + void OnGetTraceBufferPercentFull(); |
| + void OnSetWatchEvent(const std::string& category_name, |
| + const std::string& event_name); |
| + void OnCancelWatchEvent(); |
| + |
| + // Callback from trace subsystem. |
| + void OnTraceDataCollected( |
| + const scoped_refptr<base::RefCountedString>& events_str_ptr); |
| + void OnTraceNotification(int notification); |
| + |
| + IPC::Channel* channel_; |
| + base::MessageLoopProxy* ipc_message_loop_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(PpapiTraceMessageFilter); |
| +}; |
| + |
| +PpapiTraceMessageFilter::PpapiTraceMessageFilter( |
| + base::MessageLoopProxy* ipc_message_loop) |
| + : channel_(NULL), |
| + ipc_message_loop_(ipc_message_loop) {} |
| + |
| +void PpapiTraceMessageFilter::OnFilterAdded(IPC::Channel* channel) { |
| + channel_ = channel; |
| + TraceLog::GetInstance()->SetNotificationCallback( |
| + base::Bind(&PpapiTraceMessageFilter::OnTraceNotification, this)); |
| + channel_->Send(new TracingHostMsg_ChildSupportsTracing()); |
| +} |
| + |
| +void PpapiTraceMessageFilter::OnFilterRemoved() { |
| + TraceLog::GetInstance()->SetNotificationCallback( |
| + TraceLog::NotificationCallback()); |
| +} |
| + |
| +bool PpapiTraceMessageFilter::OnMessageReceived(const IPC::Message& message) { |
| + bool handled = true; |
| + IPC_BEGIN_MESSAGE_MAP(PpapiTraceMessageFilter, message) |
| + IPC_MESSAGE_HANDLER(TracingMsg_BeginTracing, OnBeginTracing) |
| + IPC_MESSAGE_HANDLER(TracingMsg_EndTracing, OnEndTracing) |
| + IPC_MESSAGE_HANDLER(TracingMsg_GetTraceBufferPercentFull, |
| + OnGetTraceBufferPercentFull) |
| + IPC_MESSAGE_HANDLER(TracingMsg_SetWatchEvent, OnSetWatchEvent) |
| + IPC_MESSAGE_HANDLER(TracingMsg_CancelWatchEvent, OnCancelWatchEvent) |
| + IPC_MESSAGE_UNHANDLED(handled = false) |
| + IPC_END_MESSAGE_MAP() |
| + return handled; |
| +} |
| + |
| +PpapiTraceMessageFilter::~PpapiTraceMessageFilter() {} |
| + |
| +void PpapiTraceMessageFilter::OnBeginTracing( |
| + const std::vector<std::string>& included_categories, |
| + const std::vector<std::string>& excluded_categories, |
| + base::TimeTicks browser_time) { |
| + // NaCl and system times are offset by a bit, so subtract some time from |
| + // the captured timestamps. The value might be off by a bit due to messaging |
| + // latency. |
| + base::TimeDelta time_offset = base::TimeTicks::NowFromSystemTraceTime() - |
| + browser_time; |
| + TraceLog::GetInstance()->SetTimeOffset(time_offset); |
| + TraceLog::GetInstance()->SetEnabled(included_categories, |
| + excluded_categories); |
| +} |
| + |
| +void PpapiTraceMessageFilter::OnEndTracing() { |
| + TraceLog::GetInstance()->SetDisabled(); |
| + |
| + // Flush will generate one or more callbacks to OnTraceDataCollected. It's |
| + // important that the last OnTraceDataCollected gets called before |
| + // EndTracingAck below. We are already on the IO thread, so the |
| + // OnTraceDataCollected calls will not be deferred. |
| + TraceLog::GetInstance()->Flush( |
| + base::Bind(&PpapiTraceMessageFilter::OnTraceDataCollected, this)); |
| + |
| + std::vector<std::string> categories; |
| + TraceLog::GetInstance()->GetKnownCategories(&categories); |
| + channel_->Send(new TracingHostMsg_EndTracingAck(categories)); |
| +} |
| + |
| +void PpapiTraceMessageFilter::OnGetTraceBufferPercentFull() { |
| + float bpf = TraceLog::GetInstance()->GetBufferPercentFull(); |
| + |
| + channel_->Send(new TracingHostMsg_TraceBufferPercentFullReply(bpf)); |
| +} |
| + |
| +void PpapiTraceMessageFilter::OnSetWatchEvent(const std::string& category_name, |
| + const std::string& event_name) { |
| + TraceLog::GetInstance()->SetWatchEvent(category_name.c_str(), |
| + event_name.c_str()); |
| +} |
| + |
| +void PpapiTraceMessageFilter::OnCancelWatchEvent() { |
| + TraceLog::GetInstance()->CancelWatchEvent(); |
| +} |
| + |
| +void PpapiTraceMessageFilter::OnTraceDataCollected( |
| + const scoped_refptr<base::RefCountedString>& events_str_ptr) { |
| + channel_->Send(new TracingHostMsg_TraceDataCollected( |
| + events_str_ptr->data())); |
| +} |
| + |
| +void PpapiTraceMessageFilter::OnTraceNotification(int notification) { |
| + if (!ipc_message_loop_->BelongsToCurrentThread()) { |
| + ipc_message_loop_->PostTask(FROM_HERE, |
| + base::Bind(&PpapiTraceMessageFilter::OnTraceNotification, this, |
| + notification)); |
| + return; |
| + } |
| + channel_->Send(new TracingHostMsg_TraceNotification(notification)); |
| +} |
| + |
| // This class manages communication between the plugin and the browser, and |
| // manages the PluginDispatcher instances for communication between the plugin |
| // and the renderer. |
| @@ -101,6 +233,7 @@ PpapiDispatcher::PpapiDispatcher(scoped_refptr<base::MessageLoopProxy> io_loop) |
| IPC::ChannelHandle channel_handle( |
| "NaCl IPC", base::FileDescriptor(NACL_IPC_FD, false)); |
| InitWithChannel(this, channel_handle, false); // Channel is server. |
| + channel()->AddFilter(new PpapiTraceMessageFilter(message_loop_)); |
| } |
| base::MessageLoopProxy* PpapiDispatcher::GetIPCMessageLoop() { |