| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 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 | 4 |
| 5 #include "content/browser/tracing/tracing_controller_impl.h" | 5 #include "content/browser/tracing/tracing_controller_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/debug/trace_event.h" | |
| 9 #include "base/file_util.h" | 8 #include "base/file_util.h" |
| 10 #include "base/json/string_escape.h" | 9 #include "base/json/string_escape.h" |
| 11 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
| 12 #include "content/browser/tracing/trace_message_filter.h" | 11 #include "content/browser/tracing/trace_message_filter.h" |
| 13 #include "content/common/child_process_messages.h" | 12 #include "content/common/child_process_messages.h" |
| 14 #include "content/public/browser/browser_message_filter.h" | 13 #include "content/public/browser/browser_message_filter.h" |
| 15 #include "content/public/common/content_switches.h" | 14 #include "content/public/common/content_switches.h" |
| 16 | 15 |
| 17 using base::debug::TraceLog; | 16 using base::debug::TraceLog; |
| 18 | 17 |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 | 111 |
| 113 | 112 |
| 114 TracingControllerImpl::TracingControllerImpl() : | 113 TracingControllerImpl::TracingControllerImpl() : |
| 115 pending_disable_recording_ack_count_(0), | 114 pending_disable_recording_ack_count_(0), |
| 116 pending_capture_monitoring_snapshot_ack_count_(0), | 115 pending_capture_monitoring_snapshot_ack_count_(0), |
| 117 pending_trace_buffer_percent_full_ack_count_(0), | 116 pending_trace_buffer_percent_full_ack_count_(0), |
| 118 maximum_trace_buffer_percent_full_(0), | 117 maximum_trace_buffer_percent_full_(0), |
| 119 // Tracing may have been enabled by ContentMainRunner if kTraceStartup | 118 // Tracing may have been enabled by ContentMainRunner if kTraceStartup |
| 120 // is specified in command line. | 119 // is specified in command line. |
| 121 is_recording_(TraceLog::GetInstance()->IsEnabled()), | 120 is_recording_(TraceLog::GetInstance()->IsEnabled()), |
| 122 is_monitoring_(false) { | 121 is_monitoring_(false), |
| 122 category_filter_( |
| 123 base::debug::CategoryFilter::kDefaultCategoryFilterString) { |
| 123 } | 124 } |
| 124 | 125 |
| 125 TracingControllerImpl::~TracingControllerImpl() { | 126 TracingControllerImpl::~TracingControllerImpl() { |
| 126 // This is a Leaky instance. | 127 // This is a Leaky instance. |
| 127 NOTREACHED(); | 128 NOTREACHED(); |
| 128 } | 129 } |
| 129 | 130 |
| 130 TracingControllerImpl* TracingControllerImpl::GetInstance() { | 131 TracingControllerImpl* TracingControllerImpl::GetInstance() { |
| 131 return g_controller.Pointer(); | 132 return g_controller.Pointer(); |
| 132 } | 133 } |
| 133 | 134 |
| 134 bool TracingControllerImpl::GetCategories( | 135 void TracingControllerImpl::GetCategories( |
| 135 const GetCategoriesDoneCallback& callback) { | 136 const GetCategoriesDoneCallback& callback) { |
| 136 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 137 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 137 | 138 |
| 138 // Known categories come back from child processes with the EndTracingAck | 139 // Known categories come back from child processes with the EndTracingAck |
| 139 // message. So to get known categories, just begin and end tracing immediately | 140 // message. So to get known categories, just begin and end tracing immediately |
| 140 // afterwards. This will ping all the child processes for categories. | 141 // afterwards. This will ping all the child processes for categories. |
| 141 pending_get_categories_done_callback_ = callback; | 142 pending_get_categories_done_callback_ = callback; |
| 142 if (!EnableRecording("*", TracingController::Options(), | 143 EnableRecording(base::debug::CategoryFilter("*"), |
| 143 EnableRecordingDoneCallback())) { | 144 TracingController::Options(), |
| 144 pending_get_categories_done_callback_.Reset(); | 145 EnableRecordingDoneCallback()); |
| 145 return false; | 146 DisableRecording(base::FilePath(), TracingFileResultCallback()); |
| 146 } | |
| 147 | |
| 148 bool ok = DisableRecording(base::FilePath(), TracingFileResultCallback()); | |
| 149 DCHECK(ok); | |
| 150 return true; | |
| 151 } | 147 } |
| 152 | 148 |
| 153 bool TracingControllerImpl::EnableRecording( | 149 bool TracingControllerImpl::EnableRecording( |
| 154 const std::string& category_filter, | 150 const base::debug::CategoryFilter& filter, |
| 155 TracingController::Options options, | 151 TracingController::Options options, |
| 156 const EnableRecordingDoneCallback& callback) { | 152 const EnableRecordingDoneCallback& callback) { |
| 157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 153 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 158 | 154 |
| 159 if (!can_enable_recording()) | 155 if (!can_enable_recording()) |
| 160 return false; | 156 return false; |
| 161 | 157 |
| 162 #if defined(OS_ANDROID) | 158 #if defined(OS_ANDROID) |
| 163 if (pending_get_categories_done_callback_.is_null()) | 159 if (pending_get_categories_done_callback_.is_null()) |
| 164 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); | 160 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); |
| 165 #endif | 161 #endif |
| 166 | 162 |
| 167 TraceLog::Options trace_options = (options & RECORD_CONTINUOUSLY) ? | 163 TraceLog::Options trace_options = (options & RECORD_CONTINUOUSLY) ? |
| 168 TraceLog::RECORD_CONTINUOUSLY : TraceLog::RECORD_UNTIL_FULL; | 164 TraceLog::RECORD_CONTINUOUSLY : TraceLog::RECORD_UNTIL_FULL; |
| 169 if (options & ENABLE_SAMPLING) { | 165 if (options & ENABLE_SAMPLING) { |
| 170 trace_options = static_cast<TraceLog::Options>( | 166 trace_options = static_cast<TraceLog::Options>( |
| 171 trace_options | TraceLog::ENABLE_SAMPLING); | 167 trace_options | TraceLog::ENABLE_SAMPLING); |
| 172 } | 168 } |
| 173 // TODO(haraken): How to handle ENABLE_SYSTRACE? | 169 // TODO(haraken): How to handle ENABLE_SYSTRACE? |
| 174 | 170 |
| 175 TraceLog::GetInstance()->SetEnabled( | 171 TraceLog::GetInstance()->SetEnabled(filter, trace_options); |
| 176 base::debug::CategoryFilter(category_filter), trace_options); | |
| 177 is_recording_ = true; | 172 is_recording_ = true; |
| 173 category_filter_ = TraceLog::GetInstance()->GetCurrentCategoryFilter(); |
| 178 | 174 |
| 179 // Notify all child processes. | 175 // Notify all child processes. |
| 180 for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin(); | 176 for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) { |
| 181 it != trace_message_filters_.end(); ++it) { | 177 it->get()->SendBeginTracing(category_filter_.ToString(), trace_options); |
| 182 it->get()->SendBeginTracing(category_filter, trace_options); | |
| 183 } | 178 } |
| 184 | 179 |
| 185 if (!callback.is_null()) | 180 if (!callback.is_null()) |
| 186 callback.Run(); | 181 callback.Run(); |
| 187 return true; | 182 return true; |
| 188 } | 183 } |
| 189 | 184 |
| 190 bool TracingControllerImpl::DisableRecording( | 185 bool TracingControllerImpl::DisableRecording( |
| 191 const base::FilePath& result_file_path, | 186 const base::FilePath& result_file_path, |
| 192 const TracingFileResultCallback& callback) { | 187 const TracingFileResultCallback& callback) { |
| 193 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 188 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 194 | 189 |
| 195 if (!can_disable_recording()) | 190 if (!can_disable_recording()) |
| 196 return false; | 191 return false; |
| 197 | 192 |
| 198 pending_disable_recording_done_callback_ = callback; | 193 pending_disable_recording_done_callback_ = callback; |
| 199 | 194 |
| 200 // Disable local trace early to avoid traces during end-tracing process from | 195 // Disable local trace early to avoid traces during end-tracing process from |
| 201 // interfering with the process. | 196 // interfering with the process. |
| 202 TraceLog::GetInstance()->SetDisabled(); | 197 TraceLog::GetInstance()->SetDisabled(); |
| 203 | 198 |
| 204 #if defined(OS_ANDROID) | 199 #if defined(OS_ANDROID) |
| 205 if (pending_get_categories_done_callback_.is_null()) | 200 if (pending_get_categories_done_callback_.is_null()) |
| 206 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); | 201 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); |
| 207 #endif | 202 #endif |
| 208 | 203 |
| 209 if (!callback.is_null() || !result_file_path.empty()) | 204 if (!callback.is_null() || !result_file_path.empty()) |
| 210 result_file_.reset(new ResultFile(result_file_path)); | 205 result_file_.reset(new ResultFile(result_file_path)); |
| 211 | 206 |
| 207 // There could be a case where there are no child processes and filters_ |
| 208 // is empty. In that case we can immediately tell the subscriber that tracing |
| 209 // has ended. To avoid recursive calls back to the subscriber, we will just |
| 210 // use the existing asynchronous OnDisableRecordingAcked code. |
| 212 // Count myself (local trace) in pending_disable_recording_ack_count_, | 211 // Count myself (local trace) in pending_disable_recording_ack_count_, |
| 213 // acked below. | 212 // acked below. |
| 214 pending_disable_recording_ack_count_ = trace_message_filters_.size() + 1; | 213 pending_disable_recording_ack_count_ = filters_.size() + 1; |
| 215 | 214 |
| 216 // Handle special case of zero child processes by immediately telling the | 215 // Handle special case of zero child processes. |
| 217 // caller that tracing has ended. Use asynchronous OnDisableRecordingAcked | |
| 218 // to avoid recursive call back to the caller. | |
| 219 if (pending_disable_recording_ack_count_ == 1) { | 216 if (pending_disable_recording_ack_count_ == 1) { |
| 220 // Ack asynchronously now, because we don't have any children to wait for. | 217 // Ack asynchronously now, because we don't have any children to wait for. |
| 221 std::vector<std::string> category_groups; | 218 std::vector<std::string> category_groups; |
| 222 TraceLog::GetInstance()->GetKnownCategoryGroups(&category_groups); | 219 TraceLog::GetInstance()->GetKnownCategoryGroups(&category_groups); |
| 223 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 220 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 224 base::Bind(&TracingControllerImpl::OnDisableRecordingAcked, | 221 base::Bind(&TracingControllerImpl::OnDisableRecordingAcked, |
| 225 base::Unretained(this), category_groups)); | 222 base::Unretained(this), category_groups)); |
| 226 } | 223 } |
| 227 | 224 |
| 228 // Notify all child processes. | 225 // Notify all child processes. |
| 229 for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin(); | 226 for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) { |
| 230 it != trace_message_filters_.end(); ++it) { | |
| 231 it->get()->SendEndTracing(); | 227 it->get()->SendEndTracing(); |
| 232 } | 228 } |
| 233 return true; | 229 return true; |
| 234 } | 230 } |
| 235 | 231 |
| 236 bool TracingControllerImpl::EnableMonitoring( | 232 bool TracingControllerImpl::EnableMonitoring( |
| 237 const std::string& category_filter, | 233 const base::debug::CategoryFilter& filter, |
| 238 TracingController::Options options, | 234 TracingController::Options options, |
| 239 const EnableMonitoringDoneCallback& callback) { | 235 const EnableMonitoringDoneCallback& callback) { |
| 240 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 236 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 241 | 237 |
| 242 if (!can_enable_monitoring()) | 238 if (!can_enable_monitoring()) |
| 243 return false; | 239 return false; |
| 244 is_monitoring_ = true; | 240 is_monitoring_ = true; |
| 245 | 241 |
| 246 #if defined(OS_ANDROID) | 242 #if defined(OS_ANDROID) |
| 247 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); | 243 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); |
| 248 #endif | 244 #endif |
| 249 | 245 |
| 250 int monitoring_tracing_options = 0; | 246 int monitoring_tracing_options = 0; |
| 251 if (options & ENABLE_SAMPLING) | 247 if (options & ENABLE_SAMPLING) |
| 252 monitoring_tracing_options |= base::debug::TraceLog::MONITOR_SAMPLING; | 248 monitoring_tracing_options |= base::debug::TraceLog::MONITOR_SAMPLING; |
| 253 | 249 |
| 254 TraceLog::GetInstance()->SetEnabled( | 250 TraceLog::GetInstance()->SetEnabled( |
| 255 base::debug::CategoryFilter(category_filter), | 251 filter, base::debug::TraceLog::Options(monitoring_tracing_options)); |
| 256 static_cast<TraceLog::Options>(monitoring_tracing_options)); | |
| 257 | 252 |
| 258 // Notify all child processes. | 253 // Notify all child processes. |
| 259 for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin(); | 254 for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) { |
| 260 it != trace_message_filters_.end(); ++it) { | 255 it->get()->SendEnableMonitoring(filter.ToString(), |
| 261 it->get()->SendEnableMonitoring(category_filter, | 256 base::debug::TraceLog::Options(monitoring_tracing_options)); |
| 262 static_cast<TraceLog::Options>(monitoring_tracing_options)); | |
| 263 } | 257 } |
| 264 | 258 |
| 265 if (!callback.is_null()) | 259 if (!callback.is_null()) |
| 266 callback.Run(); | 260 callback.Run(); |
| 267 return true; | 261 return true; |
| 268 } | 262 } |
| 269 | 263 |
| 270 bool TracingControllerImpl::DisableMonitoring( | 264 bool TracingControllerImpl::DisableMonitoring( |
| 271 const DisableMonitoringDoneCallback& callback) { | 265 const DisableMonitoringDoneCallback& callback) { |
| 272 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 266 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 273 | 267 |
| 274 if (!can_disable_monitoring()) | 268 if (!can_disable_monitoring()) |
| 275 return false; | 269 return false; |
| 276 is_monitoring_ = false; | 270 is_monitoring_ = false; |
| 277 | 271 |
| 278 TraceLog::GetInstance()->SetDisabled(); | 272 TraceLog::GetInstance()->SetDisabled(); |
| 279 | 273 |
| 280 // Notify all child processes. | 274 // Notify all child processes. |
| 281 for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin(); | 275 for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) { |
| 282 it != trace_message_filters_.end(); ++it) { | |
| 283 it->get()->SendDisableMonitoring(); | 276 it->get()->SendDisableMonitoring(); |
| 284 } | 277 } |
| 285 | 278 |
| 286 if (!callback.is_null()) | 279 if (!callback.is_null()) |
| 287 callback.Run(); | 280 callback.Run(); |
| 288 return true; | 281 return true; |
| 289 } | 282 } |
| 290 | 283 |
| 291 void TracingControllerImpl::GetMonitoringStatus( | 284 void TracingControllerImpl::GetMonitoringStatus( |
| 292 bool* out_enabled, | 285 bool* out_enabled, |
| 293 std::string* out_category_filter, | 286 base::debug::CategoryFilter* out_filter, |
| 294 TracingController::Options* out_options) { | 287 TracingController::Options* out_options) { |
| 295 NOTIMPLEMENTED(); | 288 NOTIMPLEMENTED(); |
| 296 } | 289 } |
| 297 | 290 |
| 298 bool TracingControllerImpl::CaptureMonitoringSnapshot( | 291 void TracingControllerImpl::CaptureMonitoringSnapshot( |
| 299 const base::FilePath& result_file_path, | 292 const base::FilePath& result_file_path, |
| 300 const TracingFileResultCallback& callback) { | 293 const TracingFileResultCallback& callback) { |
| 301 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 294 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 302 | 295 |
| 303 if (!can_disable_monitoring()) | 296 if (!can_disable_monitoring()) |
| 304 return false; | 297 return; |
| 305 | 298 |
| 306 if (callback.is_null() && result_file_path.empty()) | 299 if (callback.is_null() && result_file_path.empty()) |
| 307 return false; | 300 return; |
| 308 | 301 |
| 309 pending_capture_monitoring_snapshot_done_callback_ = callback; | 302 pending_capture_monitoring_snapshot_done_callback_ = callback; |
| 310 monitoring_snapshot_file_.reset(new ResultFile(result_file_path)); | 303 monitoring_snapshot_file_.reset(new ResultFile(result_file_path)); |
| 311 | 304 |
| 305 // There could be a case where there are no child processes and filters_ |
| 306 // is empty. In that case we can immediately tell the subscriber that tracing |
| 307 // has ended. To avoid recursive calls back to the subscriber, we will just |
| 308 // use the existing asynchronous OnCaptureMonitoringSnapshotAcked code. |
| 312 // Count myself in pending_capture_monitoring_snapshot_ack_count_, | 309 // Count myself in pending_capture_monitoring_snapshot_ack_count_, |
| 313 // acked below. | 310 // acked below. |
| 314 pending_capture_monitoring_snapshot_ack_count_ = | 311 pending_capture_monitoring_snapshot_ack_count_ = filters_.size() + 1; |
| 315 trace_message_filters_.size() + 1; | |
| 316 | 312 |
| 317 // Handle special case of zero child processes by immediately telling the | 313 // Handle special case of zero child processes. |
| 318 // caller that capturing snapshot has ended. Use asynchronous | |
| 319 // OnCaptureMonitoringSnapshotAcked to avoid recursive call back to the | |
| 320 // caller. | |
| 321 if (pending_capture_monitoring_snapshot_ack_count_ == 1) { | 314 if (pending_capture_monitoring_snapshot_ack_count_ == 1) { |
| 322 // Ack asynchronously now, because we don't have any children to wait for. | 315 // Ack asynchronously now, because we don't have any children to wait for. |
| 323 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 316 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 324 base::Bind(&TracingControllerImpl::OnCaptureMonitoringSnapshotAcked, | 317 base::Bind(&TracingControllerImpl::OnCaptureMonitoringSnapshotAcked, |
| 325 base::Unretained(this))); | 318 base::Unretained(this))); |
| 326 } | 319 } |
| 327 | 320 |
| 328 // Notify all child processes. | 321 // Notify all child processes. |
| 329 for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin(); | 322 for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) { |
| 330 it != trace_message_filters_.end(); ++it) { | |
| 331 it->get()->SendCaptureMonitoringSnapshot(); | 323 it->get()->SendCaptureMonitoringSnapshot(); |
| 332 } | 324 } |
| 333 | 325 |
| 334 #if defined(OS_ANDROID) | 326 #if defined(OS_ANDROID) |
| 335 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); | 327 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); |
| 336 #endif | 328 #endif |
| 337 | |
| 338 return true; | |
| 339 } | 329 } |
| 340 | 330 |
| 341 bool TracingControllerImpl::GetTraceBufferPercentFull( | 331 bool TracingControllerImpl::GetTraceBufferPercentFull( |
| 342 const GetTraceBufferPercentFullCallback& callback) { | 332 const GetTraceBufferPercentFullCallback& callback) { |
| 343 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 333 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 344 | 334 |
| 345 if (!can_get_trace_buffer_percent_full() || callback.is_null()) | 335 if (!can_get_trace_buffer_percent_full() || callback.is_null()) |
| 346 return false; | 336 return false; |
| 347 | 337 |
| 348 pending_trace_buffer_percent_full_callback_ = callback; | 338 pending_trace_buffer_percent_full_callback_ = callback; |
| 349 | 339 |
| 350 // Count myself in pending_trace_buffer_percent_full_ack_count_, acked below. | 340 // Count myself in pending_trace_buffer_percent_full_ack_count_, acked below. |
| 351 pending_trace_buffer_percent_full_ack_count_ = | 341 pending_trace_buffer_percent_full_ack_count_ = filters_.size() + 1; |
| 352 trace_message_filters_.size() + 1; | |
| 353 maximum_trace_buffer_percent_full_ = 0; | 342 maximum_trace_buffer_percent_full_ = 0; |
| 354 | 343 |
| 355 // Handle special case of zero child processes. | 344 // Handle special case of zero child processes. |
| 356 if (pending_trace_buffer_percent_full_ack_count_ == 1) { | 345 if (pending_trace_buffer_percent_full_ack_count_ == 1) { |
| 357 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 346 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 358 base::Bind(&TracingControllerImpl::OnTraceBufferPercentFullReply, | 347 base::Bind(&TracingControllerImpl::OnTraceBufferPercentFullReply, |
| 359 base::Unretained(this), | 348 base::Unretained(this), |
| 360 TraceLog::GetInstance()->GetBufferPercentFull())); | 349 TraceLog::GetInstance()->GetBufferPercentFull())); |
| 361 } | 350 } |
| 362 | 351 |
| 363 // Notify all child processes. | 352 // Notify all child processes. |
| 364 for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin(); | 353 for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) { |
| 365 it != trace_message_filters_.end(); ++it) { | |
| 366 it->get()->SendGetTraceBufferPercentFull(); | 354 it->get()->SendGetTraceBufferPercentFull(); |
| 367 } | 355 } |
| 368 return true; | 356 return true; |
| 369 } | 357 } |
| 370 | 358 |
| 371 bool TracingControllerImpl::SetWatchEvent( | 359 void TracingControllerImpl::AddFilter(TraceMessageFilter* filter) { |
| 372 const std::string& category_name, | |
| 373 const std::string& event_name, | |
| 374 const WatchEventCallback& callback) { | |
| 375 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 376 | |
| 377 if (callback.is_null()) | |
| 378 return false; | |
| 379 | |
| 380 watch_category_name_ = category_name; | |
| 381 watch_event_name_ = event_name; | |
| 382 watch_event_callback_ = callback; | |
| 383 | |
| 384 TraceLog::GetInstance()->SetWatchEvent( | |
| 385 category_name, event_name, | |
| 386 base::Bind(&TracingControllerImpl::OnWatchEventMatched, | |
| 387 base::Unretained(this))); | |
| 388 | |
| 389 for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin(); | |
| 390 it != trace_message_filters_.end(); ++it) { | |
| 391 it->get()->SendSetWatchEvent(category_name, event_name); | |
| 392 } | |
| 393 return true; | |
| 394 } | |
| 395 | |
| 396 bool TracingControllerImpl::CancelWatchEvent() { | |
| 397 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 398 | |
| 399 if (!can_cancel_watch_event()) | |
| 400 return false; | |
| 401 | |
| 402 for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin(); | |
| 403 it != trace_message_filters_.end(); ++it) { | |
| 404 it->get()->SendCancelWatchEvent(); | |
| 405 } | |
| 406 | |
| 407 watch_event_callback_.Reset(); | |
| 408 return true; | |
| 409 } | |
| 410 | |
| 411 void TracingControllerImpl::AddTraceMessageFilter( | |
| 412 TraceMessageFilter* trace_message_filter) { | |
| 413 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 360 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
| 414 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 361 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 415 base::Bind(&TracingControllerImpl::AddTraceMessageFilter, | 362 base::Bind(&TracingControllerImpl::AddFilter, base::Unretained(this), |
| 416 base::Unretained(this), | 363 make_scoped_refptr(filter))); |
| 417 make_scoped_refptr(trace_message_filter))); | |
| 418 return; | 364 return; |
| 419 } | 365 } |
| 420 | 366 |
| 421 trace_message_filters_.insert(trace_message_filter); | 367 filters_.insert(filter); |
| 422 if (can_cancel_watch_event()) { | |
| 423 trace_message_filter->SendSetWatchEvent(watch_category_name_, | |
| 424 watch_event_name_); | |
| 425 } | |
| 426 if (can_disable_recording()) { | 368 if (can_disable_recording()) { |
| 427 trace_message_filter->SendBeginTracing( | 369 std::string cf_str = category_filter_.ToString(); |
| 428 TraceLog::GetInstance()->GetCurrentCategoryFilter().ToString(), | 370 filter->SendBeginTracing(cf_str, TraceLog::GetInstance()->trace_options()); |
| 429 TraceLog::GetInstance()->trace_options()); | |
| 430 } | 371 } |
| 431 } | 372 } |
| 432 | 373 |
| 433 void TracingControllerImpl::RemoveTraceMessageFilter( | 374 void TracingControllerImpl::RemoveFilter(TraceMessageFilter* filter) { |
| 434 TraceMessageFilter* trace_message_filter) { | |
| 435 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 375 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
| 436 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 376 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 437 base::Bind(&TracingControllerImpl::RemoveTraceMessageFilter, | 377 base::Bind(&TracingControllerImpl::RemoveFilter, base::Unretained(this), |
| 438 base::Unretained(this), | 378 make_scoped_refptr(filter))); |
| 439 make_scoped_refptr(trace_message_filter))); | |
| 440 return; | 379 return; |
| 441 } | 380 } |
| 442 | 381 |
| 443 trace_message_filters_.erase(trace_message_filter); | 382 filters_.erase(filter); |
| 444 } | 383 } |
| 445 | 384 |
| 446 void TracingControllerImpl::OnDisableRecordingAcked( | 385 void TracingControllerImpl::OnDisableRecordingAcked( |
| 447 const std::vector<std::string>& known_category_groups) { | 386 const std::vector<std::string>& known_category_groups) { |
| 448 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 387 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
| 449 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 388 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 450 base::Bind(&TracingControllerImpl::OnDisableRecordingAcked, | 389 base::Bind(&TracingControllerImpl::OnDisableRecordingAcked, |
| 451 base::Unretained(this), known_category_groups)); | 390 base::Unretained(this), known_category_groups)); |
| 452 return; | 391 return; |
| 453 } | 392 } |
| 454 | 393 |
| 455 // Merge known_category_groups with known_category_groups_ | 394 // Merge known_category_groups with known_category_groups_ |
| 456 known_category_groups_.insert(known_category_groups.begin(), | 395 known_category_groups_.insert(known_category_groups.begin(), |
| 457 known_category_groups.end()); | 396 known_category_groups.end()); |
| 458 | 397 |
| 459 if (pending_disable_recording_ack_count_ == 0) | 398 if (pending_disable_recording_ack_count_ == 0) |
| 460 return; | 399 return; |
| 461 | 400 |
| 462 if (--pending_disable_recording_ack_count_ == 1) { | 401 if (--pending_disable_recording_ack_count_ == 1) { |
| 463 // All acks from subprocesses have been received. Now flush the local trace. | 402 // All acks from subprocesses have been received. Now flush the local trace. |
| 464 // During or after this call, our OnLocalTraceDataCollected will be | 403 // During or after this call, our OnLocalTraceDataCollected will be |
| 465 // called with the last of the local trace data. | 404 // called with the last of the local trace data. |
| 466 TraceLog::GetInstance()->Flush( | 405 TraceLog::GetInstance()->Flush( |
| 467 base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected, | 406 base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected, |
| 468 base::Unretained(this))); | 407 base::Unretained(this))); |
| 469 return; | |
| 470 } | 408 } |
| 471 | 409 |
| 472 if (pending_disable_recording_ack_count_ != 0) | 410 if (pending_disable_recording_ack_count_ != 0) |
| 473 return; | 411 return; |
| 474 | 412 |
| 475 // All acks (including from the subprocesses and the local trace) have been | 413 // All acks (including from the subprocesses and the local trace) have been |
| 476 // received. | 414 // received. |
| 477 is_recording_ = false; | 415 is_recording_ = false; |
| 478 | 416 |
| 479 // Trigger callback if one is set. | 417 // Trigger callback if one is set. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 511 if (pending_capture_monitoring_snapshot_ack_count_ == 0) | 449 if (pending_capture_monitoring_snapshot_ack_count_ == 0) |
| 512 return; | 450 return; |
| 513 | 451 |
| 514 if (--pending_capture_monitoring_snapshot_ack_count_ == 1) { | 452 if (--pending_capture_monitoring_snapshot_ack_count_ == 1) { |
| 515 // All acks from subprocesses have been received. Now flush the local trace. | 453 // All acks from subprocesses have been received. Now flush the local trace. |
| 516 // During or after this call, our OnLocalMonitoringTraceDataCollected | 454 // During or after this call, our OnLocalMonitoringTraceDataCollected |
| 517 // will be called with the last of the local trace data. | 455 // will be called with the last of the local trace data. |
| 518 TraceLog::GetInstance()->FlushButLeaveBufferIntact( | 456 TraceLog::GetInstance()->FlushButLeaveBufferIntact( |
| 519 base::Bind(&TracingControllerImpl::OnLocalMonitoringTraceDataCollected, | 457 base::Bind(&TracingControllerImpl::OnLocalMonitoringTraceDataCollected, |
| 520 base::Unretained(this))); | 458 base::Unretained(this))); |
| 521 return; | |
| 522 } | 459 } |
| 523 | 460 |
| 524 if (pending_capture_monitoring_snapshot_ack_count_ != 0) | 461 if (pending_capture_monitoring_snapshot_ack_count_ != 0) |
| 525 return; | 462 return; |
| 526 | 463 |
| 527 if (monitoring_snapshot_file_) { | 464 if (monitoring_snapshot_file_) { |
| 528 monitoring_snapshot_file_->Close( | 465 monitoring_snapshot_file_->Close( |
| 529 base::Bind(&TracingControllerImpl::OnMonitoringSnapshotFileClosed, | 466 base::Bind(&TracingControllerImpl::OnMonitoringSnapshotFileClosed, |
| 530 base::Unretained(this))); | 467 base::Unretained(this))); |
| 531 } | 468 } |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 625 if (pending_trace_buffer_percent_full_ack_count_ == 1) { | 562 if (pending_trace_buffer_percent_full_ack_count_ == 1) { |
| 626 // The last ack represents local trace, so we need to ack it now. Note that | 563 // The last ack represents local trace, so we need to ack it now. Note that |
| 627 // this code only executes if there were child processes. | 564 // this code only executes if there were child processes. |
| 628 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 565 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 629 base::Bind(&TracingControllerImpl::OnTraceBufferPercentFullReply, | 566 base::Bind(&TracingControllerImpl::OnTraceBufferPercentFullReply, |
| 630 base::Unretained(this), | 567 base::Unretained(this), |
| 631 TraceLog::GetInstance()->GetBufferPercentFull())); | 568 TraceLog::GetInstance()->GetBufferPercentFull())); |
| 632 } | 569 } |
| 633 } | 570 } |
| 634 | 571 |
| 635 void TracingControllerImpl::OnWatchEventMatched() { | |
| 636 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | |
| 637 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | |
| 638 base::Bind(&TracingControllerImpl::OnWatchEventMatched, | |
| 639 base::Unretained(this))); | |
| 640 } | |
| 641 | |
| 642 if (!watch_event_callback_.is_null()) | |
| 643 watch_event_callback_.Run(); | |
| 644 } | |
| 645 | |
| 646 } // namespace content | 572 } // namespace content |
| OLD | NEW |