| Index: chrome/browser/dom_ui/gpu_ui.cc
|
| ===================================================================
|
| --- chrome/browser/dom_ui/gpu_ui.cc (revision 0)
|
| +++ chrome/browser/dom_ui/gpu_ui.cc (revision 0)
|
| @@ -0,0 +1,360 @@
|
| +// Copyright (c) 2010 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/dom_ui/gpu_ui.h"
|
| +
|
| +#include <algorithm>
|
| +#include <string>
|
| +#include <utility>
|
| +#include <vector>
|
| +
|
| +#include "app/l10n_util.h"
|
| +#include "app/resource_bundle.h"
|
| +#include "base/command_line.h"
|
| +#include "base/file_util.h"
|
| +#include "base/message_loop.h"
|
| +#include "base/path_service.h"
|
| +#include "base/singleton.h"
|
| +#include "base/string_number_conversions.h"
|
| +#include "base/string_piece.h"
|
| +#include "base/utf_string_conversions.h"
|
| +#include "base/values.h"
|
| +#include "chrome/browser/browser_process.h"
|
| +#include "chrome/browser/browser_thread.h"
|
| +#include "chrome/browser/dom_ui/chrome_url_data_manager.h"
|
| +#include "chrome/browser/gpu_process_host.h"
|
| +#include "chrome/browser/gpu_process_host_ui_shim.h"
|
| +#include "chrome/browser/io_thread.h"
|
| +#include "chrome/browser/net/chrome_net_log.h"
|
| +#include "chrome/browser/net/connection_tester.h"
|
| +#include "chrome/browser/net/passive_log_collector.h"
|
| +#include "chrome/browser/net/url_fixer_upper.h"
|
| +#include "chrome/browser/platform_util.h"
|
| +#include "chrome/browser/profile.h"
|
| +#include "chrome/common/chrome_paths.h"
|
| +#include "chrome/common/chrome_version_info.h"
|
| +#include "chrome/common/net/url_request_context_getter.h"
|
| +#include "chrome/common/url_constants.h"
|
| +#include "grit/generated_resources.h"
|
| +#include "grit/gpu_resources.h"
|
| +#include "grit/net_internals_resources.h"
|
| +#include "net/base/escape.h"
|
| +#include "net/base/host_resolver_impl.h"
|
| +#include "net/base/net_errors.h"
|
| +#include "net/base/net_util.h"
|
| +#include "net/base/sys_addrinfo.h"
|
| +#include "net/disk_cache/disk_cache.h"
|
| +#include "net/http/http_cache.h"
|
| +#include "net/http/http_network_layer.h"
|
| +#include "net/http/http_network_session.h"
|
| +#include "net/http/http_proxy_client_socket_pool.h"
|
| +#include "net/proxy/proxy_service.h"
|
| +#include "net/socket/socks_client_socket_pool.h"
|
| +#include "net/socket/ssl_client_socket_pool.h"
|
| +#include "net/socket/tcp_client_socket_pool.h"
|
| +#include "net/url_request/url_request_context.h"
|
| +
|
| +namespace {
|
| +
|
| +class GpuHTMLSource : public ChromeURLDataManager::DataSource {
|
| + public:
|
| + GpuHTMLSource();
|
| +
|
| + // Called when the network layer has requested a resource underneath
|
| + // the path we registered.
|
| + virtual void StartDataRequest(const std::string& path,
|
| + bool is_off_the_record,
|
| + int request_id);
|
| + virtual std::string GetMimeType(const std::string&) const;
|
| +
|
| + private:
|
| + ~GpuHTMLSource() {}
|
| + DISALLOW_COPY_AND_ASSIGN(GpuHTMLSource);
|
| +};
|
| +
|
| +// This class receives javascript messages from the renderer.
|
| +// Note that the DOMUI infrastructure runs on the UI thread, therefore all of
|
| +// this class's methods are expected to run on the UI thread.
|
| +//
|
| +// Since the network code we want to run lives on the IO thread, we proxy
|
| +// everything over to GpuMessageHandler::IOThreadImpl, which runs
|
| +// on the IO thread.
|
| +//
|
| +// TODO(eroman): Can we start on the IO thread to begin with?
|
| +class GpuMessageHandler
|
| + : public DOMMessageHandler,
|
| + public base::SupportsWeakPtr<GpuMessageHandler> {
|
| + public:
|
| + GpuMessageHandler();
|
| + virtual ~GpuMessageHandler();
|
| +
|
| + // DOMMessageHandler implementation.
|
| + virtual DOMMessageHandler* Attach(DOMUI* dom_ui);
|
| + virtual void RegisterMessages();
|
| +
|
| + // Mesages
|
| + void OnCallAsync(const ListValue* list);
|
| +
|
| + // Submessages dispatched from OnCallAsync
|
| + Value* OnRequestGpuInfo(const ListValue* list);
|
| + Value* OnRequestClientInfo(const ListValue* list);
|
| +
|
| + // Executes the javascript function |function_name| in the renderer, passing
|
| + // it the argument |value|.
|
| + void CallJavascriptFunction(const std::wstring& function_name,
|
| + const Value* value);
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(GpuMessageHandler);
|
| + bool collecting_graphics_info_;
|
| +};
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +//
|
| +// GpuHTMLSource
|
| +//
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +
|
| +GpuHTMLSource::GpuHTMLSource()
|
| + : DataSource(chrome::kChromeUIGpuHost, MessageLoop::current()) {
|
| +}
|
| +
|
| +void GpuHTMLSource::StartDataRequest(const std::string& path,
|
| + bool is_off_the_record,
|
| + int request_id) {
|
| + // The provided "path" may contain a fragment, or query section. We only
|
| + // care about the path itself, and will disregard anything else.
|
| + std::string filename =
|
| + GURL(std::string("chrome://net/") + path).path().substr(1);
|
| +
|
| + // The source for the net internals page is flattened during compilation, so
|
| + // the only resource that should legitimately be requested is the main file.
|
| + // Note that users can type anything into the address bar, though, so we must
|
| + // handle arbitrary input.
|
| + if (filename.empty() || filename == "index.html") {
|
| + scoped_refptr<RefCountedStaticMemory> bytes(
|
| + ResourceBundle::GetSharedInstance().LoadDataResourceBytes(
|
| + IDR_GPU_INDEX_HTML));
|
| + if (bytes && bytes->front()) {
|
| + SendResponse(request_id, bytes);
|
| + return;
|
| + }
|
| + }
|
| +
|
| + const std::string data_string("<p style='color:red'>Failed to read resource" +
|
| + EscapeForHTML(filename) + "</p>");
|
| + scoped_refptr<RefCountedBytes> bytes(new RefCountedBytes);
|
| + bytes->data.resize(data_string.size());
|
| + std::copy(data_string.begin(), data_string.end(), bytes->data.begin());
|
| + SendResponse(request_id, bytes);
|
| +}
|
| +
|
| +std::string GpuHTMLSource::GetMimeType(const std::string&) const {
|
| + return "text/html";
|
| +}
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +//
|
| +// GpuMessageHandler
|
| +//
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +
|
| +GpuMessageHandler::GpuMessageHandler()
|
| + : collecting_graphics_info_(false) {
|
| +}
|
| +
|
| +GpuMessageHandler::~GpuMessageHandler() {}
|
| +
|
| +DOMMessageHandler* GpuMessageHandler::Attach(DOMUI* dom_ui) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + DOMMessageHandler* result = DOMMessageHandler::Attach(dom_ui);
|
| + return result;
|
| +}
|
| +
|
| +/* BrowserBridge.callAsync prepends a requestID to these messages. */
|
| +void GpuMessageHandler::RegisterMessages() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| +
|
| + dom_ui_->RegisterMessageCallback(
|
| + "callAsync",
|
| + NewCallback(this, &GpuMessageHandler::OnCallAsync));
|
| +}
|
| +
|
| +void GpuMessageHandler::OnCallAsync(const ListValue* args) {
|
| + DCHECK(args->GetSize() >= 2);
|
| + // unpack args into requestId, submessage and submessageArgs
|
| + bool ok;
|
| + Value* requestId;
|
| + ok = args->Get(0, &requestId);
|
| + DCHECK(ok);
|
| +
|
| + std::string submessage;
|
| + ok = args->GetString(1, &submessage);
|
| + DCHECK(ok);
|
| +
|
| + ListValue* submessageArgs = new ListValue();
|
| + for (size_t i = 2; i < args->GetSize(); ++i) {
|
| + Value* arg;
|
| + ok = args->Get(i, &arg);
|
| + DCHECK(ok);
|
| +
|
| + Value* argCopy = arg->DeepCopy();
|
| + submessageArgs->Append(argCopy);
|
| + }
|
| +
|
| + // call the submessage handler
|
| + Value* ret = NULL;
|
| + if (submessage == "requestGpuInfo") {
|
| + ret = OnRequestGpuInfo(submessageArgs);
|
| + } else if (submessage == "requestClientInfo") {
|
| + ret = OnRequestClientInfo(submessageArgs);
|
| + } else { // unrecognized submessage
|
| + DCHECK(FALSE);
|
| + delete submessageArgs;
|
| + return;
|
| + }
|
| + delete submessageArgs;
|
| +
|
| + // call BrowserBridge.onCallAsyncReply with result
|
| + if (ret) {
|
| + dom_ui_->CallJavascriptFunction(L"g_browser.onCallAsyncReply",
|
| + *requestId,
|
| + *ret);
|
| + delete ret;
|
| + } else {
|
| + dom_ui_->CallJavascriptFunction(L"g_browser.onCallAsyncReply",
|
| + *requestId);
|
| + }
|
| +}
|
| +
|
| +Value* GpuMessageHandler::OnRequestClientInfo(const ListValue* list) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| +
|
| + DictionaryValue* dict = new DictionaryValue();
|
| +
|
| + chrome::VersionInfo version_info;
|
| +
|
| + if (!version_info.is_valid()) {
|
| + DLOG(ERROR) << "Unable to create chrome::VersionInfo";
|
| + } else {
|
| + // We have everything we need to send the right values.
|
| + dict->SetString("version", version_info.Version());
|
| + dict->SetString("cl", version_info.LastChange());
|
| + dict->SetString("version_mod",
|
| + platform_util::GetVersionStringModifier());
|
| + dict->SetString("official",
|
| + l10n_util::GetStringUTF16(
|
| + version_info.IsOfficialBuild() ?
|
| + IDS_ABOUT_VERSION_OFFICIAL
|
| + : IDS_ABOUT_VERSION_UNOFFICIAL));
|
| +
|
| + dict->SetString("command_line",
|
| + CommandLine::ForCurrentProcess()->command_line_string());
|
| + }
|
| +
|
| + return dict;
|
| +}
|
| +
|
| +
|
| +#if defined(OS_WIN)
|
| +// Output DxDiagNode tree as HTML tables and nested HTML unordered list
|
| +// elements.
|
| +DictionaryValue* DxDiagNodeToDict(const DxDiagNode& node) {
|
| + DictionaryValue* dict = new DictionaryValue();
|
| + for (std::map<std::string, std::string>::const_iterator it =
|
| + node.values.begin();
|
| + it != node.values.end();
|
| + ++it) {
|
| + dict->SetString(EscapeForHTML(it->first), EscapeForHTML(it->second));
|
| + }
|
| +
|
| + for (std::map<std::string, DxDiagNode>::const_iterator it =
|
| + node.children.begin();
|
| + it != node.children.end();
|
| + ++it) {
|
| + DictionaryValue* subdict = DxDiagNodeToDict(it->second);
|
| + dict->Set(EscapeForHTML(it->first), subdict);
|
| + }
|
| + return dict;
|
| +}
|
| +
|
| +#endif // OS_WIN
|
| +
|
| +std::string VersionNumberToString(uint32 value) {
|
| + int hi = (value >> 8) & 0xff;
|
| + int low = value & 0xff;
|
| + return base::IntToString(hi) + "." + base::IntToString(low);
|
| +}
|
| +
|
| +DictionaryValue* GpuInfoToDict(const GPUInfo& gpu_info) {
|
| +
|
| + DictionaryValue* info = new DictionaryValue();
|
| + info->SetString("Initialization time",
|
| + base::Int64ToString(gpu_info.initialization_time().InMilliseconds()));
|
| + info->SetString("Vendor Id",
|
| + base::StringPrintf("0x%04x", gpu_info.vendor_id()));
|
| + info->SetString("Device Id",
|
| + base::StringPrintf("0x%04x", gpu_info.device_id()));
|
| + info->SetString("Driver version",
|
| + WideToASCII(gpu_info.driver_version()).c_str());
|
| + info->SetString("Pixel shader version",
|
| + VersionNumberToString(gpu_info.pixel_shader_version()));
|
| + info->SetString("Vertex shader version",
|
| + VersionNumberToString(gpu_info.vertex_shader_version()));
|
| + info->SetString("GL version", VersionNumberToString(gpu_info.gl_version()));
|
| +
|
| + DictionaryValue* dict = new DictionaryValue();
|
| + dict->Set("Basic GPU Information", info);
|
| +
|
| +#if defined(OS_WIN)
|
| + DictionaryValue* dx_info = DxDiagNodeToDict(gpu_info.dx_diagnostics());
|
| + dict->Set("DirectX diagnostics", dx_info);
|
| +#endif
|
| +
|
| + return dict;
|
| +}
|
| +
|
| +Value* GpuMessageHandler::OnRequestGpuInfo(const ListValue* list) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| +
|
| + // Get GPU Info.
|
| + GPUInfo gpu_info = GpuProcessHost::Get()->gpu_info();
|
| +
|
| + std::string html;
|
| + if (!gpu_info.initialized()) {
|
| + if (!collecting_graphics_info_) {
|
| + GpuProcessHostUIShim::Get()->CollectGraphicsInfoAsynchronously();
|
| + collecting_graphics_info_ = true;
|
| + }
|
| + return NULL;
|
| + } else {
|
| + collecting_graphics_info_ = false;
|
| +
|
| + return GpuInfoToDict(gpu_info);
|
| + }
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +//
|
| +// GpuUI
|
| +//
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +
|
| +GpuUI::GpuUI(TabContents* contents) : DOMUI(contents) {
|
| + AddMessageHandler((new GpuMessageHandler())->Attach(this));
|
| +
|
| + GpuHTMLSource* html_source = new GpuHTMLSource();
|
| +
|
| + // Set up the chrome://gpu/ source.
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + NewRunnableMethod(
|
| + Singleton<ChromeURLDataManager>::get(),
|
| + &ChromeURLDataManager::AddDataSource,
|
| + make_scoped_refptr(html_source)));
|
| +}
|
| +
|
|
|
| Property changes on: chrome\browser\dom_ui\gpu_ui.cc
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|