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 27 matching lines...) Expand all Loading... |
38 using base::trace_event::TraceLog; | 38 using base::trace_event::TraceLog; |
39 using base::trace_event::TraceConfig; | 39 using base::trace_event::TraceConfig; |
40 | 40 |
41 namespace content { | 41 namespace content { |
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 | |
49 std::string GetNetworkTypeString() { | 48 std::string GetNetworkTypeString() { |
50 switch (net::NetworkChangeNotifier::GetConnectionType()) { | 49 switch (net::NetworkChangeNotifier::GetConnectionType()) { |
51 case net::NetworkChangeNotifier::CONNECTION_ETHERNET: | 50 case net::NetworkChangeNotifier::CONNECTION_ETHERNET: |
52 return "Ethernet"; | 51 return "Ethernet"; |
53 case net::NetworkChangeNotifier::CONNECTION_WIFI: | 52 case net::NetworkChangeNotifier::CONNECTION_WIFI: |
54 return "WiFi"; | 53 return "WiFi"; |
55 case net::NetworkChangeNotifier::CONNECTION_2G: | 54 case net::NetworkChangeNotifier::CONNECTION_2G: |
56 return "2G"; | 55 return "2G"; |
57 case net::NetworkChangeNotifier::CONNECTION_3G: | 56 case net::NetworkChangeNotifier::CONNECTION_3G: |
58 return "3G"; | 57 return "3G"; |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 } | 137 } |
139 | 138 |
140 TracingControllerImpl::TracingControllerImpl() | 139 TracingControllerImpl::TracingControllerImpl() |
141 : pending_stop_tracing_ack_count_(0), | 140 : pending_stop_tracing_ack_count_(0), |
142 pending_capture_monitoring_snapshot_ack_count_(0), | 141 pending_capture_monitoring_snapshot_ack_count_(0), |
143 pending_trace_log_status_ack_count_(0), | 142 pending_trace_log_status_ack_count_(0), |
144 maximum_trace_buffer_usage_(0), | 143 maximum_trace_buffer_usage_(0), |
145 approximate_event_count_(0), | 144 approximate_event_count_(0), |
146 pending_memory_dump_ack_count_(0), | 145 pending_memory_dump_ack_count_(0), |
147 failed_memory_dump_count_(0), | 146 failed_memory_dump_count_(0), |
| 147 start_tracing_done_callback_(StartTracingDoneCallback()), |
148 // Tracing may have been enabled by ContentMainRunner if kTraceStartup | 148 // Tracing may have been enabled by ContentMainRunner if kTraceStartup |
149 // is specified in command line. | 149 // is specified in command line. |
150 #if defined(OS_CHROMEOS) || defined(OS_WIN) | 150 #if defined(OS_CHROMEOS) || defined(OS_WIN) |
151 is_system_tracing_(false), | 151 is_system_tracing_(false), |
152 #endif | 152 #endif |
153 is_tracing_(false), | 153 is_tracing_(false), |
154 is_monitoring_(false), | 154 is_monitoring_(false), |
155 is_power_tracing_(false) { | 155 is_power_tracing_(false) { |
156 base::trace_event::MemoryDumpManager::GetInstance()->Initialize( | 156 base::trace_event::MemoryDumpManager::GetInstance()->Initialize( |
157 this /* delegate */, true /* is_coordinator */); | 157 this /* delegate */, true /* is_coordinator */); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 } | 207 } |
208 | 208 |
209 bool TracingControllerImpl::StartTracing( | 209 bool TracingControllerImpl::StartTracing( |
210 const TraceConfig& trace_config, | 210 const TraceConfig& trace_config, |
211 const StartTracingDoneCallback& callback) { | 211 const StartTracingDoneCallback& callback) { |
212 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 212 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
213 | 213 |
214 if (!can_start_tracing()) | 214 if (!can_start_tracing()) |
215 return false; | 215 return false; |
216 is_tracing_ = true; | 216 is_tracing_ = true; |
| 217 start_tracing_done_callback_ = callback; |
217 | 218 |
218 #if defined(OS_ANDROID) | 219 #if defined(OS_ANDROID) |
219 if (pending_get_categories_done_callback_.is_null()) | 220 if (pending_get_categories_done_callback_.is_null()) |
220 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); | 221 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); |
221 #endif | 222 #endif |
222 | 223 |
223 if (trace_config.IsSystraceEnabled()) { | 224 if (trace_config.IsSystraceEnabled()) { |
224 DCHECK(!is_power_tracing_); | 225 DCHECK(!is_power_tracing_); |
225 is_power_tracing_ = PowerTracingAgent::GetInstance()->StartTracing(); | 226 is_power_tracing_ = PowerTracingAgent::GetInstance()-> |
| 227 StartAgentTracing(trace_config); |
226 #if defined(OS_CHROMEOS) | 228 #if defined(OS_CHROMEOS) |
227 DCHECK(!is_system_tracing_); | 229 DCHECK(!is_system_tracing_); |
228 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()-> | 230 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()-> |
229 StartSystemTracing(); | 231 StartAgentTracing(trace_config); |
230 is_system_tracing_ = true; | 232 is_system_tracing_ = true; |
231 #elif defined(OS_WIN) | 233 #elif defined(OS_WIN) |
232 DCHECK(!is_system_tracing_); | 234 DCHECK(!is_system_tracing_); |
233 is_system_tracing_ = | 235 is_system_tracing_ = |
234 EtwSystemEventConsumer::GetInstance()->StartSystemTracing(); | 236 EtwSystemEventConsumer::GetInstance()->StartAgentTracing(trace_config); |
235 #endif | 237 #endif |
236 } | 238 } |
237 | 239 |
238 // TraceLog may have been enabled in startup tracing before threads are ready. | 240 // TraceLog may have been enabled in startup tracing before threads are ready. |
239 if (TraceLog::GetInstance()->IsEnabled()) | 241 if (TraceLog::GetInstance()->IsEnabled()) |
240 return true; | 242 return true; |
241 | 243 |
242 base::Closure on_start_tracing_done_callback = | 244 return StartAgentTracing(trace_config); |
243 base::Bind(&TracingControllerImpl::OnStartTracingDone, | |
244 base::Unretained(this), | |
245 trace_config, callback); | |
246 if (!BrowserThread::PostTask( | |
247 BrowserThread::FILE, FROM_HERE, | |
248 base::Bind(&TracingControllerImpl::SetEnabledOnFileThread, | |
249 base::Unretained(this), trace_config, | |
250 base::trace_event::TraceLog::RECORDING_MODE, | |
251 on_start_tracing_done_callback))) { | |
252 // BrowserThread::PostTask fails if the threads haven't been created yet, | |
253 // so it should be safe to just use TraceLog::SetEnabled directly. | |
254 base::trace_event::TraceLog::GetInstance()->SetEnabled( | |
255 trace_config, base::trace_event::TraceLog::RECORDING_MODE); | |
256 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | |
257 on_start_tracing_done_callback); | |
258 } | |
259 | |
260 return true; | |
261 } | 245 } |
262 | 246 |
263 void TracingControllerImpl::OnStartTracingDone( | 247 void TracingControllerImpl::OnStartAgentTracingDone( |
264 const TraceConfig& trace_config, | 248 const TraceConfig& trace_config, |
265 const StartTracingDoneCallback& callback) { | 249 const StartTracingDoneCallback& callback) { |
266 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 250 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
267 | 251 |
268 TRACE_EVENT_API_ADD_METADATA_EVENT("IsTimeTicksHighResolution", "value", | 252 TRACE_EVENT_API_ADD_METADATA_EVENT("IsTimeTicksHighResolution", "value", |
269 base::TimeTicks::IsHighResolution()); | 253 base::TimeTicks::IsHighResolution()); |
270 TRACE_EVENT_API_ADD_METADATA_EVENT("TraceConfig", "value", | 254 TRACE_EVENT_API_ADD_METADATA_EVENT("TraceConfig", "value", |
271 trace_config.AsConvertableToTraceFormat()); | 255 trace_config.AsConvertableToTraceFormat()); |
272 | 256 |
273 // Notify all child processes. | 257 // Notify all child processes. |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 if (is_system_tracing_) { | 303 if (is_system_tracing_) { |
320 // Disable system tracing. | 304 // Disable system tracing. |
321 is_system_tracing_ = false; | 305 is_system_tracing_ = false; |
322 ++pending_stop_tracing_ack_count_; | 306 ++pending_stop_tracing_ack_count_; |
323 | 307 |
324 #if defined(OS_CHROMEOS) | 308 #if defined(OS_CHROMEOS) |
325 scoped_refptr<base::TaskRunner> task_runner = | 309 scoped_refptr<base::TaskRunner> task_runner = |
326 BrowserThread::GetBlockingPool(); | 310 BrowserThread::GetBlockingPool(); |
327 chromeos::DBusThreadManager::Get() | 311 chromeos::DBusThreadManager::Get() |
328 ->GetDebugDaemonClient() | 312 ->GetDebugDaemonClient() |
329 ->RequestStopSystemTracing( | 313 ->SetStopAgentTracingTaskRunner(task_runner); |
330 task_runner, | 314 chromeos::DBusThreadManager::Get() |
| 315 ->GetDebugDaemonClient() |
| 316 ->StopAgentTracing( |
331 base::Bind(&TracingControllerImpl::OnEndSystemTracingAcked, | 317 base::Bind(&TracingControllerImpl::OnEndSystemTracingAcked, |
332 base::Unretained(this))); | 318 base::Unretained(this))); |
333 #elif defined(OS_WIN) | 319 #elif defined(OS_WIN) |
334 EtwSystemEventConsumer::GetInstance()->StopSystemTracing( | 320 EtwSystemEventConsumer::GetInstance()->StopAgentTracing( |
335 base::Bind(&TracingControllerImpl::OnEndSystemTracingAcked, | 321 base::Bind(&TracingControllerImpl::OnEndSystemTracingAcked, |
336 base::Unretained(this))); | 322 base::Unretained(this))); |
337 #endif | 323 #endif |
338 } | 324 } |
339 #endif // defined(OS_CHROMEOS) || defined(OS_WIN) | 325 #endif // defined(OS_CHROMEOS) || defined(OS_WIN) |
340 | 326 |
341 if (is_power_tracing_) { | 327 if (is_power_tracing_) { |
342 is_power_tracing_ = false; | 328 is_power_tracing_ = false; |
343 ++pending_stop_tracing_ack_count_; | 329 ++pending_stop_tracing_ack_count_; |
344 PowerTracingAgent::GetInstance()->StopTracing( | 330 PowerTracingAgent::GetInstance()->StopAgentTracing( |
345 base::Bind(&TracingControllerImpl::OnEndPowerTracingAcked, | 331 base::Bind(&TracingControllerImpl::OnEndPowerTracingAcked, |
346 base::Unretained(this))); | 332 base::Unretained(this))); |
347 } | 333 } |
348 | 334 |
349 // Handle special case of zero child processes by immediately flushing the | 335 StopAgentTracing(StopAgentTracingCallback()); |
350 // trace log. Once the flush has completed the caller will be notified that | |
351 // tracing has ended. | |
352 if (pending_stop_tracing_ack_count_ == 1) { | |
353 // Flush/cancel asynchronously now, because we don't have any children to | |
354 // wait for. | |
355 if (trace_data_sink_) { | |
356 TraceLog::GetInstance()->Flush( | |
357 base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected, | |
358 base::Unretained(this)), | |
359 true); | |
360 } else { | |
361 TraceLog::GetInstance()->CancelTracing( | |
362 base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected, | |
363 base::Unretained(this))); | |
364 } | |
365 } | |
366 | |
367 // Notify all child processes. | |
368 for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin(); | |
369 it != trace_message_filters_.end(); ++it) { | |
370 if (trace_data_sink_) | |
371 it->get()->SendEndTracing(); | |
372 else | |
373 it->get()->SendCancelTracing(); | |
374 } | |
375 } | 336 } |
376 | 337 |
377 bool TracingControllerImpl::StartMonitoring( | 338 bool TracingControllerImpl::StartMonitoring( |
378 const TraceConfig& trace_config, | 339 const TraceConfig& trace_config, |
379 const StartMonitoringDoneCallback& callback) { | 340 const StartMonitoringDoneCallback& callback) { |
380 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 341 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
381 | 342 |
382 if (!can_start_monitoring()) | 343 if (!can_start_monitoring()) |
383 return false; | 344 return false; |
384 OnMonitoringStateChanged(true); | 345 OnMonitoringStateChanged(true); |
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
907 DCHECK(tracing_uis_.find(tracing_ui) == tracing_uis_.end()); | 868 DCHECK(tracing_uis_.find(tracing_ui) == tracing_uis_.end()); |
908 tracing_uis_.insert(tracing_ui); | 869 tracing_uis_.insert(tracing_ui); |
909 } | 870 } |
910 | 871 |
911 void TracingControllerImpl::UnregisterTracingUI(TracingUI* tracing_ui) { | 872 void TracingControllerImpl::UnregisterTracingUI(TracingUI* tracing_ui) { |
912 std::set<TracingUI*>::iterator it = tracing_uis_.find(tracing_ui); | 873 std::set<TracingUI*>::iterator it = tracing_uis_.find(tracing_ui); |
913 DCHECK(it != tracing_uis_.end()); | 874 DCHECK(it != tracing_uis_.end()); |
914 tracing_uis_.erase(it); | 875 tracing_uis_.erase(it); |
915 } | 876 } |
916 | 877 |
| 878 std::string TracingControllerImpl::GetTracingAgentName() { |
| 879 return kChromeTracingAgentName; |
| 880 } |
| 881 |
| 882 bool TracingControllerImpl::StartAgentTracing( |
| 883 const base::trace_event::TraceConfig& trace_config) { |
| 884 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 885 |
| 886 base::Closure on_start_tracing_done_callback = |
| 887 base::Bind(&TracingControllerImpl::OnStartAgentTracingDone, |
| 888 base::Unretained(this), |
| 889 trace_config, start_tracing_done_callback_); |
| 890 if (!BrowserThread::PostTask( |
| 891 BrowserThread::FILE, FROM_HERE, |
| 892 base::Bind(&TracingControllerImpl::SetEnabledOnFileThread, |
| 893 base::Unretained(this), trace_config, |
| 894 base::trace_event::TraceLog::RECORDING_MODE, |
| 895 on_start_tracing_done_callback))) { |
| 896 // BrowserThread::PostTask fails if the threads haven't been created yet, |
| 897 // so it should be safe to just use TraceLog::SetEnabled directly. |
| 898 base::trace_event::TraceLog::GetInstance()->SetEnabled( |
| 899 trace_config, base::trace_event::TraceLog::RECORDING_MODE); |
| 900 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 901 on_start_tracing_done_callback); |
| 902 } |
| 903 |
| 904 return true; |
| 905 } |
| 906 |
| 907 void TracingControllerImpl::StopAgentTracing( |
| 908 const StopAgentTracingCallback& callback) { |
| 909 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 910 // Handle special case of zero child processes by immediately flushing the |
| 911 // trace log. Once the flush has completed the caller will be notified that |
| 912 // tracing has ended. |
| 913 if (pending_stop_tracing_ack_count_ == 1) { |
| 914 // Flush/cancel asynchronously now, because we don't have any children to |
| 915 // wait for. |
| 916 if (trace_data_sink_) { |
| 917 TraceLog::GetInstance()->Flush( |
| 918 base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected, |
| 919 base::Unretained(this)), |
| 920 true); |
| 921 } else { |
| 922 TraceLog::GetInstance()->CancelTracing( |
| 923 base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected, |
| 924 base::Unretained(this))); |
| 925 } |
| 926 } |
| 927 |
| 928 // Notify all child processes. |
| 929 for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin(); |
| 930 it != trace_message_filters_.end(); ++it) { |
| 931 if (trace_data_sink_) |
| 932 it->get()->SendEndTracing(); |
| 933 else |
| 934 it->get()->SendCancelTracing(); |
| 935 } |
| 936 } |
| 937 |
| 938 bool TracingControllerImpl::SupportsExplicitClockSync() { |
| 939 // TODO(zhenw): return true after implementing explicit clock sync. |
| 940 return false; |
| 941 } |
| 942 |
| 943 void TracingControllerImpl::RecordClockSyncMarker( |
| 944 scoped_ptr<base::DictionaryValue> marker) { |
| 945 DCHECK(SupportsExplicitClockSync()); |
| 946 // TODO(zhenw): implement explicit clock sync. |
| 947 } |
| 948 |
| 949 void TracingControllerImpl::IssueClockSyncMarker() { |
| 950 DCHECK(SupportsExplicitClockSync()); |
| 951 // TODO(zhenw): implement explicit clock sync. |
| 952 } |
| 953 |
917 void TracingControllerImpl::RequestGlobalMemoryDump( | 954 void TracingControllerImpl::RequestGlobalMemoryDump( |
918 const base::trace_event::MemoryDumpRequestArgs& args, | 955 const base::trace_event::MemoryDumpRequestArgs& args, |
919 const base::trace_event::MemoryDumpCallback& callback) { | 956 const base::trace_event::MemoryDumpCallback& callback) { |
920 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 957 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
921 BrowserThread::PostTask( | 958 BrowserThread::PostTask( |
922 BrowserThread::UI, FROM_HERE, | 959 BrowserThread::UI, FROM_HERE, |
923 base::Bind(&TracingControllerImpl::RequestGlobalMemoryDump, | 960 base::Bind(&TracingControllerImpl::RequestGlobalMemoryDump, |
924 base::Unretained(this), args, callback)); | 961 base::Unretained(this), args, callback)); |
925 return; | 962 return; |
926 } | 963 } |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1043 is_monitoring_ = is_monitoring; | 1080 is_monitoring_ = is_monitoring; |
1044 #if !defined(OS_ANDROID) | 1081 #if !defined(OS_ANDROID) |
1045 for (std::set<TracingUI*>::iterator it = tracing_uis_.begin(); | 1082 for (std::set<TracingUI*>::iterator it = tracing_uis_.begin(); |
1046 it != tracing_uis_.end(); it++) { | 1083 it != tracing_uis_.end(); it++) { |
1047 (*it)->OnMonitoringStateChanged(is_monitoring); | 1084 (*it)->OnMonitoringStateChanged(is_monitoring); |
1048 } | 1085 } |
1049 #endif | 1086 #endif |
1050 } | 1087 } |
1051 | 1088 |
1052 } // namespace content | 1089 } // namespace content |
OLD | NEW |