Commit ffc24720 authored by Brett Wilson's avatar Brett Wilson Committed by Commit Bot

Remove chrome://profiler WebUI.

This removes the WebUI frontend for the task profiler. The underlying
infrastructure will be removed in a separate pass.

This saves about 30KB binary size.

BUG=739505

Cq-Include-Trybots: master.tryserver.chromium.linux:closure_compilation
Change-Id: I9d871e028168104496a0ab7f68aa45e428cba278
Reviewed-on: https://chromium-review.googlesource.com/650947
Commit-Queue: Brett Wilson <brettw@chromium.org>
Reviewed-by: default avatarJohn Abd-El-Malek <jam@chromium.org>
Cr-Commit-Position: refs/heads/master@{#500031}
parent f7644527
......@@ -1398,8 +1398,6 @@ split_static_library("browser") {
"tab_contents/tab_util.h",
"task_manager/web_contents_tags.cc",
"task_manager/web_contents_tags.h",
"task_profiler/task_profiler_data_serializer.cc",
"task_profiler/task_profiler_data_serializer.h",
"themes/theme_service_win.cc",
"themes/theme_service_win.h",
"thumbnails/thumbnail_list_source.cc",
......
......@@ -452,8 +452,6 @@
<include name="IDR_PRINT_PREVIEW_IMAGES_MOBILE_SHARED"
file="resources\print_preview\images\mobile_shared.png" type="BINDATA" />
</if>
<include name="IDR_PROFILER_HTML" file="resources\profiler\profiler.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" compress="gzip" />
<include name="IDR_PROFILER_JS" file="resources\profiler\profiler.js" flattenhtml="true" type="BINDATA" compress="gzip" />
<include name="IDR_SITE_ENGAGEMENT_HTML" file="resources\engagement\site_engagement.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" compress="gzip" />
<include name="IDR_SITE_ENGAGEMENT_JS" file="resources\engagement\site_engagement.js" flattenhtml="true" type="BINDATA" compress="gzip" />
<include name="IDR_SITE_ENGAGEMENT_MOJO_JS" file="${root_gen_dir}\chrome\browser\engagement\site_engagement_details.mojom.js" use_base_dir="false" type="BINDATA" compress="gzip" />
......
eroman@chromium.org
jar@chromium.org
# COMPONENT: Internals>Metrics
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
<script src="chrome://resources/js/load_time_data.js"></script>
<script src="chrome://resources/js/util.js"></script>
<script src="chrome://profiler/strings.js"></script>
<script src="chrome://profiler/profiler.js"></script>
<style>
body {
font-size: 80%;
}
/*
* The following styles are for a TABLE that uses a thin collapsed border, and
* has a blue heading. When you hover over rows, they turn yellow.
*/
table.results-table {
border-collapse: collapse;
}
table.results-table,
.results-table th,
.results-table td {
border: 1px solid #777;
padding-left: 4px;
padding-right: 4px;
}
.results-table th {
background: rgb(224,236,255);
}
.results-table tbody tr:hover {
background-color: rgb(255, 255, 187);
}
/*
* Make the column headers change the mouse to a "hand" cursor, sine they are
* clickable.
*/
.results-table th {
cursor: pointer;
}
/*
* This is row which displays aggregate totals for each column.
*/
.results-table .aggregator-row {
background: rgb(255, 204, 153);
}
/*
* This is the row at the end of tables which explains how many rows were shown,
* and how many were hidden.
*/
.results-table .truncation-row {
background: #eee;
}
/*---------------------------------------------------------------------------*/
/*
* When grouping data, the table for each bucket is wrapped in a DIV with this
* class. Used to add a bit of spacing between groups.
*/
.group-container {
margin-bottom: 2ex;
margin-top: 2ex;
}
/*
* The title for each group is enclosed in a DIV of the following class.
*/
.group-title-container {
font-size: 140%;
margin-bottom: 1ex;
}
/* Styling to make a span look like a clickable link */
.pseudo-link {
color: blue;
cursor: pointer;
text-decoration: underline;
}
.selected-snapshot {
color: purple;
font-weight: bold;
}
#snapshot-selection-summary {
color: green;
font-style: italic;
font-weight: bold;
margin-top: 1ex;
}
.errormsg {
color: red;
}
</style>
</head>
<body>
<table width=100%>
<tr>
<td>
<b>Save:</b><button id=save-snapshots-button>Save</button>
<b>Restore:</b> <input type=file id=snapshot-file-loader>
<span id=file-load-error hidden class=errormsg></span>
</td>
<td align=right>
<a target="_blank"
href="https://sites.google.com/a/chromium.org/dev/developers/threaded-task-tracking">
Profiler Documentation
</a>
</td>
</tr>
</table>
<hr>
<table width=100%>
<tr>
<td>
<b>Group by: </b> <span id=group-by-container></span>
<b>Sort by: </b> <span id=sort-by-container></span>
</td>
<td align=right>
<span id=snapshots-link class=pseudo-link>[snapshots]</span>
<span id=edit-columns-link class=pseudo-link>[columns]</span>
<input type='search' incremental id='filter-search'>
</td>
</tr>
<tr id=edit-columns-row style='display:none'>
<td colspan=2>
<div>
<b>Merge: </b><span id=column-merge-toggles-container></span>
<label><input type=checkbox id='merge-similar-threads-checkbox' checked>
Merge similar threads.</label>
</div>
<div>
<b>Show: </b><span id=column-toggles-container></span>
</div>
</td>
</tr>
<tr id=snapshots-row style='display:none'>
<td colspan=2>
<button id=take-snapshot-button>Add snapshot</button>
<table><tbody id=snapshots-tbody></tbody></table>
<div id=snapshot-selection-summary></div>
</td>
</tr>
</table>
<hr>
<div id='results-div'></div>
<a style="display: none" id="download-anchor" download="profile.json"></a>
</body>
</html>
This diff is collapsed.
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/task_profiler/task_profiler_data_serializer.h"
#include <memory>
#include <utility>
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/json/json_string_value_serializer.h"
#include "base/time/time.h"
#include "base/tracked_objects.h"
#include "base/values.h"
#include "chrome/common/chrome_content_client.h"
#include "components/nacl/common/nacl_process_type.h"
#include "content/public/common/process_type.h"
#include "url/gurl.h"
using base::DictionaryValue;
using base::ListValue;
using base::Value;
using tracked_objects::BirthOnThreadSnapshot;
using tracked_objects::DeathDataSnapshot;
using tracked_objects::LocationSnapshot;
using tracked_objects::TaskSnapshot;
using tracked_objects::ProcessDataPhaseSnapshot;
namespace {
// Re-serializes the |location| into |dictionary|.
void LocationSnapshotToValue(const LocationSnapshot& location,
base::DictionaryValue* dictionary) {
dictionary->SetString("file_name", location.file_name);
// Note: This function name is not escaped, and templates have less-than
// characters, which means this is not suitable for display as HTML unless
// properly escaped.
dictionary->SetString("function_name", location.function_name);
dictionary->SetInteger("line_number", location.line_number);
}
// Re-serializes the |birth| into |dictionary|. Prepends the |prefix| to the
// "thread" and "location" key names in the dictionary.
void BirthOnThreadSnapshotToValue(const BirthOnThreadSnapshot& birth,
const std::string& prefix,
base::DictionaryValue* dictionary) {
DCHECK(!prefix.empty());
std::unique_ptr<base::DictionaryValue> location_value(
new base::DictionaryValue);
LocationSnapshotToValue(birth.location, location_value.get());
dictionary->Set(prefix + "_location", std::move(location_value));
dictionary->SetString(prefix + "_thread", birth.sanitized_thread_name);
}
// Re-serializes the |death_data| into |dictionary|.
void DeathDataSnapshotToValue(const DeathDataSnapshot& death_data,
base::DictionaryValue* dictionary) {
dictionary->SetInteger("count", death_data.count);
dictionary->SetInteger("run_ms", death_data.run_duration_sum);
dictionary->SetInteger("run_ms_max", death_data.run_duration_max);
dictionary->SetInteger("run_ms_sample", death_data.run_duration_sample);
dictionary->SetInteger("queue_ms", death_data.queue_duration_sum);
dictionary->SetInteger("queue_ms_max", death_data.queue_duration_max);
dictionary->SetInteger("queue_ms_sample", death_data.queue_duration_sample);
dictionary->SetInteger("alloc_ops", death_data.alloc_ops);
dictionary->SetInteger("free_ops", death_data.free_ops);
// The byte counts are 64 bit integers, pass them through as doubles, as
// integer values truncate to 32 bits.
dictionary->SetDouble("allocated_bytes", death_data.allocated_bytes);
dictionary->SetDouble("freed_bytes", death_data.freed_bytes);
dictionary->SetDouble("alloc_overhead_bytes",
death_data.alloc_overhead_bytes);
dictionary->SetInteger("max_allocated_bytes", death_data.max_allocated_bytes);
}
// Re-serializes the |snapshot| into |dictionary|.
void TaskSnapshotToValue(const TaskSnapshot& snapshot,
base::DictionaryValue* dictionary) {
BirthOnThreadSnapshotToValue(snapshot.birth, "birth", dictionary);
std::unique_ptr<base::DictionaryValue> death_data(new base::DictionaryValue);
DeathDataSnapshotToValue(snapshot.death_data, death_data.get());
dictionary->Set("death_data", std::move(death_data));
dictionary->SetString("death_thread", snapshot.death_sanitized_thread_name);
}
int AsChromeProcessType(
metrics::ProfilerEventProto::TrackedObject::ProcessType process_type) {
switch (process_type) {
case metrics::ProfilerEventProto::TrackedObject::UNKNOWN:
case metrics::ProfilerEventProto::TrackedObject::PLUGIN:
return content::PROCESS_TYPE_UNKNOWN;
case metrics::ProfilerEventProto::TrackedObject::BROWSER:
return content::PROCESS_TYPE_BROWSER;
case metrics::ProfilerEventProto::TrackedObject::RENDERER:
return content::PROCESS_TYPE_RENDERER;
case metrics::ProfilerEventProto::TrackedObject::WORKER:
return content::PROCESS_TYPE_WORKER_DEPRECATED;
case metrics::ProfilerEventProto::TrackedObject::NACL_LOADER:
return PROCESS_TYPE_NACL_LOADER;
case metrics::ProfilerEventProto::TrackedObject::UTILITY:
return content::PROCESS_TYPE_UTILITY;
case metrics::ProfilerEventProto::TrackedObject::PROFILE_IMPORT:
return content::PROCESS_TYPE_UNKNOWN;
case metrics::ProfilerEventProto::TrackedObject::ZYGOTE:
return content::PROCESS_TYPE_ZYGOTE;
case metrics::ProfilerEventProto::TrackedObject::SANDBOX_HELPER:
return content::PROCESS_TYPE_SANDBOX_HELPER;
case metrics::ProfilerEventProto::TrackedObject::NACL_BROKER:
return PROCESS_TYPE_NACL_BROKER;
case metrics::ProfilerEventProto::TrackedObject::GPU:
return content::PROCESS_TYPE_GPU;
case metrics::ProfilerEventProto::TrackedObject::PPAPI_PLUGIN:
return content::PROCESS_TYPE_PPAPI_PLUGIN;
case metrics::ProfilerEventProto::TrackedObject::PPAPI_BROKER:
return content::PROCESS_TYPE_PPAPI_BROKER;
}
NOTREACHED();
return content::PROCESS_TYPE_UNKNOWN;
}
} // anonymous namespace
namespace task_profiler {
// static
void TaskProfilerDataSerializer::ToValue(
const ProcessDataPhaseSnapshot& process_data_phase,
base::ProcessId process_id,
metrics::ProfilerEventProto::TrackedObject::ProcessType process_type,
base::DictionaryValue* dictionary) {
std::unique_ptr<base::ListValue> tasks_list(new base::ListValue);
for (const auto& task : process_data_phase.tasks) {
std::unique_ptr<base::DictionaryValue> snapshot(new base::DictionaryValue);
TaskSnapshotToValue(task, snapshot.get());
tasks_list->Append(std::move(snapshot));
}
dictionary->Set("list", std::move(tasks_list));
dictionary->SetInteger("process_id", process_id);
dictionary->SetString("process_type", content::GetProcessTypeNameInEnglish(
AsChromeProcessType(process_type)));
}
} // namespace task_profiler
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_TASK_PROFILER_TASK_PROFILER_DATA_SERIALIZER_H_
#define CHROME_BROWSER_TASK_PROFILER_TASK_PROFILER_DATA_SERIALIZER_H_
#include "base/macros.h"
#include "base/process/process_handle.h"
#include "components/metrics/proto/profiler_event.pb.h"
namespace base {
class DictionaryValue;
}
namespace tracked_objects {
struct ProcessDataPhaseSnapshot;
}
namespace task_profiler {
// This class collects task profiler data and serializes it to a file. The file
// format is compatible with the about:profiler UI.
class TaskProfilerDataSerializer {
public:
TaskProfilerDataSerializer() {}
// Writes the contents of |process_data_phase|, |process_id| and
// |process_type| into |dictionary|.
static void ToValue(
const tracked_objects::ProcessDataPhaseSnapshot& process_data_phase,
base::ProcessId process_id,
metrics::ProfilerEventProto::TrackedObject::ProcessType process_type,
base::DictionaryValue* dictionary);
private:
DISALLOW_COPY_AND_ASSIGN(TaskProfilerDataSerializer);
};
} // namespace task_profiler
#endif // CHROME_BROWSER_TASK_PROFILER_TASK_PROFILER_DATA_SERIALIZER_H_
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <string>
#include "base/json/json_writer.h"
#include "base/process/process_handle.h"
#include "base/strings/string_number_conversions.h"
#include "base/tracked_objects.h"
#include "base/values.h"
#include "chrome/browser/task_profiler/task_profiler_data_serializer.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
void ExpectSerialization(
const tracked_objects::ProcessDataPhaseSnapshot& process_data_phase,
base::ProcessId process_id,
metrics::ProfilerEventProto::TrackedObject::ProcessType process_type,
const std::string& expected_json) {
base::DictionaryValue serialized_value;
task_profiler::TaskProfilerDataSerializer::ToValue(
process_data_phase, process_id, process_type, &serialized_value);
std::string serialized_json;
base::JSONWriter::Write(serialized_value, &serialized_json);
EXPECT_EQ(expected_json, serialized_json);
}
} // anonymous namespace
// Tests the JSON serialization format for profiled process data.
TEST(TaskProfilerDataSerializerTest, SerializeProcessDataToJson) {
{
// Empty data.
tracked_objects::ProcessDataPhaseSnapshot process_data_phase;
ExpectSerialization(process_data_phase, 239,
metrics::ProfilerEventProto::TrackedObject::BROWSER,
"{"
"\"list\":["
"],"
"\"process_id\":239,"
"\"process_type\":\"Browser\""
"}");
}
{
// Non-empty data.
tracked_objects::ProcessDataPhaseSnapshot process_data_phase;
tracked_objects::BirthOnThreadSnapshot parent;
parent.location.file_name = "path/to/foo.cc";
parent.location.function_name = "WhizBang";
parent.location.line_number = 101;
parent.sanitized_thread_name = "CrBrowserMain";
tracked_objects::BirthOnThreadSnapshot child;
child.location.file_name = "path/to/bar.cc";
child.location.function_name = "FizzBoom";
child.location.line_number = 433;
child.sanitized_thread_name = "Chrome_IOThread";
// Add a snapshot.
process_data_phase.tasks.push_back(tracked_objects::TaskSnapshot());
process_data_phase.tasks.back().birth = parent;
process_data_phase.tasks.back().death_data.count = 37;
process_data_phase.tasks.back().death_data.run_duration_max = 5;
process_data_phase.tasks.back().death_data.run_duration_sample = 3;
process_data_phase.tasks.back().death_data.run_duration_sum = 17;
process_data_phase.tasks.back().death_data.queue_duration_max = 53;
process_data_phase.tasks.back().death_data.queue_duration_sample = 13;
process_data_phase.tasks.back().death_data.queue_duration_sum = 79;
process_data_phase.tasks.back().death_data.alloc_ops = 127;
process_data_phase.tasks.back().death_data.free_ops = 120;
process_data_phase.tasks.back().death_data.allocated_bytes = 2013;
process_data_phase.tasks.back().death_data.freed_bytes = 1092;
process_data_phase.tasks.back().death_data.alloc_overhead_bytes = 201;
process_data_phase.tasks.back().death_data.max_allocated_bytes = 1500;
process_data_phase.tasks.back().death_sanitized_thread_name =
"WorkerPool/-1340960768";
// Add a second snapshot.
process_data_phase.tasks.push_back(tracked_objects::TaskSnapshot());
process_data_phase.tasks.back().birth = child;
process_data_phase.tasks.back().death_data.count = 41;
process_data_phase.tasks.back().death_data.run_duration_max = 205;
process_data_phase.tasks.back().death_data.run_duration_sample = 203;
process_data_phase.tasks.back().death_data.run_duration_sum = 2017;
process_data_phase.tasks.back().death_data.queue_duration_max = 2053;
process_data_phase.tasks.back().death_data.queue_duration_sample = 2013;
process_data_phase.tasks.back().death_data.queue_duration_sum = 2079;
process_data_phase.tasks.back().death_data.alloc_ops = 1207;
process_data_phase.tasks.back().death_data.free_ops = 1200;
process_data_phase.tasks.back().death_data.allocated_bytes = 20013;
process_data_phase.tasks.back().death_data.freed_bytes = 10092;
process_data_phase.tasks.back().death_data.alloc_overhead_bytes = 2001;
process_data_phase.tasks.back().death_data.max_allocated_bytes = 15000;
process_data_phase.tasks.back().death_sanitized_thread_name =
"PAC thread #3";
ExpectSerialization(process_data_phase, 239,
metrics::ProfilerEventProto::TrackedObject::RENDERER,
"{"
"\"list\":[{"
"\"birth_location\":{"
"\"file_name\":\"path/to/foo.cc\","
"\"function_name\":\"WhizBang\","
"\"line_number\":101"
"},"
"\"birth_thread\":\"CrBrowserMain\","
"\"death_data\":{"
"\"alloc_ops\":127,"
"\"alloc_overhead_bytes\":201.0,"
"\"allocated_bytes\":2013.0,"
"\"count\":37,"
"\"free_ops\":120,"
"\"freed_bytes\":1092.0,"
"\"max_allocated_bytes\":1500,"
"\"queue_ms\":79,"
"\"queue_ms_max\":53,"
"\"queue_ms_sample\":13,"
"\"run_ms\":17,"
"\"run_ms_max\":5,"
"\"run_ms_sample\":3"
"},"
"\"death_thread\":\"WorkerPool/-1340960768\""
"},{"
"\"birth_location\":{"
"\"file_name\":\"path/to/bar.cc\","
"\"function_name\":\"FizzBoom\","
"\"line_number\":433"
"},"
"\"birth_thread\":\"Chrome_IOThread\","
"\"death_data\":{"
"\"alloc_ops\":1207,"
"\"alloc_overhead_bytes\":2001.0,"
"\"allocated_bytes\":20013.0,"
"\"count\":41,"
"\"free_ops\":1200,"
"\"freed_bytes\":10092.0,"
"\"max_allocated_bytes\":15000,"
"\"queue_ms\":2079,"
"\"queue_ms_max\":2053,"
"\"queue_ms_sample\":2013,"
"\"run_ms\":2017,"
"\"run_ms_max\":205,"
"\"run_ms_sample\":203"
"},"
"\"death_thread\":\"PAC thread #3\""
"}],"
"\"process_id\":239,"
"\"process_type\":\"Tab\""
"}");
}
}
......@@ -398,8 +398,6 @@ split_static_library("ui") {
"webui/predictors/predictors_ui.h",
"webui/prefs_internals_source.cc",
"webui/prefs_internals_source.h",
"webui/profiler_ui.cc",
"webui/profiler_ui.h",
"webui/quota_internals/quota_internals_handler.cc",
"webui/quota_internals/quota_internals_handler.h",
"webui/quota_internals/quota_internals_proxy.cc",
......
......@@ -49,7 +49,6 @@
#include "chrome/browser/ui/webui/physical_web/physical_web_ui.h"
#include "chrome/browser/ui/webui/policy_ui.h"
#include "chrome/browser/ui/webui/predictors/predictors_ui.h"
#include "chrome/browser/ui/webui/profiler_ui.h"
#include "chrome/browser/ui/webui/quota_internals/quota_internals_ui.h"
#include "chrome/browser/ui/webui/settings/md_settings_ui.h"
#include "chrome/browser/ui/webui/settings_utils.h"
......@@ -355,8 +354,6 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui,
return &NewWebUI<PhysicalWebUI>;
if (url.host_piece() == chrome::kChromeUIPredictorsHost)
return &NewWebUI<PredictorsUI>;
if (url.host_piece() == chrome::kChromeUIProfilerHost)
return &NewWebUI<ProfilerUI>;
if (url.host() == chrome::kChromeUIQuotaInternalsHost)
return &NewWebUI<QuotaInternalsUI>;
if (url.host() == safe_browsing::kChromeUISafeBrowsingHost)
......
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/webui/profiler_ui.h"
#include <string>
// When testing the javacript code, it is cumbersome to have to keep
// re-building the resouces package and reloading the browser. To solve
// this, enable the following flag to read the webapp's source files
// directly off disk, so all you have to do is refresh the page to
// test the modifications.
// #define USE_SOURCE_FILES_DIRECTLY
#include "base/bind.h"
#include "base/debug/debugging_flags.h"
#include "base/debug/thread_heap_usage_tracker.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/strings/string_util.h"
#include "base/tracked_objects.h"
#include "base/values.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/task_profiler/task_profiler_data_serializer.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/browser_resources.h"
#include "components/metrics/profiler/tracking_synchronizer.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/url_data_source.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_data_source.h"
#include "content/public/browser/web_ui_message_handler.h"
#ifdef USE_SOURCE_FILES_DIRECTLY
#include "base/base_paths.h"
#include "base/files/file_util.h"
#include "base/memory/ref_counted_memory.h"
#include "base/path_service.h"
#endif // USE_SOURCE_FILES_DIRECTLY
using content::BrowserThread;
using content::WebContents;
using content::WebUIMessageHandler;
using metrics::TrackingSynchronizer;
namespace {
#ifdef USE_SOURCE_FILES_DIRECTLY
class ProfilerWebUIDataSource : public content::URLDataSource {
public:
ProfilerWebUIDataSource() {
}
protected:
// content::URLDataSource implementation.
std::string GetSource() override {
return chrome::kChromeUIProfilerHost;
}
std::string GetMimeType(const std::string& path) const override {
if (base::EndsWith(path, ".js", base::CompareCase::INSENSITIVE_ASCII))
return "application/javascript";
return "text/html";
}
void StartDataRequest(
const std::string& path,
bool is_incognito,
const content::URLDataSource::GotDataCallback& callback) override {
base::FilePath base_path;
PathService::Get(base::DIR_SOURCE_ROOT, &base_path);
base_path = base_path.AppendASCII("chrome");
base_path = base_path.AppendASCII("browser");
base_path = base_path.AppendASCII("resources");
base_path = base_path.AppendASCII("profiler");
// If no resource was specified, default to profiler.html.
std::string filename = path.empty() ? "profiler.html" : path;
base::FilePath file_path;
file_path = base_path.AppendASCII(filename);
// Read the file synchronously and send it as the response.
base::ThreadRestrictions::ScopedAllowIO allow;
std::string file_contents;
if (!base::ReadFileToString(file_path, &file_contents))
LOG(ERROR) << "Couldn't read file: " << file_path.value();
scoped_refptr<base::RefCountedString> response =
new base::RefCountedString();
response->data() = file_contents;
callback.Run(response);
}
private:
DISALLOW_COPY_AND_ASSIGN(ProfilerWebUIDataSource);
};
#else // USE_SOURCE_FILES_DIRECTLY
content::WebUIDataSource* CreateProfilerHTMLSource() {
content::WebUIDataSource* source =
content::WebUIDataSource::Create(chrome::kChromeUIProfilerHost);
source->SetJsonPath("strings.js");
source->AddResourcePath("profiler.js", IDR_PROFILER_JS);
source->SetDefaultResource(IDR_PROFILER_HTML);
source->UseGzip(std::unordered_set<std::string>());
source->AddBoolean(
"enableMemoryTaskProfiler",
base::debug::ThreadHeapUsageTracker::IsHeapTrackingEnabled());
return source;
}
#endif
// This class receives javascript messages from the renderer.
// Note that the WebUI infrastructure runs on the UI thread, therefore all of
// this class's methods are expected to run on the UI thread.
class ProfilerMessageHandler : public WebUIMessageHandler {
public:
ProfilerMessageHandler() {}
// WebUIMessageHandler implementation.
void RegisterMessages() override;
// Messages.
void OnGetData(const base::ListValue* list);
private:
DISALLOW_COPY_AND_ASSIGN(ProfilerMessageHandler);
};
void ProfilerMessageHandler::RegisterMessages() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
web_ui()->RegisterMessageCallback("getData",
base::Bind(&ProfilerMessageHandler::OnGetData, base::Unretained(this)));
}
void ProfilerMessageHandler::OnGetData(const base::ListValue* list) {
ProfilerUI* profiler_ui = static_cast<ProfilerUI*>(web_ui()->GetController());
profiler_ui->GetData();
}
} // namespace
ProfilerUI::ProfilerUI(content::WebUI* web_ui)
: WebUIController(web_ui),
weak_ptr_factory_(this) {
web_ui->AddMessageHandler(base::MakeUnique<ProfilerMessageHandler>());
// Set up the chrome://profiler/ source.
Profile* profile = Profile::FromWebUI(web_ui);
#if defined(USE_SOURCE_FILES_DIRECTLY)
content::URLDataSource::Add(profile, new ProfilerWebUIDataSource);
#else
content::WebUIDataSource::Add(profile, CreateProfilerHTMLSource());
#endif
}
ProfilerUI::~ProfilerUI() {
}
void ProfilerUI::GetData() {
TrackingSynchronizer::FetchProfilerDataAsynchronously(
weak_ptr_factory_.GetWeakPtr());
}
void ProfilerUI::ReceivedProfilerData(
const metrics::ProfilerDataAttributes& attributes,
const tracked_objects::ProcessDataPhaseSnapshot& process_data_phase,
const metrics::ProfilerEvents& past_events) {
// Serialize the data to JSON.
base::DictionaryValue json_data;
task_profiler::TaskProfilerDataSerializer::ToValue(
process_data_phase, attributes.process_id, attributes.process_type,
&json_data);
// Send the data to the renderer.
web_ui()->CallJavascriptFunctionUnsafe("g_browserBridge.receivedData",
json_data);
}
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_WEBUI_PROFILER_UI_H_
#define CHROME_BROWSER_UI_WEBUI_PROFILER_UI_H_
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "components/metrics/profiler/tracking_synchronizer_observer.h"
#include "content/public/browser/web_ui_controller.h"
// The C++ back-end for the chrome://profiler webui page.
class ProfilerUI : public content::WebUIController,
public metrics::TrackingSynchronizerObserver {
public:
explicit ProfilerUI(content::WebUI* web_ui);
~ProfilerUI() override;
// Get the tracking data from TrackingSynchronizer.
void GetData();
private:
// TrackingSynchronizerObserver:
void ReceivedProfilerData(
const metrics::ProfilerDataAttributes& attributes,
const tracked_objects::ProcessDataPhaseSnapshot& process_data_phase,
const metrics::ProfilerEvents& past_events) override;
// Used to get |weak_ptr_| to self on the UI thread.
base::WeakPtrFactory<ProfilerUI> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(ProfilerUI);
};
#endif // CHROME_BROWSER_UI_WEBUI_PROFILER_UI_H_
......@@ -232,7 +232,6 @@ const char kChromeUIComponentsHost[] = "components";
const char kChromeUIPolicyHost[] = "policy";
const char kChromeUIMdUserManagerHost[] = "md-user-manager";
const char kChromeUIPredictorsHost[] = "predictors";
const char kChromeUIProfilerHost[] = "profiler";
const char kChromeUIQuotaInternalsHost[] = "quota-internals";
const char kChromeUIQuitHost[] = "quit";
const char kChromeUIRestartHost[] = "restart";
......@@ -665,7 +664,6 @@ const char* const kChromeHostURLs[] = {
kChromeUIPasswordManagerInternalsHost,
kChromeUIPolicyHost,
kChromeUIPredictorsHost,
kChromeUIProfilerHost,
kChromeUIQuotaInternalsHost,
kChromeUISignInInternalsHost,
kChromeUISiteEngagementHost,
......
......@@ -218,7 +218,6 @@ extern const char kChromeUIPolicyHost[];
extern const char kChromeUIPrefsInternalsHost[];
extern const char kChromeUIMdUserManagerHost[];
extern const char kChromeUIPredictorsHost[];
extern const char kChromeUIProfilerHost[];
extern const char kChromeUIQuotaInternalsHost[];
extern const char kChromeUIQuitHost[];
extern const char kChromeUIRestartHost[];
......
......@@ -3372,7 +3372,6 @@ test("unit_tests") {
"../browser/sync/profile_sync_service_factory_unittest.cc",
"../browser/sync/sessions/sync_sessions_web_contents_router_unittest.cc",
"../browser/sync/sync_startup_tracker_unittest.cc",
"../browser/task_profiler/task_profiler_data_serializer_unittest.cc",
"../browser/thumbnails/thumbnail_service_unittest.cc",
"../browser/thumbnails/thumbnail_utils_unittest.cc",
"../browser/tracing/background_tracing_field_trial_unittest.cc",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment