summaryrefslogtreecommitdiffstats
path: root/content/browser/tracing
diff options
context:
space:
mode:
authorwangxianzhu@chromium.org <wangxianzhu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-19 23:50:29 +0000
committerwangxianzhu@chromium.org <wangxianzhu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-19 23:50:29 +0000
commite7f04cea9fb2f3682166ed9be645a0f1fc6b802f (patch)
tree3b8e75d8088771e1264ddd0e75513b0bad8a5b1a /content/browser/tracing
parent3110b12ee2f239e0f0fb02f1255d1cfb31c8d9ef (diff)
downloadchromium_src-e7f04cea9fb2f3682166ed9be645a0f1fc6b802f.zip
chromium_src-e7f04cea9fb2f3682166ed9be645a0f1fc6b802f.tar.gz
chromium_src-e7f04cea9fb2f3682166ed9be645a0f1fc6b802f.tar.bz2
Allow TracingController output trace data to specified file
Sometimes we need to let TracingController output traces to specified file, e.g. trace-startup (which will be migrated from TraceController to TracingController). Also fixed the problem of IO operations in UI thread. BUG=none TEST=TracingControllerTest.EnableAndDisableRecordingWithFilePath TEST=TracingControllerTest.EnableCaptureAndDisableMonitoringWithFilePath R=joi@chromium.org, nduca@chromium.org Review URL: https://codereview.chromium.org/66893003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@236071 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/tracing')
-rw-r--r--content/browser/tracing/trace_message_filter.cc3
-rw-r--r--content/browser/tracing/tracing_controller_browsertest.cc205
-rw-r--r--content/browser/tracing/tracing_controller_impl.cc185
-rw-r--r--content/browser/tracing/tracing_controller_impl.h30
4 files changed, 290 insertions, 133 deletions
diff --git a/content/browser/tracing/trace_message_filter.cc b/content/browser/tracing/trace_message_filter.cc
index 3de5d38..f8cb4fa 100644
--- a/content/browser/tracing/trace_message_filter.cc
+++ b/content/browser/tracing/trace_message_filter.cc
@@ -150,7 +150,8 @@ void TraceMessageFilter::OnMonitoringTraceDataCollected(
const std::string& data) {
scoped_refptr<base::RefCountedString> data_ptr(new base::RefCountedString());
data_ptr->data() = data;
- TracingControllerImpl::GetInstance()->OnTraceDataCollected(data_ptr);
+ TracingControllerImpl::GetInstance()->OnMonitoringTraceDataCollected(
+ data_ptr);
}
void TraceMessageFilter::OnTraceNotification(int notification) {
diff --git a/content/browser/tracing/tracing_controller_browsertest.cc b/content/browser/tracing/tracing_controller_browsertest.cc
index a3a589f..2f2031a 100644
--- a/content/browser/tracing/tracing_controller_browsertest.cc
+++ b/content/browser/tracing/tracing_controller_browsertest.cc
@@ -47,13 +47,14 @@ class TracingControllerTest : public ContentBrowserTest {
}
void DisableRecordingDoneCallbackTest(base::Closure quit_callback,
- scoped_ptr<base::FilePath> file_path) {
+ const base::FilePath& file_path) {
disable_recording_done_callback_count_++;
- EXPECT_TRUE(PathExists(*file_path));
+ EXPECT_TRUE(PathExists(file_path));
int64 file_size;
- file_util::GetFileSize(*file_path, &file_size);
+ file_util::GetFileSize(file_path, &file_size);
EXPECT_TRUE(file_size > 0);
quit_callback.Run();
+ last_actual_recording_file_path_ = file_path;
}
void EnableMonitoringDoneCallbackTest(base::Closure quit_callback) {
@@ -67,13 +68,14 @@ class TracingControllerTest : public ContentBrowserTest {
}
void CaptureMonitoringSnapshotDoneCallbackTest(
- base::Closure quit_callback, scoped_ptr<base::FilePath> file_path) {
+ base::Closure quit_callback, const base::FilePath& file_path) {
capture_monitoring_snapshot_done_callback_count_++;
- EXPECT_TRUE(PathExists(*file_path));
+ EXPECT_TRUE(PathExists(file_path));
int64 file_size;
- file_util::GetFileSize(*file_path, &file_size);
+ file_util::GetFileSize(file_path, &file_size);
EXPECT_TRUE(file_size > 0);
quit_callback.Run();
+ last_actual_monitoring_file_path_ = file_path;
}
int get_categories_done_callback_count() const {
@@ -100,6 +102,91 @@ class TracingControllerTest : public ContentBrowserTest {
return capture_monitoring_snapshot_done_callback_count_;
}
+ base::FilePath last_actual_recording_file_path() const {
+ return last_actual_recording_file_path_;
+ }
+
+ base::FilePath last_actual_monitoring_file_path() const {
+ return last_actual_monitoring_file_path_;
+ }
+
+ void TestEnableAndDisableRecording(const base::FilePath& result_file_path) {
+ Navigate(shell());
+
+ TracingController* controller = TracingController::GetInstance();
+
+ {
+ base::RunLoop run_loop;
+ TracingController::EnableRecordingDoneCallback callback =
+ base::Bind(&TracingControllerTest::EnableRecordingDoneCallbackTest,
+ base::Unretained(this),
+ run_loop.QuitClosure());
+ bool result = controller->EnableRecording(
+ base::debug::CategoryFilter(""), TracingController::Options(),
+ callback);
+ EXPECT_TRUE(result);
+ run_loop.Run();
+ EXPECT_EQ(enable_recording_done_callback_count(), 1);
+ }
+
+ {
+ base::RunLoop run_loop;
+ TracingController::TracingFileResultCallback callback =
+ base::Bind(&TracingControllerTest::DisableRecordingDoneCallbackTest,
+ base::Unretained(this),
+ run_loop.QuitClosure());
+ bool result = controller->DisableRecording(result_file_path, callback);
+ EXPECT_TRUE(result);
+ run_loop.Run();
+ EXPECT_EQ(disable_recording_done_callback_count(), 1);
+ }
+ }
+
+ void TestEnableCaptureAndDisableMonitoring(
+ const base::FilePath& result_file_path) {
+ Navigate(shell());
+
+ TracingController* controller = TracingController::GetInstance();
+
+ {
+ base::RunLoop run_loop;
+ TracingController::EnableMonitoringDoneCallback callback =
+ base::Bind(&TracingControllerTest::EnableMonitoringDoneCallbackTest,
+ base::Unretained(this),
+ run_loop.QuitClosure());
+ bool result = controller->EnableMonitoring(
+ base::debug::CategoryFilter(""), TracingController::ENABLE_SAMPLING,
+ callback);
+ EXPECT_TRUE(result);
+ run_loop.Run();
+ EXPECT_EQ(enable_monitoring_done_callback_count(), 1);
+ }
+
+ {
+ base::RunLoop run_loop;
+ TracingController::TracingFileResultCallback callback =
+ base::Bind(&TracingControllerTest::
+ CaptureMonitoringSnapshotDoneCallbackTest,
+ base::Unretained(this),
+ run_loop.QuitClosure());
+ controller->CaptureMonitoringSnapshot(result_file_path, callback);
+ run_loop.Run();
+ EXPECT_EQ(capture_monitoring_snapshot_done_callback_count(), 1);
+ }
+
+ {
+ base::RunLoop run_loop;
+ TracingController::DisableMonitoringDoneCallback callback =
+ base::Bind(&TracingControllerTest::DisableMonitoringDoneCallbackTest,
+ base::Unretained(this),
+ run_loop.QuitClosure());
+ bool result = controller->DisableMonitoring(callback);
+ EXPECT_TRUE(result);
+ run_loop.Run();
+ EXPECT_EQ(disable_monitoring_done_callback_count(), 1);
+ }
+ }
+
private:
int get_categories_done_callback_count_;
int enable_recording_done_callback_count_;
@@ -107,6 +194,8 @@ class TracingControllerTest : public ContentBrowserTest {
int enable_monitoring_done_callback_count_;
int disable_monitoring_done_callback_count_;
int capture_monitoring_snapshot_done_callback_count_;
+ base::FilePath last_actual_recording_file_path_;
+ base::FilePath last_actual_monitoring_file_path_;
};
IN_PROC_BROWSER_TEST_F(TracingControllerTest, GetCategories) {
@@ -125,78 +214,58 @@ IN_PROC_BROWSER_TEST_F(TracingControllerTest, GetCategories) {
}
IN_PROC_BROWSER_TEST_F(TracingControllerTest, EnableAndDisableRecording) {
+ TestEnableAndDisableRecording(base::FilePath());
+}
+
+IN_PROC_BROWSER_TEST_F(TracingControllerTest,
+ EnableAndDisableRecordingWithFilePath) {
+ base::FilePath file_path;
+ file_util::CreateTemporaryFile(&file_path);
+ TestEnableAndDisableRecording(file_path);
+ EXPECT_EQ(file_path.value(), last_actual_recording_file_path().value());
+}
+
+IN_PROC_BROWSER_TEST_F(TracingControllerTest,
+ EnableAndDisableRecordingWithEmptyFileAndNullCallback) {
Navigate(shell());
TracingController* controller = TracingController::GetInstance();
-
- {
- base::RunLoop run_loop;
- TracingController::EnableRecordingDoneCallback callback =
- base::Bind(&TracingControllerTest::EnableRecordingDoneCallbackTest,
- base::Unretained(this),
- run_loop.QuitClosure());
- bool result = controller->EnableRecording(base::debug::CategoryFilter("*"),
- TracingController::Options(), callback);
- EXPECT_TRUE(result);
- run_loop.Run();
- EXPECT_EQ(enable_recording_done_callback_count(), 1);
- }
-
- {
- base::RunLoop run_loop;
- TracingController::TracingFileResultCallback callback =
- base::Bind(&TracingControllerTest::DisableRecordingDoneCallbackTest,
- base::Unretained(this),
- run_loop.QuitClosure());
- bool result = controller->DisableRecording(callback);
- EXPECT_TRUE(result);
- run_loop.Run();
- EXPECT_EQ(disable_recording_done_callback_count(), 1);
- }
+ EXPECT_TRUE(controller->EnableRecording(
+ base::debug::CategoryFilter(""), TracingController::Options(),
+ TracingController::EnableRecordingDoneCallback()));
+ EXPECT_TRUE(controller->DisableRecording(
+ base::FilePath(), TracingController::TracingFileResultCallback()));
+ base::RunLoop().RunUntilIdle();
}
IN_PROC_BROWSER_TEST_F(TracingControllerTest,
EnableCaptureAndDisableMonitoring) {
+ TestEnableCaptureAndDisableMonitoring(base::FilePath());
+}
+
+IN_PROC_BROWSER_TEST_F(TracingControllerTest,
+ EnableCaptureAndDisableMonitoringWithFilePath) {
+ base::FilePath file_path;
+ file_util::CreateTemporaryFile(&file_path);
+ TestEnableCaptureAndDisableMonitoring(file_path);
+ EXPECT_EQ(file_path.value(), last_actual_monitoring_file_path().value());
+}
+
+IN_PROC_BROWSER_TEST_F(
+ TracingControllerTest,
+ EnableCaptureAndDisableMonitoringWithEmptyFileAndNullCallback) {
Navigate(shell());
TracingController* controller = TracingController::GetInstance();
-
- {
- base::RunLoop run_loop;
- TracingController::EnableMonitoringDoneCallback callback =
- base::Bind(&TracingControllerTest::EnableMonitoringDoneCallbackTest,
- base::Unretained(this),
- run_loop.QuitClosure());
- bool result = controller->EnableMonitoring(base::debug::CategoryFilter("*"),
- TracingController::ENABLE_SAMPLING, callback);
- EXPECT_TRUE(result);
- run_loop.Run();
- EXPECT_EQ(enable_monitoring_done_callback_count(), 1);
- }
-
- {
- base::RunLoop run_loop;
- TracingController::TracingFileResultCallback callback =
- base::Bind(&TracingControllerTest::
- CaptureMonitoringSnapshotDoneCallbackTest,
- base::Unretained(this),
- run_loop.QuitClosure());
- controller->CaptureMonitoringSnapshot(callback);
- run_loop.Run();
- EXPECT_EQ(capture_monitoring_snapshot_done_callback_count(), 1);
- }
-
- {
- base::RunLoop run_loop;
- TracingController::DisableMonitoringDoneCallback callback =
- base::Bind(&TracingControllerTest::DisableMonitoringDoneCallbackTest,
- base::Unretained(this),
- run_loop.QuitClosure());
- bool result = controller->DisableMonitoring(callback);
- EXPECT_TRUE(result);
- run_loop.Run();
- EXPECT_EQ(disable_monitoring_done_callback_count(), 1);
- }
+ EXPECT_TRUE(controller->EnableMonitoring(
+ base::debug::CategoryFilter(""), TracingController::ENABLE_SAMPLING,
+ TracingController::EnableMonitoringDoneCallback()));
+ controller->CaptureMonitoringSnapshot(
+ base::FilePath(), TracingController::TracingFileResultCallback());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(controller->DisableMonitoring(
+ TracingController::DisableMonitoringDoneCallback()));
+ base::RunLoop().RunUntilIdle();
}
} // namespace content
diff --git a/content/browser/tracing/tracing_controller_impl.cc b/content/browser/tracing/tracing_controller_impl.cc
index d2e8a31..6eea271 100644
--- a/content/browser/tracing/tracing_controller_impl.cc
+++ b/content/browser/tracing/tracing_controller_impl.cc
@@ -28,15 +28,94 @@ TracingController* TracingController::GetInstance() {
return TracingControllerImpl::GetInstance();
}
+class TracingControllerImpl::ResultFile {
+ public:
+ explicit ResultFile(const base::FilePath& path);
+ void Write(const scoped_refptr<base::RefCountedString>& events_str_ptr) {
+ BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+ base::Bind(&TracingControllerImpl::ResultFile::WriteTask,
+ base::Unretained(this), events_str_ptr));
+ }
+ void Close(const base::Closure& callback) {
+ BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+ base::Bind(&TracingControllerImpl::ResultFile::CloseTask,
+ base::Unretained(this), callback));
+ }
+ const base::FilePath& path() const { return path_; }
+
+ private:
+ void OpenTask();
+ void WriteTask(const scoped_refptr<base::RefCountedString>& events_str_ptr);
+ void CloseTask(const base::Closure& callback);
+
+ FILE* file_;
+ base::FilePath path_;
+ bool has_at_least_one_result_;
+
+ DISALLOW_COPY_AND_ASSIGN(ResultFile);
+};
+
+TracingControllerImpl::ResultFile::ResultFile(const base::FilePath& path)
+ : file_(NULL),
+ path_(path),
+ has_at_least_one_result_(false) {
+ BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+ base::Bind(&TracingControllerImpl::ResultFile::OpenTask,
+ base::Unretained(this)));
+}
+
+void TracingControllerImpl::ResultFile::OpenTask() {
+ if (path_.empty())
+ file_util::CreateTemporaryFile(&path_);
+ file_ = file_util::OpenFile(path_, "w");
+ if (!file_) {
+ LOG(ERROR) << "Failed to open " << path_.value();
+ return;
+ }
+ const char* preamble = "{\"traceEvents\": [";
+ size_t written = fwrite(preamble, strlen(preamble), 1, file_);
+ DCHECK(written == 1);
+}
+
+void TracingControllerImpl::ResultFile::WriteTask(
+ const scoped_refptr<base::RefCountedString>& events_str_ptr) {
+ if (!file_)
+ return;
+
+ // If there is already a result in the file, then put a commma
+ // before the next batch of results.
+ if (has_at_least_one_result_)
+ fwrite(",", 1, 1, file_);
+ has_at_least_one_result_ = true;
+ size_t written = fwrite(events_str_ptr->data().c_str(),
+ events_str_ptr->data().size(), 1,
+ file_);
+ DCHECK(written == 1);
+}
+
+void TracingControllerImpl::ResultFile::CloseTask(
+ const base::Closure& callback) {
+ if (!file_)
+ return;
+
+ const char* trailout = "]}";
+ size_t written = fwrite(trailout, strlen(trailout), 1, file_);
+ DCHECK(written == 1);
+ file_util::CloseFile(file_);
+ file_ = NULL;
+
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
+}
+
+
TracingControllerImpl::TracingControllerImpl() :
pending_disable_recording_ack_count_(0),
pending_capture_monitoring_snapshot_ack_count_(0),
is_recording_(false),
is_monitoring_(false),
+ trace_options_(TraceLog::RECORD_UNTIL_FULL),
category_filter_(
- base::debug::CategoryFilter::kDefaultCategoryFilterString),
- result_file_(0),
- result_file_has_at_least_one_result_(false) {
+ base::debug::CategoryFilter::kDefaultCategoryFilterString) {
}
TracingControllerImpl::~TracingControllerImpl() {
@@ -59,7 +138,7 @@ void TracingControllerImpl::GetCategories(
EnableRecording(base::debug::CategoryFilter("*"),
TracingController::Options(),
EnableRecordingDoneCallback());
- DisableRecording(TracingFileResultCallback());
+ DisableRecording(base::FilePath(), TracingFileResultCallback());
}
bool TracingControllerImpl::EnableRecording(
@@ -94,6 +173,7 @@ bool TracingControllerImpl::EnableRecording(
}
bool TracingControllerImpl::DisableRecording(
+ const base::FilePath& result_file_path,
const TracingFileResultCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -111,17 +191,8 @@ bool TracingControllerImpl::DisableRecording(
TraceLog::GetInstance()->AddClockSyncMetadataEvent();
#endif
- // We don't need to create a temporary file when getting categories.
- if (pending_get_categories_done_callback_.is_null()) {
- base::FilePath temporary_file;
- file_util::CreateTemporaryFile(&temporary_file);
- result_file_path_.reset(new base::FilePath(temporary_file));
- result_file_ = file_util::OpenFile(*result_file_path_, "w");
- result_file_has_at_least_one_result_ = false;
- const char* preamble = "{\"traceEvents\": [";
- size_t written = fwrite(preamble, strlen(preamble), 1, result_file_);
- DCHECK(written == 1);
- }
+ if (!callback.is_null() || !result_file_path.empty())
+ result_file_.reset(new ResultFile(result_file_path));
// There could be a case where there are no child processes and filters_
// is empty. In that case we can immediately tell the subscriber that tracing
@@ -203,6 +274,7 @@ void TracingControllerImpl::GetMonitoringStatus(
}
void TracingControllerImpl::CaptureMonitoringSnapshot(
+ const base::FilePath& result_file_path,
const TracingFileResultCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -211,14 +283,8 @@ void TracingControllerImpl::CaptureMonitoringSnapshot(
pending_capture_monitoring_snapshot_done_callback_ = callback;
- base::FilePath temporary_file;
- file_util::CreateTemporaryFile(&temporary_file);
- result_file_path_.reset(new base::FilePath(temporary_file));
- result_file_ = file_util::OpenFile(*result_file_path_, "w");
- result_file_has_at_least_one_result_ = false;
- const char* preamble = "{\"traceEvents\": [";
- size_t written = fwrite(preamble, strlen(preamble), 1, result_file_);
- DCHECK(written == 1);
+ if (!callback.is_null() || !result_file_path.empty())
+ monitoring_snapshot_file_.reset(new ResultFile(result_file_path));
// There could be a case where there are no child processes and filters_
// is empty. In that case we can immediately tell the subscriber that tracing
@@ -308,15 +374,24 @@ void TracingControllerImpl::OnDisableRecordingAcked(
if (!pending_get_categories_done_callback_.is_null()) {
pending_get_categories_done_callback_.Run(known_category_groups_);
pending_get_categories_done_callback_.Reset();
- } else if (!pending_disable_recording_done_callback_.is_null()) {
- const char* trailout = "]}";
- size_t written = fwrite(trailout, strlen(trailout), 1, result_file_);
- DCHECK(written == 1);
- file_util::CloseFile(result_file_);
- result_file_ = 0;
- pending_disable_recording_done_callback_.Run(result_file_path_.Pass());
+ } else if (result_file_) {
+ result_file_->Close(
+ base::Bind(&TracingControllerImpl::OnResultFileClosed,
+ base::Unretained(this)));
+ }
+}
+
+void TracingControllerImpl::OnResultFileClosed() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (!result_file_)
+ return;
+
+ if (!pending_disable_recording_done_callback_.is_null()) {
+ pending_disable_recording_done_callback_.Run(result_file_->path());
pending_disable_recording_done_callback_.Reset();
}
+ result_file_.reset();
}
void TracingControllerImpl::OnCaptureMonitoringSnapshotAcked() {
@@ -342,16 +417,25 @@ void TracingControllerImpl::OnCaptureMonitoringSnapshotAcked() {
if (pending_capture_monitoring_snapshot_ack_count_ != 0)
return;
+ if (monitoring_snapshot_file_) {
+ monitoring_snapshot_file_->Close(
+ base::Bind(&TracingControllerImpl::OnMonitoringSnapshotFileClosed,
+ base::Unretained(this)));
+ }
+}
+
+void TracingControllerImpl::OnMonitoringSnapshotFileClosed() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (!monitoring_snapshot_file_)
+ return;
+
if (!pending_capture_monitoring_snapshot_done_callback_.is_null()) {
- const char* trailout = "]}";
- size_t written = fwrite(trailout, strlen(trailout), 1, result_file_);
- DCHECK(written == 1);
- file_util::CloseFile(result_file_);
- result_file_ = 0;
pending_capture_monitoring_snapshot_done_callback_.Run(
- result_file_path_.Pass());
+ monitoring_snapshot_file_->path());
pending_capture_monitoring_snapshot_done_callback_.Reset();
}
+ monitoring_snapshot_file_.reset();
}
void TracingControllerImpl::OnTraceDataCollected(
@@ -365,22 +449,21 @@ void TracingControllerImpl::OnTraceDataCollected(
return;
}
- // Drop trace events if we are just getting categories.
- if (!pending_get_categories_done_callback_.is_null())
- return;
+ if (result_file_)
+ result_file_->Write(events_str_ptr);
+}
- // If there is already a result in the file, then put a commma
- // before the next batch of results.
- if (result_file_has_at_least_one_result_) {
- size_t written = fwrite(",", 1, 1, result_file_);
- DCHECK(written == 1);
- } else {
- result_file_has_at_least_one_result_ = true;
+void TracingControllerImpl::OnMonitoringTraceDataCollected(
+ const scoped_refptr<base::RefCountedString>& events_str_ptr) {
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(&TracingControllerImpl::OnMonitoringTraceDataCollected,
+ base::Unretained(this), events_str_ptr));
+ return;
}
- size_t written = fwrite(events_str_ptr->data().c_str(),
- events_str_ptr->data().size(), 1,
- result_file_);
- DCHECK(written == 1);
+
+ if (!monitoring_snapshot_file_)
+ monitoring_snapshot_file_->Write(events_str_ptr);
}
void TracingControllerImpl::OnLocalTraceDataCollected(
@@ -402,7 +485,7 @@ void TracingControllerImpl::OnLocalMonitoringTraceDataCollected(
const scoped_refptr<base::RefCountedString>& events_str_ptr,
bool has_more_events) {
if (events_str_ptr->data().size())
- OnTraceDataCollected(events_str_ptr);
+ OnMonitoringTraceDataCollected(events_str_ptr);
if (has_more_events)
return;
diff --git a/content/browser/tracing/tracing_controller_impl.h b/content/browser/tracing/tracing_controller_impl.h
index 175365e..cbc05aa 100644
--- a/content/browser/tracing/tracing_controller_impl.h
+++ b/content/browser/tracing/tracing_controller_impl.h
@@ -9,6 +9,7 @@
#include <string>
#include <vector>
+#include "base/files/file_path.h"
#include "base/lazy_instance.h"
#include "content/public/browser/trace_subscriber.h"
#include "content/public/browser/tracing_controller.h"
@@ -17,8 +18,7 @@ namespace content {
class TraceMessageFilter;
-class TracingControllerImpl :
- public TracingController, public TraceSubscriber {
+class TracingControllerImpl : public TracingController {
public:
static TracingControllerImpl* GetInstance();
@@ -30,6 +30,7 @@ class TracingControllerImpl :
TracingController::Options options,
const EnableRecordingDoneCallback& callback) OVERRIDE;
virtual bool DisableRecording(
+ const base::FilePath& result_file_path,
const TracingFileResultCallback& callback) OVERRIDE;
virtual bool EnableMonitoring(const base::debug::CategoryFilter& filter,
TracingController::Options options,
@@ -41,10 +42,12 @@ class TracingControllerImpl :
base::debug::CategoryFilter* out_filter,
TracingController::Options* out_options) OVERRIDE;
virtual void CaptureMonitoringSnapshot(
+ const base::FilePath& result_file_path,
const TracingFileResultCallback& callback) OVERRIDE;
private:
typedef std::set<scoped_refptr<TraceMessageFilter> > FilterMap;
+ class ResultFile;
friend struct base::DefaultLazyInstanceTraits<TracingControllerImpl>;
friend class TraceMessageFilter;
@@ -52,16 +55,12 @@ class TracingControllerImpl :
TracingControllerImpl();
virtual ~TracingControllerImpl();
- // TraceSubscriber implementation.
- virtual void OnTraceDataCollected(
- const scoped_refptr<base::RefCountedString>& events_str_ptr) OVERRIDE;
-
bool can_enable_recording() const {
return !is_recording_;
}
bool can_disable_recording() const {
- return is_recording_ && pending_disable_recording_ack_count_ == 0;
+ return is_recording_ && !result_file_;
}
bool can_enable_monitoring() const {
@@ -69,14 +68,18 @@ class TracingControllerImpl :
}
bool can_disable_monitoring() const {
- return is_monitoring_ &&
- pending_capture_monitoring_snapshot_ack_count_ == 0;
+ return is_monitoring_ && !monitoring_snapshot_file_;
}
// Methods for use by TraceMessageFilter.
void AddFilter(TraceMessageFilter* filter);
void RemoveFilter(TraceMessageFilter* filter);
+ void OnTraceDataCollected(
+ const scoped_refptr<base::RefCountedString>& events_str_ptr);
+ void OnMonitoringTraceDataCollected(
+ const scoped_refptr<base::RefCountedString>& events_str_ptr);
+
// Callback of TraceLog::Flush() for the local trace.
void OnLocalTraceDataCollected(
const scoped_refptr<base::RefCountedString>& events_str_ptr,
@@ -88,7 +91,10 @@ class TracingControllerImpl :
void OnDisableRecordingAcked(
const std::vector<std::string>& known_category_groups);
+ void OnResultFileClosed();
+
void OnCaptureMonitoringSnapshotAcked();
+ void OnMonitoringSnapshotFileClosed();
FilterMap filters_;
// Pending acks for DisableRecording.
@@ -103,10 +109,8 @@ class TracingControllerImpl :
std::set<std::string> known_category_groups_;
base::debug::TraceLog::Options trace_options_;
base::debug::CategoryFilter category_filter_;
- FILE* result_file_;
- scoped_ptr<base::FilePath> result_file_path_;
- bool result_file_has_at_least_one_result_;
-
+ scoped_ptr<ResultFile> result_file_;
+ scoped_ptr<ResultFile> monitoring_snapshot_file_;
DISALLOW_COPY_AND_ASSIGN(TracingControllerImpl);
};