Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / webui / profiler_ui.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/webui/profiler_ui.h"
6
7 #include <string>
8
9 // When testing the javacript code, it is cumbersome to have to keep
10 // re-building the resouces package and reloading the browser. To solve
11 // this, enable the following flag to read the webapp's source files
12 // directly off disk, so all you have to do is refresh the page to
13 // test the modifications.
14 // #define USE_SOURCE_FILES_DIRECTLY
15
16 #include "base/bind.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/strings/string_util.h"
19 #include "base/tracked_objects.h"
20 #include "base/values.h"
21 #include "chrome/browser/metrics/tracking_synchronizer.h"
22 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/browser/task_profiler/task_profiler_data_serializer.h"
24 #include "chrome/common/url_constants.h"
25 #include "content/public/browser/browser_thread.h"
26 #include "content/public/browser/url_data_source.h"
27 #include "content/public/browser/web_contents.h"
28 #include "content/public/browser/web_ui.h"
29 #include "content/public/browser/web_ui_data_source.h"
30 #include "content/public/browser/web_ui_message_handler.h"
31 #include "grit/browser_resources.h"
32 #include "grit/generated_resources.h"
33
34 #ifdef USE_SOURCE_FILES_DIRECTLY
35 #include "base/base_paths.h"
36 #include "base/file_util.h"
37 #include "base/memory/ref_counted_memory.h"
38 #include "base/path_service.h"
39 #endif  //  USE_SOURCE_FILES_DIRECTLY
40
41 using chrome_browser_metrics::TrackingSynchronizer;
42 using content::BrowserThread;
43 using content::WebContents;
44 using content::WebUIMessageHandler;
45
46 namespace {
47
48 #ifdef USE_SOURCE_FILES_DIRECTLY
49
50 class ProfilerWebUIDataSource : public content::URLDataSource {
51  public:
52   ProfilerWebUIDataSource() {
53   }
54
55  protected:
56   // content::URLDataSource implementation.
57   virtual std::string GetSource() OVERRIDE {
58     return chrome::kChromeUIProfilerHost;
59   }
60
61   virtual std::string GetMimeType(const std::string& path) const OVERRIDE {
62     if (EndsWith(path, ".js", false))
63       return "application/javascript";
64     return "text/html";
65   }
66
67   virtual void StartDataRequest(
68       const std::string& path,
69       bool is_incognito,
70       const content::URLDataSource::GotDataCallback& callback) OVERRIDE {
71     base::FilePath base_path;
72     PathService::Get(base::DIR_SOURCE_ROOT, &base_path);
73     base_path = base_path.AppendASCII("chrome");
74     base_path = base_path.AppendASCII("browser");
75     base_path = base_path.AppendASCII("resources");
76     base_path = base_path.AppendASCII("profiler");
77
78     // If no resource was specified, default to profiler.html.
79     std::string filename = path.empty() ? "profiler.html" : path;
80
81     base::FilePath file_path;
82     file_path = base_path.AppendASCII(filename);
83
84     // Read the file synchronously and send it as the response.
85     base::ThreadRestrictions::ScopedAllowIO allow;
86     std::string file_contents;
87     if (!base::ReadFileToString(file_path, &file_contents))
88       LOG(ERROR) << "Couldn't read file: " << file_path.value();
89     scoped_refptr<base::RefCountedString> response =
90         new base::RefCountedString();
91     response->data() = file_contents;
92     callback.Run(response);
93   }
94
95  private:
96   DISALLOW_COPY_AND_ASSIGN(ProfilerWebUIDataSource);
97 };
98
99 #else  // USE_SOURCE_FILES_DIRECTLY
100
101 content::WebUIDataSource* CreateProfilerHTMLSource() {
102   content::WebUIDataSource* source =
103       content::WebUIDataSource::Create(chrome::kChromeUIProfilerHost);
104
105   source->SetJsonPath("strings.js");
106   source->AddResourcePath("profiler.js", IDR_PROFILER_JS);
107   source->SetDefaultResource(IDR_PROFILER_HTML);
108   return source;
109 }
110
111 #endif
112
113 // This class receives javascript messages from the renderer.
114 // Note that the WebUI infrastructure runs on the UI thread, therefore all of
115 // this class's methods are expected to run on the UI thread.
116 class ProfilerMessageHandler : public WebUIMessageHandler {
117  public:
118   ProfilerMessageHandler() {}
119
120   // WebUIMessageHandler implementation.
121   virtual void RegisterMessages() OVERRIDE;
122
123   // Messages.
124   void OnGetData(const base::ListValue* list);
125   void OnResetData(const base::ListValue* list);
126
127  private:
128   DISALLOW_COPY_AND_ASSIGN(ProfilerMessageHandler);
129 };
130
131 void ProfilerMessageHandler::RegisterMessages() {
132   DCHECK_CURRENTLY_ON(BrowserThread::UI);
133
134   web_ui()->RegisterMessageCallback("getData",
135       base::Bind(&ProfilerMessageHandler::OnGetData, base::Unretained(this)));
136   web_ui()->RegisterMessageCallback("resetData",
137       base::Bind(&ProfilerMessageHandler::OnResetData,
138                  base::Unretained(this)));
139 }
140
141 void ProfilerMessageHandler::OnGetData(const base::ListValue* list) {
142   ProfilerUI* profiler_ui = static_cast<ProfilerUI*>(web_ui()->GetController());
143   profiler_ui->GetData();
144 }
145
146 void ProfilerMessageHandler::OnResetData(const base::ListValue* list) {
147   tracked_objects::ThreadData::ResetAllThreadData();
148 }
149
150 }  // namespace
151
152 ProfilerUI::ProfilerUI(content::WebUI* web_ui)
153     : WebUIController(web_ui),
154       weak_ptr_factory_(this) {
155   web_ui->AddMessageHandler(new ProfilerMessageHandler());
156
157   // Set up the chrome://profiler/ source.
158   Profile* profile = Profile::FromWebUI(web_ui);
159 #if defined(USE_SOURCE_FILES_DIRECTLY)
160   content::URLDataSource::Add(profile, new ProfilerWebUIDataSource);
161 #else
162   content::WebUIDataSource::Add(profile, CreateProfilerHTMLSource());
163 #endif
164 }
165
166 ProfilerUI::~ProfilerUI() {
167 }
168
169 void ProfilerUI::GetData() {
170   TrackingSynchronizer::FetchProfilerDataAsynchronously(
171       weak_ptr_factory_.GetWeakPtr());
172 }
173
174 void ProfilerUI::ReceivedProfilerData(
175     const tracked_objects::ProcessDataSnapshot& profiler_data,
176     int process_type) {
177   // Serialize the data to JSON.
178   base::DictionaryValue json_data;
179   task_profiler::TaskProfilerDataSerializer::ToValue(profiler_data,
180                                                      process_type,
181                                                      &json_data);
182
183   // Send the data to the renderer.
184   web_ui()->CallJavascriptFunction("g_browserBridge.receivedData", json_data);
185 }