| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 #include "content/browser/tracing/tracing_controller_impl.h" | 4 #include "content/browser/tracing/tracing_controller_impl.h" |
| 5 | 5 |
| 6 #include "base/bind.h" | 6 #include "base/bind.h" |
| 7 #include "base/cpu.h" | 7 #include "base/cpu.h" |
| 8 #include "base/files/file_util.h" | 8 #include "base/files/file_util.h" |
| 9 #include "base/json/string_escape.h" | 9 #include "base/json/string_escape.h" |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 | 42 |
| 43 namespace { | 43 namespace { |
| 44 | 44 |
| 45 base::LazyInstance<TracingControllerImpl>::Leaky g_controller = | 45 base::LazyInstance<TracingControllerImpl>::Leaky g_controller = |
| 46 LAZY_INSTANCE_INITIALIZER; | 46 LAZY_INSTANCE_INITIALIZER; |
| 47 | 47 |
| 48 const char kChromeTracingAgentName[] = "chrome"; | 48 const char kChromeTracingAgentName[] = "chrome"; |
| 49 const char kETWTracingAgentName[] = "etw"; | 49 const char kETWTracingAgentName[] = "etw"; |
| 50 const char kChromeTraceLabel[] = "traceEvents"; | 50 const char kChromeTraceLabel[] = "traceEvents"; |
| 51 | 51 |
| 52 const int kIssueClockSyncTimeout = 30; |
| 53 |
| 52 std::string GetNetworkTypeString() { | 54 std::string GetNetworkTypeString() { |
| 53 switch (net::NetworkChangeNotifier::GetConnectionType()) { | 55 switch (net::NetworkChangeNotifier::GetConnectionType()) { |
| 54 case net::NetworkChangeNotifier::CONNECTION_ETHERNET: | 56 case net::NetworkChangeNotifier::CONNECTION_ETHERNET: |
| 55 return "Ethernet"; | 57 return "Ethernet"; |
| 56 case net::NetworkChangeNotifier::CONNECTION_WIFI: | 58 case net::NetworkChangeNotifier::CONNECTION_WIFI: |
| 57 return "WiFi"; | 59 return "WiFi"; |
| 58 case net::NetworkChangeNotifier::CONNECTION_2G: | 60 case net::NetworkChangeNotifier::CONNECTION_2G: |
| 59 return "2G"; | 61 return "2G"; |
| 60 case net::NetworkChangeNotifier::CONNECTION_3G: | 62 case net::NetworkChangeNotifier::CONNECTION_3G: |
| 61 return "3G"; | 63 return "3G"; |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 } | 143 } |
| 142 | 144 |
| 143 TracingControllerImpl::TracingControllerImpl() | 145 TracingControllerImpl::TracingControllerImpl() |
| 144 : pending_stop_tracing_ack_count_(0), | 146 : pending_stop_tracing_ack_count_(0), |
| 145 pending_capture_monitoring_snapshot_ack_count_(0), | 147 pending_capture_monitoring_snapshot_ack_count_(0), |
| 146 pending_trace_log_status_ack_count_(0), | 148 pending_trace_log_status_ack_count_(0), |
| 147 maximum_trace_buffer_usage_(0), | 149 maximum_trace_buffer_usage_(0), |
| 148 approximate_event_count_(0), | 150 approximate_event_count_(0), |
| 149 pending_memory_dump_ack_count_(0), | 151 pending_memory_dump_ack_count_(0), |
| 150 failed_memory_dump_count_(0), | 152 failed_memory_dump_count_(0), |
| 153 clock_sync_id_(0), |
| 154 pending_clock_sync_ack_count_(0), |
| 151 is_tracing_(false), | 155 is_tracing_(false), |
| 152 is_monitoring_(false) { | 156 is_monitoring_(false) { |
| 153 base::trace_event::MemoryDumpManager::GetInstance()->Initialize( | 157 base::trace_event::MemoryDumpManager::GetInstance()->Initialize( |
| 154 this /* delegate */, true /* is_coordinator */); | 158 this /* delegate */, true /* is_coordinator */); |
| 155 | 159 |
| 156 // Deliberately leaked, like this class. | 160 // Deliberately leaked, like this class. |
| 157 base::FileTracing::SetProvider(new FileTracingProviderImpl); | 161 base::FileTracing::SetProvider(new FileTracingProviderImpl); |
| 158 } | 162 } |
| 159 | 163 |
| 160 TracingControllerImpl::~TracingControllerImpl() { | 164 TracingControllerImpl::~TracingControllerImpl() { |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 delegate->GetMetadataFilterPredicate()); | 284 delegate->GetMetadataFilterPredicate()); |
| 281 } | 285 } |
| 282 } | 286 } |
| 283 trace_data_sink->AddMetadata(*GenerateTracingMetadataDict().get()); | 287 trace_data_sink->AddMetadata(*GenerateTracingMetadataDict().get()); |
| 284 } | 288 } |
| 285 | 289 |
| 286 if (!can_stop_tracing()) | 290 if (!can_stop_tracing()) |
| 287 return false; | 291 return false; |
| 288 | 292 |
| 289 trace_data_sink_ = trace_data_sink; | 293 trace_data_sink_ = trace_data_sink; |
| 294 |
| 295 // Issue clock sync marker before actually stopping tracing. |
| 296 // StopTracingAfterClockSync() will be called after clock sync is done. |
| 297 IssueClockSyncMarker(); |
| 298 |
| 299 return true; |
| 300 } |
| 301 |
| 302 void TracingControllerImpl::StopTracingAfterClockSync() { |
| 303 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 304 |
| 305 // |pending_clock_sync_ack_count_| could be non-zero if clock sync times out. |
| 306 pending_clock_sync_ack_count_ = 0; |
| 307 |
| 290 // Disable local trace early to avoid traces during end-tracing process from | 308 // Disable local trace early to avoid traces during end-tracing process from |
| 291 // interfering with the process. | 309 // interfering with the process. |
| 292 base::Closure on_stop_tracing_done_callback = base::Bind( | 310 base::Closure on_stop_tracing_done_callback = base::Bind( |
| 293 &TracingControllerImpl::OnStopTracingDone, base::Unretained(this)); | 311 &TracingControllerImpl::OnStopTracingDone, base::Unretained(this)); |
| 294 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 312 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| 295 base::Bind(&TracingControllerImpl::SetDisabledOnFileThread, | 313 base::Bind(&TracingControllerImpl::SetDisabledOnFileThread, |
| 296 base::Unretained(this), | 314 base::Unretained(this), |
| 297 on_stop_tracing_done_callback)); | 315 on_stop_tracing_done_callback)); |
| 298 return true; | |
| 299 } | 316 } |
| 300 | 317 |
| 301 void TracingControllerImpl::OnStopTracingDone() { | 318 void TracingControllerImpl::OnStopTracingDone() { |
| 302 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 319 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 303 | 320 |
| 304 #if defined(OS_ANDROID) | 321 #if defined(OS_ANDROID) |
| 305 if (pending_get_categories_done_callback_.is_null()) | 322 if (pending_get_categories_done_callback_.is_null()) |
| 306 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); | 323 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); |
| 307 #endif | 324 #endif |
| 308 | 325 |
| (...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 906 // Notify all child processes. | 923 // Notify all child processes. |
| 907 for (auto it : trace_message_filters_) { | 924 for (auto it : trace_message_filters_) { |
| 908 if (trace_data_sink_) | 925 if (trace_data_sink_) |
| 909 it->SendEndTracing(); | 926 it->SendEndTracing(); |
| 910 else | 927 else |
| 911 it->SendCancelTracing(); | 928 it->SendCancelTracing(); |
| 912 } | 929 } |
| 913 } | 930 } |
| 914 | 931 |
| 915 bool TracingControllerImpl::SupportsExplicitClockSync() { | 932 bool TracingControllerImpl::SupportsExplicitClockSync() { |
| 916 // TODO(zhenw): return true after implementing explicit clock sync. | 933 return true; |
| 917 return false; | |
| 918 } | 934 } |
| 919 | 935 |
| 920 void TracingControllerImpl::RecordClockSyncMarker( | 936 void TracingControllerImpl::RecordClockSyncMarker( |
| 921 int sync_id, | 937 int sync_id, |
| 922 const RecordClockSyncMarkerCallback& callback) { | 938 const RecordClockSyncMarkerCallback& callback) { |
| 923 DCHECK(SupportsExplicitClockSync()); | 939 DCHECK(SupportsExplicitClockSync()); |
| 924 // TODO(zhenw): implement explicit clock sync. | 940 |
| 941 TRACE_EVENT_CLOCK_SYNC_RECEIVER(sync_id); |
| 942 } |
| 943 |
| 944 int TracingControllerImpl::GetUniqueClockSyncID() { |
| 945 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 946 // There is no need to lock because this function only runs on UI thread. |
| 947 return ++clock_sync_id_; |
| 925 } | 948 } |
| 926 | 949 |
| 927 void TracingControllerImpl::IssueClockSyncMarker() { | 950 void TracingControllerImpl::IssueClockSyncMarker() { |
| 928 // TODO(zhenw): implement explicit clock sync. | 951 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 952 DCHECK(pending_clock_sync_ack_count_ == 0); |
| 953 |
| 954 for (const auto& it : additional_tracing_agents_) { |
| 955 if (it->SupportsExplicitClockSync()) { |
| 956 it->RecordClockSyncMarker( |
| 957 GetUniqueClockSyncID(), |
| 958 base::Bind(&TracingControllerImpl::OnClockSyncMarkerRecordedByAgent, |
| 959 base::Unretained(this))); |
| 960 pending_clock_sync_ack_count_++; |
| 961 } |
| 962 } |
| 963 |
| 964 // If no clock sync is needed, stop tracing right away. Otherwise, schedule |
| 965 // to stop tracing after timeout. |
| 966 if (pending_clock_sync_ack_count_ == 0) { |
| 967 StopTracingAfterClockSync(); |
| 968 } else { |
| 969 clock_sync_timer_.Start( |
| 970 FROM_HERE, |
| 971 base::TimeDelta::FromSeconds(kIssueClockSyncTimeout), |
| 972 this, |
| 973 &TracingControllerImpl::StopTracingAfterClockSync); |
| 974 } |
| 975 } |
| 976 |
| 977 void TracingControllerImpl::OnClockSyncMarkerRecordedByAgent( |
| 978 int sync_id, |
| 979 const base::TimeTicks& issue_ts, |
| 980 const base::TimeTicks& issue_end_ts) { |
| 981 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 982 |
| 983 TRACE_EVENT_CLOCK_SYNC_ISSUER(sync_id, issue_ts, issue_end_ts); |
| 984 |
| 985 // Timer is not running means that clock sync already timed out. |
| 986 if (!clock_sync_timer_.IsRunning()) |
| 987 return; |
| 988 |
| 989 // Stop tracing only if all agents report back. |
| 990 if(--pending_clock_sync_ack_count_ == 0) { |
| 991 clock_sync_timer_.Stop(); |
| 992 StopTracingAfterClockSync(); |
| 993 } |
| 929 } | 994 } |
| 930 | 995 |
| 931 void TracingControllerImpl::RequestGlobalMemoryDump( | 996 void TracingControllerImpl::RequestGlobalMemoryDump( |
| 932 const base::trace_event::MemoryDumpRequestArgs& args, | 997 const base::trace_event::MemoryDumpRequestArgs& args, |
| 933 const base::trace_event::MemoryDumpCallback& callback) { | 998 const base::trace_event::MemoryDumpCallback& callback) { |
| 934 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 999 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
| 935 BrowserThread::PostTask( | 1000 BrowserThread::PostTask( |
| 936 BrowserThread::UI, FROM_HERE, | 1001 BrowserThread::UI, FROM_HERE, |
| 937 base::Bind(&TracingControllerImpl::RequestGlobalMemoryDump, | 1002 base::Bind(&TracingControllerImpl::RequestGlobalMemoryDump, |
| 938 base::Unretained(this), args, callback)); | 1003 base::Unretained(this), args, callback)); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1057 is_monitoring_ = is_monitoring; | 1122 is_monitoring_ = is_monitoring; |
| 1058 #if !defined(OS_ANDROID) | 1123 #if !defined(OS_ANDROID) |
| 1059 for (std::set<TracingUI*>::iterator it = tracing_uis_.begin(); | 1124 for (std::set<TracingUI*>::iterator it = tracing_uis_.begin(); |
| 1060 it != tracing_uis_.end(); it++) { | 1125 it != tracing_uis_.end(); it++) { |
| 1061 (*it)->OnMonitoringStateChanged(is_monitoring); | 1126 (*it)->OnMonitoringStateChanged(is_monitoring); |
| 1062 } | 1127 } |
| 1063 #endif | 1128 #endif |
| 1064 } | 1129 } |
| 1065 | 1130 |
| 1066 } // namespace content | 1131 } // namespace content |
| OLD | NEW |