Home | History | Annotate | Download | only in tracing
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "components/tracing/child_trace_message_filter.h"
      6 
      7 #include "base/debug/trace_event.h"
      8 #include "base/message_loop/message_loop_proxy.h"
      9 #include "components/tracing/tracing_messages.h"
     10 #include "ipc/ipc_channel.h"
     11 
     12 using base::debug::TraceLog;
     13 
     14 namespace tracing {
     15 
     16 ChildTraceMessageFilter::ChildTraceMessageFilter(
     17     base::MessageLoopProxy* ipc_message_loop)
     18     : sender_(NULL),
     19       ipc_message_loop_(ipc_message_loop) {}
     20 
     21 void ChildTraceMessageFilter::OnFilterAdded(IPC::Sender* sender) {
     22   sender_ = sender;
     23   sender_->Send(new TracingHostMsg_ChildSupportsTracing());
     24 }
     25 
     26 void ChildTraceMessageFilter::OnFilterRemoved() {
     27   sender_ = NULL;
     28 }
     29 
     30 bool ChildTraceMessageFilter::OnMessageReceived(const IPC::Message& message) {
     31   bool handled = true;
     32   IPC_BEGIN_MESSAGE_MAP(ChildTraceMessageFilter, message)
     33     IPC_MESSAGE_HANDLER(TracingMsg_BeginTracing, OnBeginTracing)
     34     IPC_MESSAGE_HANDLER(TracingMsg_EndTracing, OnEndTracing)
     35     IPC_MESSAGE_HANDLER(TracingMsg_EnableMonitoring, OnEnableMonitoring)
     36     IPC_MESSAGE_HANDLER(TracingMsg_DisableMonitoring, OnDisableMonitoring)
     37     IPC_MESSAGE_HANDLER(TracingMsg_CaptureMonitoringSnapshot,
     38                         OnCaptureMonitoringSnapshot)
     39     IPC_MESSAGE_HANDLER(TracingMsg_GetTraceBufferPercentFull,
     40                         OnGetTraceBufferPercentFull)
     41     IPC_MESSAGE_HANDLER(TracingMsg_SetWatchEvent, OnSetWatchEvent)
     42     IPC_MESSAGE_HANDLER(TracingMsg_CancelWatchEvent, OnCancelWatchEvent)
     43     IPC_MESSAGE_UNHANDLED(handled = false)
     44   IPC_END_MESSAGE_MAP()
     45   return handled;
     46 }
     47 
     48 ChildTraceMessageFilter::~ChildTraceMessageFilter() {}
     49 
     50 void ChildTraceMessageFilter::OnBeginTracing(
     51     const std::string& category_filter_str,
     52     base::TimeTicks browser_time,
     53     const std::string& options) {
     54 #if defined(__native_client__)
     55   // NaCl and system times are offset by a bit, so subtract some time from
     56   // the captured timestamps. The value might be off by a bit due to messaging
     57   // latency.
     58   base::TimeDelta time_offset = base::TimeTicks::NowFromSystemTraceTime() -
     59       browser_time;
     60   TraceLog::GetInstance()->SetTimeOffset(time_offset);
     61 #endif
     62   base::debug::TraceOptions trace_options;
     63   trace_options.SetFromString(options);
     64   TraceLog::GetInstance()->SetEnabled(
     65       base::debug::CategoryFilter(category_filter_str),
     66       base::debug::TraceLog::RECORDING_MODE,
     67       trace_options);
     68 }
     69 
     70 void ChildTraceMessageFilter::OnEndTracing() {
     71   TraceLog::GetInstance()->SetDisabled();
     72 
     73   // Flush will generate one or more callbacks to OnTraceDataCollected
     74   // synchronously or asynchronously. EndTracingAck will be sent in the last
     75   // OnTraceDataCollected. We are already on the IO thread, so the
     76   // OnTraceDataCollected calls will not be deferred.
     77   TraceLog::GetInstance()->Flush(
     78       base::Bind(&ChildTraceMessageFilter::OnTraceDataCollected, this));
     79 }
     80 
     81 void ChildTraceMessageFilter::OnEnableMonitoring(
     82     const std::string& category_filter_str,
     83     base::TimeTicks browser_time,
     84     const std::string& options) {
     85   base::debug::TraceOptions trace_options;
     86   trace_options.SetFromString(options);
     87   TraceLog::GetInstance()->SetEnabled(
     88       base::debug::CategoryFilter(category_filter_str),
     89       base::debug::TraceLog::MONITORING_MODE,
     90       trace_options);
     91 }
     92 
     93 void ChildTraceMessageFilter::OnDisableMonitoring() {
     94   TraceLog::GetInstance()->SetDisabled();
     95 }
     96 
     97 void ChildTraceMessageFilter::OnCaptureMonitoringSnapshot() {
     98   // Flush will generate one or more callbacks to
     99   // OnMonitoringTraceDataCollected. It's important that the last
    100   // OnMonitoringTraceDataCollected gets called before
    101   // CaptureMonitoringSnapshotAck below. We are already on the IO thread,
    102   // so the OnMonitoringTraceDataCollected calls will not be deferred.
    103   TraceLog::GetInstance()->FlushButLeaveBufferIntact(
    104       base::Bind(&ChildTraceMessageFilter::OnMonitoringTraceDataCollected,
    105                  this));
    106 }
    107 
    108 void ChildTraceMessageFilter::OnGetTraceBufferPercentFull() {
    109   float bpf = TraceLog::GetInstance()->GetBufferPercentFull();
    110 
    111   sender_->Send(new TracingHostMsg_TraceBufferPercentFullReply(bpf));
    112 }
    113 
    114 void ChildTraceMessageFilter::OnSetWatchEvent(const std::string& category_name,
    115                                               const std::string& event_name) {
    116   TraceLog::GetInstance()->SetWatchEvent(
    117       category_name, event_name,
    118       base::Bind(&ChildTraceMessageFilter::OnWatchEventMatched, this));
    119 }
    120 
    121 void ChildTraceMessageFilter::OnCancelWatchEvent() {
    122   TraceLog::GetInstance()->CancelWatchEvent();
    123 }
    124 
    125 void ChildTraceMessageFilter::OnWatchEventMatched() {
    126   if (!ipc_message_loop_->BelongsToCurrentThread()) {
    127     ipc_message_loop_->PostTask(FROM_HERE,
    128         base::Bind(&ChildTraceMessageFilter::OnWatchEventMatched, this));
    129     return;
    130   }
    131   sender_->Send(new TracingHostMsg_WatchEventMatched);
    132 }
    133 
    134 void ChildTraceMessageFilter::OnTraceDataCollected(
    135     const scoped_refptr<base::RefCountedString>& events_str_ptr,
    136     bool has_more_events) {
    137   if (!ipc_message_loop_->BelongsToCurrentThread()) {
    138     ipc_message_loop_->PostTask(FROM_HERE,
    139         base::Bind(&ChildTraceMessageFilter::OnTraceDataCollected, this,
    140                    events_str_ptr, has_more_events));
    141     return;
    142   }
    143   if (events_str_ptr->data().size()) {
    144     sender_->Send(new TracingHostMsg_TraceDataCollected(
    145         events_str_ptr->data()));
    146   }
    147   if (!has_more_events) {
    148     std::vector<std::string> category_groups;
    149     TraceLog::GetInstance()->GetKnownCategoryGroups(&category_groups);
    150     sender_->Send(new TracingHostMsg_EndTracingAck(category_groups));
    151   }
    152 }
    153 
    154 void ChildTraceMessageFilter::OnMonitoringTraceDataCollected(
    155      const scoped_refptr<base::RefCountedString>& events_str_ptr,
    156      bool has_more_events) {
    157   if (!ipc_message_loop_->BelongsToCurrentThread()) {
    158     ipc_message_loop_->PostTask(FROM_HERE,
    159         base::Bind(&ChildTraceMessageFilter::
    160                    OnMonitoringTraceDataCollected,
    161                    this,
    162                    events_str_ptr,
    163                    has_more_events));
    164     return;
    165   }
    166   sender_->Send(new TracingHostMsg_MonitoringTraceDataCollected(
    167       events_str_ptr->data()));
    168 
    169   if (!has_more_events)
    170     sender_->Send(new TracingHostMsg_CaptureMonitoringSnapshotAck());
    171 }
    172 
    173 }  // namespace tracing
    174