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() { |