15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/tracing/child_trace_message_filter.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event.h" 8a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/tracing/tracing_messages.h" 105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ipc/ipc_channel.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::debug::TraceLog; 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)namespace tracing { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ChildTraceMessageFilter::ChildTraceMessageFilter( 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoopProxy* ipc_message_loop) 18f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) : sender_(NULL), 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ipc_message_loop_(ipc_message_loop) {} 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void ChildTraceMessageFilter::OnFilterAdded(IPC::Sender* sender) { 22f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sender_ = sender; 23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sender_->Send(new TracingHostMsg_ChildSupportsTracing()); 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChildTraceMessageFilter::OnFilterRemoved() { 27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sender_ = NULL; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChildTraceMessageFilter::OnMessageReceived(const IPC::Message& message) { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool handled = true; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(ChildTraceMessageFilter, message) 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC_MESSAGE_HANDLER(TracingMsg_BeginTracing, OnBeginTracing) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC_MESSAGE_HANDLER(TracingMsg_EndTracing, OnEndTracing) 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) IPC_MESSAGE_HANDLER(TracingMsg_EnableMonitoring, OnEnableMonitoring) 364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) IPC_MESSAGE_HANDLER(TracingMsg_DisableMonitoring, OnDisableMonitoring) 374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) IPC_MESSAGE_HANDLER(TracingMsg_CaptureMonitoringSnapshot, 384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) OnCaptureMonitoringSnapshot) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC_MESSAGE_HANDLER(TracingMsg_GetTraceBufferPercentFull, 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnGetTraceBufferPercentFull) 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC_MESSAGE_HANDLER(TracingMsg_SetWatchEvent, OnSetWatchEvent) 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC_MESSAGE_HANDLER(TracingMsg_CancelWatchEvent, OnCancelWatchEvent) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_UNHANDLED(handled = false) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_END_MESSAGE_MAP() 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return handled; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChildTraceMessageFilter::~ChildTraceMessageFilter() {} 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChildTraceMessageFilter::OnBeginTracing( 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& category_filter_str, 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks browser_time, 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& options) { 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(__native_client__) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // NaCl and system times are offset by a bit, so subtract some time from 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the captured timestamps. The value might be off by a bit due to messaging 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // latency. 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta time_offset = base::TimeTicks::NowFromSystemTraceTime() - 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser_time; 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TraceLog::GetInstance()->SetTimeOffset(time_offset); 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::debug::TraceOptions trace_options; 636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) trace_options.SetFromString(options); 64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) TraceLog::GetInstance()->SetEnabled( 65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::debug::CategoryFilter(category_filter_str), 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::debug::TraceLog::RECORDING_MODE, 676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) trace_options); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChildTraceMessageFilter::OnEndTracing() { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceLog::GetInstance()->SetDisabled(); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Flush will generate one or more callbacks to OnTraceDataCollected 7458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // synchronously or asynchronously. EndTracingAck will be sent in the last 7558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // OnTraceDataCollected. We are already on the IO thread, so the 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OnTraceDataCollected calls will not be deferred. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceLog::GetInstance()->Flush( 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ChildTraceMessageFilter::OnTraceDataCollected, this)); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChildTraceMessageFilter::OnEnableMonitoring( 824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& category_filter_str, 834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::TimeTicks browser_time, 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& options) { 856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::debug::TraceOptions trace_options; 866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) trace_options.SetFromString(options); 874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TraceLog::GetInstance()->SetEnabled( 884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::debug::CategoryFilter(category_filter_str), 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::debug::TraceLog::MONITORING_MODE, 906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) trace_options); 914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChildTraceMessageFilter::OnDisableMonitoring() { 944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TraceLog::GetInstance()->SetDisabled(); 954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChildTraceMessageFilter::OnCaptureMonitoringSnapshot() { 984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Flush will generate one or more callbacks to 994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // OnMonitoringTraceDataCollected. It's important that the last 1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // OnMonitoringTraceDataCollected gets called before 1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // CaptureMonitoringSnapshotAck below. We are already on the IO thread, 1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // so the OnMonitoringTraceDataCollected calls will not be deferred. 1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TraceLog::GetInstance()->FlushButLeaveBufferIntact( 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(&ChildTraceMessageFilter::OnMonitoringTraceDataCollected, 1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) this)); 1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChildTraceMessageFilter::OnGetTraceBufferPercentFull() { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float bpf = TraceLog::GetInstance()->GetBufferPercentFull(); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sender_->Send(new TracingHostMsg_TraceBufferPercentFullReply(bpf)); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChildTraceMessageFilter::OnSetWatchEvent(const std::string& category_name, 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name) { 116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) TraceLog::GetInstance()->SetWatchEvent( 117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) category_name, event_name, 118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Bind(&ChildTraceMessageFilter::OnWatchEventMatched, this)); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChildTraceMessageFilter::OnCancelWatchEvent() { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceLog::GetInstance()->CancelWatchEvent(); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ChildTraceMessageFilter::OnWatchEventMatched() { 126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!ipc_message_loop_->BelongsToCurrentThread()) { 127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ipc_message_loop_->PostTask(FROM_HERE, 128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Bind(&ChildTraceMessageFilter::OnWatchEventMatched, this)); 129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 131f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sender_->Send(new TracingHostMsg_WatchEventMatched); 132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChildTraceMessageFilter::OnTraceDataCollected( 13558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const scoped_refptr<base::RefCountedString>& events_str_ptr, 13658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool has_more_events) { 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!ipc_message_loop_->BelongsToCurrentThread()) { 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ipc_message_loop_->PostTask(FROM_HERE, 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ChildTraceMessageFilter::OnTraceDataCollected, this, 14058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) events_str_ptr, has_more_events)); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (events_str_ptr->data().size()) { 144f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sender_->Send(new TracingHostMsg_TraceDataCollected( 14558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) events_str_ptr->data())); 14658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 14758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!has_more_events) { 14858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::vector<std::string> category_groups; 14958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) TraceLog::GetInstance()->GetKnownCategoryGroups(&category_groups); 150f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sender_->Send(new TracingHostMsg_EndTracingAck(category_groups)); 15158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChildTraceMessageFilter::OnMonitoringTraceDataCollected( 1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const scoped_refptr<base::RefCountedString>& events_str_ptr, 1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool has_more_events) { 1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!ipc_message_loop_->BelongsToCurrentThread()) { 1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ipc_message_loop_->PostTask(FROM_HERE, 1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Bind(&ChildTraceMessageFilter:: 1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) OnMonitoringTraceDataCollected, 1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) this, 1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) events_str_ptr, 1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) has_more_events)); 1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sender_->Send(new TracingHostMsg_MonitoringTraceDataCollected( 1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) events_str_ptr->data())); 168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!has_more_events) 170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sender_->Send(new TracingHostMsg_CaptureMonitoringSnapshotAck()); 1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 173a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} // namespace tracing 174