Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(264)

Side by Side Diff: chrome/browser/dom_ui/gpu_internals_ui.cc

Issue 5228004: Switch the about:gpu implementation from an about handler to dom_ui.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2010 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/dom_ui/gpu_internals_ui.h"
6
7 #include <algorithm>
8 #include <string>
9 #include <utility>
10 #include <vector>
11
12 #include "app/l10n_util.h"
13 #include "app/resource_bundle.h"
14 #include "base/command_line.h"
15 #include "base/file_util.h"
16 #include "base/message_loop.h"
17 #include "base/path_service.h"
18 #include "base/singleton.h"
19 #include "base/string_number_conversions.h"
20 #include "base/string_piece.h"
21 #include "base/utf_string_conversions.h"
22 #include "base/values.h"
23 #include "chrome/browser/browser_process.h"
24 #include "chrome/browser/browser_thread.h"
25 #include "chrome/browser/dom_ui/chrome_url_data_manager.h"
26 #include "chrome/browser/gpu_process_host.h"
27 #include "chrome/browser/gpu_process_host_ui_shim.h"
28 #include "chrome/browser/io_thread.h"
29 #include "chrome/browser/net/chrome_net_log.h"
30 #include "chrome/browser/net/connection_tester.h"
31 #include "chrome/browser/net/passive_log_collector.h"
32 #include "chrome/browser/net/url_fixer_upper.h"
33 #include "chrome/browser/platform_util.h"
34 #include "chrome/browser/profile.h"
35 #include "chrome/common/chrome_paths.h"
36 #include "chrome/common/chrome_version_info.h"
37 #include "chrome/common/jstemplate_builder.h"
38 #include "chrome/common/net/url_request_context_getter.h"
39 #include "chrome/common/url_constants.h"
40 #include "grit/browser_resources.h"
41 #include "grit/generated_resources.h"
42 #include "net/base/escape.h"
43
44
45 namespace {
46
47 class GpuHTMLSource : public ChromeURLDataManager::DataSource {
arv (Not doing code reviews) 2010/12/06 19:45:57 Should this be named GPUHTMLSource? It looks very
nduca 2010/12/07 01:03:40 I hear you. This is based on the rest of the Chrom
48 public:
49 GpuHTMLSource();
50
51 // Called when the network layer has requested a resource underneath
52 // the path we registered.
53 virtual void StartDataRequest(const std::string& path,
54 bool is_off_the_record,
55 int request_id);
56 virtual std::string GetMimeType(const std::string&) const;
57
58 private:
59 ~GpuHTMLSource() {}
60 DISALLOW_COPY_AND_ASSIGN(GpuHTMLSource);
61 };
62
63 // This class receives javascript messages from the renderer.
64 // Note that the DOMUI infrastructure runs on the UI thread, therefore all of
65 // this class's methods are expected to run on the UI thread.
66 //
67 // Since the network code we want to run lives on the IO thread, we proxy
68 // everything over to GpuMessageHandler::IOThreadImpl, which runs
69 // on the IO thread.
70 //
71 // TODO(eroman): Can we start on the IO thread to begin with?
72 class GpuMessageHandler
73 : public DOMMessageHandler,
74 public base::SupportsWeakPtr<GpuMessageHandler> {
75 public:
76 GpuMessageHandler();
77 virtual ~GpuMessageHandler();
78
79 // DOMMessageHandler implementation.
80 virtual DOMMessageHandler* Attach(DOMUI* dom_ui);
81 virtual void RegisterMessages();
82
83 // Mesages
84 void OnCallAsync(const ListValue* list);
85
86 // Submessages dispatched from OnCallAsync
87 Value* OnRequestGpuInfo(const ListValue* list);
88 Value* OnRequestClientInfo(const ListValue* list);
89
90 // Executes the javascript function |function_name| in the renderer, passing
91 // it the argument |value|.
92 void CallJavascriptFunction(const std::wstring& function_name,
93 const Value* value);
94
95 private:
96 bool collecting_graphics_info_;
97 DISALLOW_COPY_AND_ASSIGN(GpuMessageHandler);
98 };
99
100 ////////////////////////////////////////////////////////////////////////////////
101 //
102 // GpuHTMLSource
103 //
104 ////////////////////////////////////////////////////////////////////////////////
105
106 GpuHTMLSource::GpuHTMLSource()
107 : DataSource(chrome::kChromeUIGpuInternalsHost, MessageLoop::current()) {
108 }
109
110 void GpuHTMLSource::StartDataRequest(const std::string& path,
111 bool is_off_the_record,
112 int request_id) {
113 DictionaryValue* localized_strings = new DictionaryValue();
114 SetFontAndTextDirection(localized_strings);
115
116 static const base::StringPiece options_html(
117 ResourceBundle::GetSharedInstance().GetRawDataResource(
118 IDR_GPU_INTERNALS_HTML));
119 const std::string full_html = jstemplate_builder::GetI18nTemplateHtml(
120 options_html, localized_strings);
121
122 scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
123 html_bytes->data.resize(full_html.size());
124 std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin());
125
126 SendResponse(request_id, html_bytes);
127 }
128
129 std::string GpuHTMLSource::GetMimeType(const std::string&) const {
130 return "text/html";
131 }
132
133 ////////////////////////////////////////////////////////////////////////////////
134 //
135 // GpuMessageHandler
136 //
137 ////////////////////////////////////////////////////////////////////////////////
138
139 GpuMessageHandler::GpuMessageHandler()
140 : collecting_graphics_info_(false) {
141 }
142
143 GpuMessageHandler::~GpuMessageHandler() {}
144
145 DOMMessageHandler* GpuMessageHandler::Attach(DOMUI* dom_ui) {
146 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
147 DOMMessageHandler* result = DOMMessageHandler::Attach(dom_ui);
148 return result;
149 }
150
151 /* BrowserBridge.callAsync prepends a requestID to these messages. */
152 void GpuMessageHandler::RegisterMessages() {
153 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
154
155 dom_ui_->RegisterMessageCallback(
156 "callAsync",
157 NewCallback(this, &GpuMessageHandler::OnCallAsync));
158 }
159
160 void GpuMessageHandler::OnCallAsync(const ListValue* args) {
161 DCHECK(args->GetSize() >= 2);
162 // unpack args into requestId, submessage and submessageArgs
163 bool ok;
164 Value* requestId;
165 ok = args->Get(0, &requestId);
166 DCHECK(ok);
167
168 std::string submessage;
169 ok = args->GetString(1, &submessage);
170 DCHECK(ok);
171
172 ListValue* submessageArgs = new ListValue();
173 for (size_t i = 2; i < args->GetSize(); ++i) {
174 Value* arg;
175 ok = args->Get(i, &arg);
176 DCHECK(ok);
177
178 Value* argCopy = arg->DeepCopy();
179 submessageArgs->Append(argCopy);
180 }
181
182 // call the submessage handler
183 Value* ret = NULL;
184 if (submessage == "requestGpuInfo") {
arv (Not doing code reviews) 2010/12/06 19:45:57 I find this strange. DOMUI RegisterMessageCallback
nduca 2010/12/07 01:03:40 I'm fine doing that, but question though first. I
arv (Not doing code reviews) 2010/12/08 17:55:19 One option would be to extend chrome.send to take
185 ret = OnRequestGpuInfo(submessageArgs);
186 } else if (submessage == "requestClientInfo") {
187 ret = OnRequestClientInfo(submessageArgs);
188 } else { // unrecognized submessage
189 NOTREACHED();
190 delete submessageArgs;
191 return;
192 }
193 delete submessageArgs;
194
195 // call BrowserBridge.onCallAsyncReply with result
196 if (ret) {
197 dom_ui_->CallJavascriptFunction(L"browser.onCallAsyncReply",
arv (Not doing code reviews) 2010/12/06 19:45:57 Same goes for calling into js
198 *requestId,
199 *ret);
200 delete ret;
201 } else {
202 dom_ui_->CallJavascriptFunction(L"browser.onCallAsyncReply",
203 *requestId);
204 }
205 }
206
207 Value* GpuMessageHandler::OnRequestClientInfo(const ListValue* list) {
208 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
209
210 DictionaryValue* dict = new DictionaryValue();
arv (Not doing code reviews) 2010/12/06 19:45:57 Who is deleting this?
nduca 2010/12/07 01:03:40 OnCallAsync, line 200, "delete ret" after we've se
211
212 chrome::VersionInfo version_info;
213
214 if (!version_info.is_valid()) {
215 DLOG(ERROR) << "Unable to create chrome::VersionInfo";
216 } else {
217 // We have everything we need to send the right values.
218 dict->SetString("version", version_info.Version());
219 dict->SetString("cl", version_info.LastChange());
220 dict->SetString("version_mod",
221 platform_util::GetVersionStringModifier());
222 dict->SetString("official",
223 l10n_util::GetStringUTF16(
224 version_info.IsOfficialBuild() ?
225 IDS_ABOUT_VERSION_OFFICIAL
226 : IDS_ABOUT_VERSION_UNOFFICIAL));
227
228 dict->SetString("command_line",
229 CommandLine::ForCurrentProcess()->command_line_string());
230 }
231
232 return dict;
233 }
234
235
236 #if defined(OS_WIN)
237 // Output DxDiagNode tree as HTML tables and nested HTML unordered list
238 // elements.
239 DictionaryValue* DxDiagNodeToDict(const DxDiagNode& node) {
240 DictionaryValue* dict = new DictionaryValue();
arv (Not doing code reviews) 2010/12/06 19:45:57 Who is deleting this?
nduca 2010/12/07 01:03:40 Caller. On 2010/12/06 19:45:57, arv wrote:
241 for (std::map<std::string, std::string>::const_iterator it =
242 node.values.begin();
243 it != node.values.end();
244 ++it) {
245 dict->SetString(EscapeForHTML(it->first), EscapeForHTML(it->second));
246 }
247
248 for (std::map<std::string, DxDiagNode>::const_iterator it =
249 node.children.begin();
250 it != node.children.end();
251 ++it) {
252 DictionaryValue* subdict = DxDiagNodeToDict(it->second);
253 dict->Set(EscapeForHTML(it->first), subdict);
254 }
255 return dict;
256 }
257
258 #endif // OS_WIN
259
260 std::string VersionNumberToString(uint32 value) {
261 int hi = (value >> 8) & 0xff;
262 int low = value & 0xff;
263 return base::IntToString(hi) + "." + base::IntToString(low);
264 }
265
266 DictionaryValue* GpuInfoToDict(const GPUInfo& gpu_info) {
267 DictionaryValue* info = new DictionaryValue();
arv (Not doing code reviews) 2010/12/06 19:45:57 Who is deleting this?
nduca 2010/12/07 01:03:40 Caller. On 2010/12/06 19:45:57, arv wrote:
268 info->SetString("Initialization time",
269 base::Int64ToString(gpu_info.initialization_time().InMilliseconds()));
270 info->SetString("Vendor Id",
271 base::StringPrintf("0x%04x", gpu_info.vendor_id()));
272 info->SetString("Device Id",
273 base::StringPrintf("0x%04x", gpu_info.device_id()));
274 info->SetString("Driver version",
275 WideToASCII(gpu_info.driver_version()).c_str());
276 info->SetString("Pixel shader version",
277 VersionNumberToString(gpu_info.pixel_shader_version()));
278 info->SetString("Vertex shader version",
279 VersionNumberToString(gpu_info.vertex_shader_version()));
280 info->SetString("GL version", VersionNumberToString(gpu_info.gl_version()));
281
282 DictionaryValue* dict = new DictionaryValue();
283 dict->Set("Basic GPU Information", info);
284
285 #if defined(OS_WIN)
286 DictionaryValue* dx_info = DxDiagNodeToDict(gpu_info.dx_diagnostics());
287 dict->Set("DirectX diagnostics", dx_info);
288 #endif
289
290 return dict;
291 }
292
293 Value* GpuMessageHandler::OnRequestGpuInfo(const ListValue* list) {
294 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
295
296 // Get GPU Info.
297 GPUInfo gpu_info = GpuProcessHostUIShim::Get()->gpu_info();
298
299 std::string html;
300 if (gpu_info.progress() != GPUInfo::kComplete) {
301 if (!collecting_graphics_info_) {
302 GpuProcessHostUIShim::Get()->CollectGraphicsInfoAsynchronously();
303 collecting_graphics_info_ = true;
304 }
305 return NULL;
306 } else {
307 collecting_graphics_info_ = false;
308
309 return GpuInfoToDict(gpu_info);
310 }
311 }
312
313 } // namespace
314
315
316 ////////////////////////////////////////////////////////////////////////////////
317 //
318 // GpuUI
319 //
320 ////////////////////////////////////////////////////////////////////////////////
321
322 GpuUI::GpuUI(TabContents* contents) : DOMUI(contents) {
323 AddMessageHandler((new GpuMessageHandler())->Attach(this));
324
325 GpuHTMLSource* html_source = new GpuHTMLSource();
326
327 // Set up the chrome://gpu/ source.
328 BrowserThread::PostTask(
329 BrowserThread::IO, FROM_HERE,
330 NewRunnableMethod(
331 Singleton<ChromeURLDataManager>::get(),
332 &ChromeURLDataManager::AddDataSource,
333 make_scoped_refptr(html_source)));
334 }
335
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698