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

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/common/chrome_paths.h"
35 #include "chrome/common/chrome_version_info.h"
36 #include "chrome/common/jstemplate_builder.h"
37 #include "chrome/common/net/url_request_context_getter.h"
38 #include "chrome/common/url_constants.h"
39 #include "grit/browser_resources.h"
40 #include "grit/generated_resources.h"
41 #include "net/base/escape.h"
42
43
44 namespace {
45
46 class GpuHTMLSource : public ChromeURLDataManager::DataSource {
47 public:
48 GpuHTMLSource();
49
50 // Called when the network layer has requested a resource underneath
51 // the path we registered.
52 virtual void StartDataRequest(const std::string& path,
53 bool is_off_the_record,
54 int request_id);
55 virtual std::string GetMimeType(const std::string&) const;
56
57 private:
58 ~GpuHTMLSource() {}
59 DISALLOW_COPY_AND_ASSIGN(GpuHTMLSource);
60 };
61
62 // This class receives javascript messages from the renderer.
63 // Note that the DOMUI infrastructure runs on the UI thread, therefore all of
64 // this class's methods are expected to run on the UI thread.
65 //
66 // Since the network code we want to run lives on the IO thread, we proxy
67 // everything over to GpuMessageHandler::IOThreadImpl, which runs
68 // on the IO thread.
69 //
70 // TODO(eroman): Can we start on the IO thread to begin with?
eroman 2010/12/09 02:46:45 Looks like you copied this comment block from net_
nduca 2010/12/09 17:24:54 Done.
71 class GpuMessageHandler
72 : public DOMMessageHandler,
73 public base::SupportsWeakPtr<GpuMessageHandler> {
74 public:
75 GpuMessageHandler();
76 virtual ~GpuMessageHandler();
77
78 // DOMMessageHandler implementation.
79 virtual DOMMessageHandler* Attach(DOMUI* dom_ui);
80 virtual void RegisterMessages();
81
82 // Mesages
83 void OnCallAsync(const ListValue* list);
84
85 // Submessages dispatched from OnCallAsync
86 Value* OnRequestGpuInfo(const ListValue* list);
87 Value* OnRequestClientInfo(const ListValue* list);
88
89 // Executes the javascript function |function_name| in the renderer, passing
90 // it the argument |value|.
91 void CallJavascriptFunction(const std::wstring& function_name,
92 const Value* value);
93
94 private:
95 DISALLOW_COPY_AND_ASSIGN(GpuMessageHandler);
96 };
97
98 ////////////////////////////////////////////////////////////////////////////////
99 //
100 // GpuHTMLSource
101 //
102 ////////////////////////////////////////////////////////////////////////////////
103
104 GpuHTMLSource::GpuHTMLSource()
105 : DataSource(chrome::kChromeUIGpuInternalsHost, MessageLoop::current()) {
106 }
107
108 void GpuHTMLSource::StartDataRequest(const std::string& path,
109 bool is_off_the_record,
eroman 2010/12/09 02:46:45 indentation.
nduca 2010/12/09 17:24:54 Done.
110 int request_id) {
111 DictionaryValue localized_strings;
112 SetFontAndTextDirection(&localized_strings);
113
114 static const base::StringPiece gpu_html(
eroman 2010/12/09 02:46:45 Why static? Seems incorrect to save a StringPiece
nduca 2010/12/09 17:24:54 This is copied from options_ui.cc, which does this
115 ResourceBundle::GetSharedInstance().GetRawDataResource(
116 IDR_GPU_INTERNALS_HTML));
117 std::string full_html(gpu_html.data(), gpu_html.size());
118 jstemplate_builder::AppendJsonHtml(&localized_strings, &full_html);
119 jstemplate_builder::AppendI18nTemplateSourceHtml(&full_html);
120 jstemplate_builder::AppendI18nTemplateProcessHtml(&full_html);
121 jstemplate_builder::AppendJsTemplateSourceHtml(&full_html);
122
123
124 scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
125 html_bytes->data.resize(full_html.size());
126 std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin());
127
128 SendResponse(request_id, html_bytes);
129 }
130
131 std::string GpuHTMLSource::GetMimeType(const std::string&) const {
132 return "text/html";
133 }
134
135 ////////////////////////////////////////////////////////////////////////////////
136 //
137 // GpuMessageHandler
138 //
139 ////////////////////////////////////////////////////////////////////////////////
140
141 GpuMessageHandler::GpuMessageHandler() {
142 }
143
144 GpuMessageHandler::~GpuMessageHandler() {}
145
146 DOMMessageHandler* GpuMessageHandler::Attach(DOMUI* dom_ui) {
147 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
148 DOMMessageHandler* result = DOMMessageHandler::Attach(dom_ui);
149 return result;
150 }
151
152 /* BrowserBridge.callAsync prepends a requestID to these messages. */
153 void GpuMessageHandler::RegisterMessages() {
154 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
155
156 dom_ui_->RegisterMessageCallback(
157 "callAsync",
158 NewCallback(this, &GpuMessageHandler::OnCallAsync));
159 }
160
161 void GpuMessageHandler::OnCallAsync(const ListValue* args) {
162 DCHECK_GE(args->GetSize(), static_cast<size_t>(2));
163 // unpack args into requestId, submessage and submessageArgs
164 bool ok;
165 Value* requestId;
166 ok = args->Get(0, &requestId);
167 DCHECK(ok);
168
169 std::string submessage;
170 ok = args->GetString(1, &submessage);
171 DCHECK(ok);
172
173 ListValue* submessageArgs = new ListValue();
174 for (size_t i = 2; i < args->GetSize(); ++i) {
175 Value* arg;
176 ok = args->Get(i, &arg);
177 DCHECK(ok);
178
179 Value* argCopy = arg->DeepCopy();
180 submessageArgs->Append(argCopy);
181 }
182
183 // call the submessage handler
184 Value* ret = NULL;
185 if (submessage == "requestGpuInfo") {
186 ret = OnRequestGpuInfo(submessageArgs);
187 } else if (submessage == "requestClientInfo") {
188 ret = OnRequestClientInfo(submessageArgs);
189 } else { // unrecognized submessage
190 NOTREACHED();
191 delete submessageArgs;
192 return;
193 }
194 delete submessageArgs;
195
196 // call BrowserBridge.onCallAsyncReply with result
197 if (ret) {
198 dom_ui_->CallJavascriptFunction(L"browserBridge.onCallAsyncReply",
199 *requestId,
200 *ret);
201 delete ret;
202 } else {
203 dom_ui_->CallJavascriptFunction(L"browserBridge.onCallAsyncReply",
204 *requestId);
205 }
206 }
207
208 Value* GpuMessageHandler::OnRequestClientInfo(const ListValue* list) {
209 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
210
211 DictionaryValue* dict = new DictionaryValue();
212
213 chrome::VersionInfo version_info;
214
215 if (!version_info.is_valid()) {
216 DLOG(ERROR) << "Unable to create chrome::VersionInfo";
217 } else {
218 // We have everything we need to send the right values.
219 dict->SetString("version", version_info.Version());
220 dict->SetString("cl", version_info.LastChange());
221 dict->SetString("version_mod",
222 platform_util::GetVersionStringModifier());
223 dict->SetString("official",
224 l10n_util::GetStringUTF16(
225 version_info.IsOfficialBuild() ?
226 IDS_ABOUT_VERSION_OFFICIAL
227 : IDS_ABOUT_VERSION_UNOFFICIAL));
228
229 dict->SetString("command_line",
230 CommandLine::ForCurrentProcess()->command_line_string());
231 }
232
233 return dict;
234 }
235
236 DictionaryValue* NewDescriptionValuePair(const std::string& desc,
237 const std::string& value) {
238 DictionaryValue* dict = new DictionaryValue();
239 dict->SetString("description", EscapeForHTML(desc));
240 dict->SetString("value", EscapeForHTML(value));
241 return dict;
242 }
243
244 DictionaryValue* NewDescriptionValuePair(const std::string& desc,
245 Value* value) {
246 DictionaryValue* dict = new DictionaryValue();
247 dict->SetString("description", EscapeForHTML(desc));
248 dict->Set("value", value);
249 return dict;
250 }
251
252 #if defined(OS_WIN)
253 // Output DxDiagNode tree as nested array of {description,value} pairs
254 ListValue* DxDiagNodeToList(const DxDiagNode& node) {
255 ListValue* list = new ListValue();
256 for (std::map<std::string, std::string>::const_iterator it =
257 node.values.begin();
258 it != node.values.end();
259 ++it) {
260 list->Append(NewDescriptionValuePair(it->first, it->second));
261 }
262
263 for (std::map<std::string, DxDiagNode>::const_iterator it =
264 node.children.begin();
265 it != node.children.end();
266 ++it) {
267 ListValue* sublist = DxDiagNodeToList(it->second);
268 list->Append(NewDescriptionValuePair(it->first, sublist));
269 }
270 return list;
271 }
272
273 #endif // OS_WIN
274
275 std::string VersionNumberToString(uint32 value) {
276 int hi = (value >> 8) & 0xff;
277 int low = value & 0xff;
278 return base::IntToString(hi) + "." + base::IntToString(low);
279 }
280
281 DictionaryValue* GpuInfoToDict(const GPUInfo& gpu_info) {
282 ListValue* basic_info = new ListValue();
283 basic_info->Append(NewDescriptionValuePair("Initialization time",
284 base::Int64ToString(gpu_info.initialization_time().InMilliseconds())));
285 basic_info->Append(NewDescriptionValuePair("Vendor Id",
286 base::StringPrintf("0x%04x", gpu_info.vendor_id())));
287 basic_info->Append(NewDescriptionValuePair("Device Id",
288 base::StringPrintf("0x%04x", gpu_info.device_id())));
289 basic_info->Append(NewDescriptionValuePair("Driver version",
290 WideToASCII(gpu_info.driver_version()).c_str()));
291 basic_info->Append(NewDescriptionValuePair("Pixel shader version",
292 VersionNumberToString(gpu_info.pixel_shader_version())));
293 basic_info->Append(NewDescriptionValuePair("Vertex shader version",
294 VersionNumberToString(gpu_info.vertex_shader_version())));
295 basic_info->Append(NewDescriptionValuePair("GL version",
296 VersionNumberToString(gpu_info.gl_version())));
297
298 DictionaryValue* info = new DictionaryValue();
299 info->Set("basic_info", basic_info);
300
301 if (gpu_info.progress() == GPUInfo::kPartial) {
302 info->SetString("progress", "partial");
303 } else {
304 info->SetString("progress", "complete");
305 }
306 #if defined(OS_WIN)
307 if (gpu_info.progress() == GPUInfo::kComplete) {
308 ListValue* dx_info = DxDiagNodeToList(gpu_info.dx_diagnostics());
309 info->Set("diagnostics", dx_info);
310 }
311 #endif
312
313 return info;
314 }
315
316 Value* GpuMessageHandler::OnRequestGpuInfo(const ListValue* list) {
317 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
318
319 // Get GPU Info.
320 GPUInfo gpu_info = GpuProcessHostUIShim::Get()->gpu_info();
321
322 std::string html;
323 if (gpu_info.progress() != GPUInfo::kComplete) {
324 GpuProcessHostUIShim::Get()->CollectGraphicsInfoAsynchronously();
325 }
326
327 if (gpu_info.progress() != GPUInfo::kUninitialized) {
328 return GpuInfoToDict(gpu_info);
329 } else {
330 return NULL;
331 }
332 }
333
334 } // namespace
335
336
337 ////////////////////////////////////////////////////////////////////////////////
338 //
339 // GpuUI
340 //
341 ////////////////////////////////////////////////////////////////////////////////
342
343 GpuUI::GpuUI(TabContents* contents) : DOMUI(contents) {
344 AddMessageHandler((new GpuMessageHandler())->Attach(this));
345
346 GpuHTMLSource* html_source = new GpuHTMLSource();
347
348 // Set up the chrome://gpu/ source.
349 BrowserThread::PostTask(
350 BrowserThread::IO, FROM_HERE,
351 NewRunnableMethod(
352 Singleton<ChromeURLDataManager>::get(),
353 &ChromeURLDataManager::AddDataSource,
354 make_scoped_refptr(html_source)));
355 }
356
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698