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     int 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 
     63   TraceLog::GetInstance()->SetEnabled(
     64       base::debug::CategoryFilter(category_filter_str),
     65       base::debug::TraceLog::RECORDING_MODE,
     66       static_cast<base::debug::TraceLog::Options>(options));
     67 }
     68 
     69 void ChildTraceMessageFilter::OnEndTracing() {
     70   TraceLog::GetInstance()->SetDisabled();
     71 
     72   // Flush will generate one or more callbacks to OnTraceDataCollected
     73   // synchronously or asynchronously. EndTracingAck will be sent in the last
     74   // OnTraceDataCollected. We are already on the IO thread, so the
     75   // OnTraceDataCollected calls will not be deferred.
     76   TraceLog::GetInstance()->Flush(
     77       base::Bind(&ChildTraceMessageFilter::OnTraceDataCollected, this));
     78 }
     79 
     80 void ChildTraceMessageFilter::OnEnableMonitoring(
     81     const std::string& category_filter_str,
     82     base::TimeTicks browser_time,
     83     int options) {
     84   TraceLog::GetInstance()->SetEnabled(
     85       base::debug::CategoryFilter(category_filter_str),
     86       base::debug::TraceLog::MONITORING_MODE,
     87       static_cast<base::debug::TraceLog::Options>(options));
     88 }
     89 
     90 void ChildTraceMessageFilter::OnDisableMonitoring() {
     91   TraceLog::GetInstance()->SetDisabled();
     92 }
     93 
     94 void ChildTraceMessageFilter::OnCaptureMonitoringSnapshot() {
     95   // Flush will generate one or more callbacks to
     96   // OnMonitoringTraceDataCollected. It's important that the last
     97   // OnMonitoringTraceDataCollected gets called before
     98   // CaptureMonitoringSnapshotAck below. We are already on the IO thread,
     99   // so the OnMonitoringTraceDataCollected calls will not be deferred.
    100   TraceLog::GetInstance()->FlushButLeaveBufferIntact(
    101       base::Bind(&ChildTraceMessageFilter::OnMonitoringTraceDataCollected,
    102                  this));
    103 }
    104 
    105 void ChildTraceMessageFilter::OnGetTraceBufferPercentFull() {
    106   float bpf = TraceLog::GetInstance()->GetBufferPercentFull();
    107 
    108   sender_->Send(new TracingHostMsg_TraceBufferPercentFullReply(bpf));
    109 }
    110 
    111 void ChildTraceMessageFilter::OnSetWatchEvent(const std::string& category_name,
    112                                               const std::string& event_name) {
    113   TraceLog::GetInstance()->SetWatchEvent(
    114       category_name, event_name,
    115       base::Bind(&ChildTraceMessageFilter::OnWatchEventMatched, this));
    116 }
    117 
    118 void ChildTraceMessageFilter::OnCancelWatchEvent() {
    119   TraceLog::GetInstance()->CancelWatchEvent();
    120 }
    121 
    122 void ChildTraceMessageFilter::OnWatchEventMatched() {
    123   if (!ipc_message_loop_->BelongsToCurrentThread()) {
    124     ipc_message_loop_->PostTask(FROM_HERE,
    125         base::Bind(&ChildTraceMessageFilter::OnWatchEventMatched, this));
    126     return;
    127   }
    128   sender_->Send(new TracingHostMsg_WatchEventMatched);
    129 }
    130 
    131 void ChildTraceMessageFilter::OnTraceDataCollected(
    132     const scoped_refptr<base::RefCountedString>& events_str_ptr,
    133     bool has_more_events) {
    134   if (!ipc_message_loop_->BelongsToCurrentThread()) {
    135     ipc_message_loop_->PostTask(FROM_HERE,
    136         base::Bind(&ChildTraceMessageFilter::OnTraceDataCollected, this,
    137                    events_str_ptr, has_more_events));
    138     return;
    139   }
    140   if (events_str_ptr->data().size()) {
    141     sender_->Send(new TracingHostMsg_TraceDataCollected(
    142         events_str_ptr->data()));
    143   }
    144   if (!has_more_events) {
    145     std::vector<std::string> category_groups;
    146     TraceLog::GetInstance()->GetKnownCategoryGroups(&category_groups);
    147     sender_->Send(new TracingHostMsg_EndTracingAck(category_groups));
    148   }
    149 }
    150 
    151 void ChildTraceMessageFilter::OnMonitoringTraceDataCollected(
    152      const scoped_refptr<base::RefCountedString>& events_str_ptr,
    153      bool has_more_events) {
    154   if (!ipc_message_loop_->BelongsToCurrentThread()) {
    155     ipc_message_loop_->PostTask(FROM_HERE,
    156         base::Bind(&ChildTraceMessageFilter::
    157                    OnMonitoringTraceDataCollected,
    158                    this,
    159                    events_str_ptr,
    160                    has_more_events));
    161     return;
    162   }
    163   sender_->Send(new TracingHostMsg_MonitoringTraceDataCollected(
    164       events_str_ptr->data()));
    165 
    166   if (!has_more_events)
    167     sender_->Send(new TracingHostMsg_CaptureMonitoringSnapshotAck());
    168 }
    169 
    170 }  // namespace tracing
    171