Chromium Code Reviews
|
| OLD | NEW |
|---|---|
| (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 | |
| OLD | NEW |