diff options
author | eroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-05 19:28:36 +0000 |
---|---|---|
committer | eroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-05 19:28:36 +0000 |
commit | a0360d8b084eb8908b5bc57e409304aa96947bd4 (patch) | |
tree | ddfbcfe03a7d2ed1722e6da00809155dc12a9b96 | |
parent | 678223eaf6708d2d3839d488c99729c80ddb8f6f (diff) | |
download | chromium_src-a0360d8b084eb8908b5bc57e409304aa96947bd4.zip chromium_src-a0360d8b084eb8908b5bc57e409304aa96947bd4.tar.gz chromium_src-a0360d8b084eb8908b5bc57e409304aa96947bd4.tar.bz2 |
Add the proxy information to the new net internals page.
BUG=37421
Review URL: http://codereview.chromium.org/1607004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@43636 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/dom_ui/net_internals_ui.cc | 159 | ||||
-rw-r--r-- | chrome/browser/resources/net_internals/index.html | 22 | ||||
-rw-r--r-- | chrome/browser/resources/net_internals/main.css | 12 | ||||
-rw-r--r-- | chrome/browser/resources/net_internals/main.js | 190 | ||||
-rw-r--r-- | chrome/browser/resources/net_internals/proxyview.js | 62 | ||||
-rw-r--r-- | chrome/browser/resources/net_internals/requestsview.js | 2 | ||||
-rwxr-xr-x | chrome/chrome_browser.gypi | 1 |
7 files changed, 404 insertions, 44 deletions
diff --git a/chrome/browser/dom_ui/net_internals_ui.cc b/chrome/browser/dom_ui/net_internals_ui.cc index c04b30a..d33b17f 100644 --- a/chrome/browser/dom_ui/net_internals_ui.cc +++ b/chrome/browser/dom_ui/net_internals_ui.cc @@ -4,6 +4,8 @@ #include "chrome/browser/dom_ui/net_internals_ui.h" +#include <sstream> + #include "app/resource_bundle.h" #include "base/file_util.h" #include "base/path_service.h" @@ -12,15 +14,25 @@ #include "base/string_util.h" #include "base/values.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/dom_ui/chrome_url_data_manager.h" #include "chrome/browser/chrome_thread.h" +#include "chrome/browser/dom_ui/chrome_url_data_manager.h" #include "chrome/browser/io_thread.h" #include "chrome/browser/net/chrome_net_log.h" +#include "chrome/browser/net/url_request_context_getter.h" +#include "chrome/browser/profile.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/url_constants.h" +#include "net/base/escape.h" +#include "net/proxy/proxy_service.h" +#include "net/url_request/url_request_context.h" namespace { +// Formats |t| as a decimal number, in milliseconds. +std::string TickCountToString(const base::TimeTicks& t) { + return Int64ToString((t - base::TimeTicks()).InMilliseconds()); +} + // TODO(eroman): Bootstrap the net-internals page using the passively logged // data. @@ -93,7 +105,8 @@ class NetInternalsMessageHandler::IOThreadImpl // we need to grab it from the UI thread). IOThreadImpl( const base::WeakPtr<NetInternalsMessageHandler>& handler, - IOThread* io_thread); + IOThread* io_thread, + URLRequestContextGetter* context_getter); ~IOThreadImpl(); @@ -115,6 +128,11 @@ class NetInternalsMessageHandler::IOThreadImpl // it indicates that the renderer is ready to start receiving captured data. void OnRendererReady(const Value* value); + void OnGetProxySettings(const Value* value); + void OnReloadProxySettings(const Value* value); + void OnGetBadProxies(const Value* value); + void OnClearBadProxies(const Value* value); + // ChromeNetLog::Observer implementation: virtual void OnAddEntry(const net::NetLog::Entry& entry); @@ -129,7 +147,6 @@ class NetInternalsMessageHandler::IOThreadImpl void CallJavascriptFunction(const std::wstring& function_name, Value* arg); - private: // Pointer to the UI-thread message handler. Only access this from // the UI thread. base::WeakPtr<NetInternalsMessageHandler> handler_; @@ -137,6 +154,8 @@ class NetInternalsMessageHandler::IOThreadImpl // The global IOThread, which contains the global NetLog to observer. IOThread* io_thread_; + scoped_refptr<URLRequestContextGetter> context_getter_; + // True if we have attached an observer to the NetLog already. bool is_observing_log_; friend class base::RefCountedThreadSafe<IOThreadImpl>; @@ -192,7 +211,15 @@ void NetInternalsHTMLSource::StartDataRequest(const std::string& path, std::string data_string; FilePath file_path; PathService::Get(chrome::DIR_NET_INTERNALS, &file_path); - std::string filename = path.empty() ? "index.html" : path; + std::string filename; + + // The provided "path" may contain a fragment, or query section. We only + // care about the path itself, and will disregard anything else. + filename = GURL(std::string("chrome://net/") + path).path().substr(1); + + if (filename.empty()) + filename = "index.html"; + file_path = file_path.AppendASCII(filename); if (!file_util::ReadFileToString(file_path, &data_string)) { @@ -233,7 +260,8 @@ NetInternalsMessageHandler::~NetInternalsMessageHandler() { DOMMessageHandler* NetInternalsMessageHandler::Attach(DOMUI* dom_ui) { DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); - proxy_ = new IOThreadImpl(this->AsWeakPtr(), g_browser_process->io_thread()); + proxy_ = new IOThreadImpl(this->AsWeakPtr(), g_browser_process->io_thread(), + dom_ui->GetProfile()->GetRequestContext()); DOMMessageHandler* result = DOMMessageHandler::Attach(dom_ui); return result; } @@ -243,6 +271,14 @@ void NetInternalsMessageHandler::RegisterMessages() { dom_ui_->RegisterMessageCallback("notifyReady", proxy_->CreateCallback(&IOThreadImpl::OnRendererReady)); + dom_ui_->RegisterMessageCallback("getProxySettings", + proxy_->CreateCallback(&IOThreadImpl::OnGetProxySettings)); + dom_ui_->RegisterMessageCallback("reloadProxySettings", + proxy_->CreateCallback(&IOThreadImpl::OnReloadProxySettings)); + dom_ui_->RegisterMessageCallback("getBadProxies", + proxy_->CreateCallback(&IOThreadImpl::OnGetBadProxies)); + dom_ui_->RegisterMessageCallback("clearBadProxies", + proxy_->CreateCallback(&IOThreadImpl::OnClearBadProxies)); } void NetInternalsMessageHandler::CallJavascriptFunction( @@ -260,9 +296,11 @@ void NetInternalsMessageHandler::CallJavascriptFunction( NetInternalsMessageHandler::IOThreadImpl::IOThreadImpl( const base::WeakPtr<NetInternalsMessageHandler>& handler, - IOThread* io_thread) + IOThread* io_thread, + URLRequestContextGetter* context_getter) : handler_(handler), io_thread_(io_thread), + context_getter_(context_getter), is_observing_log_(false) { DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); } @@ -308,7 +346,7 @@ void NetInternalsMessageHandler::IOThreadImpl::OnRendererReady( static_cast<int>(event_types[i])); } - CallJavascriptFunction(L"setLogEventTypeConstants", dict); + CallJavascriptFunction(L"g_browser.receivedLogEventTypeConstants", dict); } // Tell the javascript about the relationship between event phase enums and @@ -320,7 +358,7 @@ void NetInternalsMessageHandler::IOThreadImpl::OnRendererReady( dict->SetInteger(L"PHASE_END", net::NetLog::PHASE_END); dict->SetInteger(L"PHASE_NONE", net::NetLog::PHASE_NONE); - CallJavascriptFunction(L"setLogEventPhaseConstants", dict); + CallJavascriptFunction(L"g_browser.receivedLogEventPhaseConstants", dict); } // Tell the javascript about the relationship between source type enums and @@ -336,7 +374,7 @@ void NetInternalsMessageHandler::IOThreadImpl::OnRendererReady( net::NetLog::SOURCE_INIT_PROXY_RESOLVER); dict->SetInteger(L"CONNECT_JOB", net::NetLog::SOURCE_CONNECT_JOB); - CallJavascriptFunction(L"setLogSourceTypeConstants", dict); + CallJavascriptFunction(L"g_browser.receivedLogSourceTypeConstants", dict); } // Tell the javascript about the relationship between entry type enums and @@ -348,8 +386,99 @@ void NetInternalsMessageHandler::IOThreadImpl::OnRendererReady( dict->SetInteger(L"TYPE_STRING", net::NetLog::Entry::TYPE_STRING); dict->SetInteger(L"TYPE_ERROR_CODE", net::NetLog::Entry::TYPE_ERROR_CODE); - CallJavascriptFunction(L"setLogEntryTypeConstants", dict); + CallJavascriptFunction(L"g_browser.receivedLogEntryTypeConstants", dict); + } + + // Tell the javascript how the "time ticks" values we have given it relate to + // actual system times. (We used time ticks throughout since they are stable + // across system clock changes). + { + int64 cur_time_ms = (base::Time::Now() - base::Time()).InMilliseconds(); + + int64 cur_time_ticks_ms = + (base::TimeTicks::Now() - base::TimeTicks()).InMilliseconds(); + + // If we add this number to a time tick value, it gives the timestamp. + int64 tick_to_time_ms = cur_time_ms - cur_time_ticks_ms; + + // Chrome on all platforms stores times using the Windows epoch + // (Jan 1 1601), but the javascript wants a unix epoch. + // TODO(eroman): Getting the timestamp relative the to unix epoch should + // be part of the time library. + const int64 kUnixEpochMs = 11644473600000LL; + int64 tick_to_unix_time_ms = tick_to_time_ms - kUnixEpochMs; + + // Pass it as a string, since it may be too large to fit in an integer. + CallJavascriptFunction(L"g_browser.receivedTimeTickOffset", + Value::CreateStringValue( + Int64ToString(tick_to_unix_time_ms))); + } + + // Notify the client of the basic proxy data. + OnGetProxySettings(NULL); + OnGetBadProxies(NULL); +} + +void NetInternalsMessageHandler::IOThreadImpl::OnGetProxySettings( + const Value* value) { + URLRequestContext* context = context_getter_->GetURLRequestContext(); + net::ProxyService* proxy_service = context->proxy_service(); + + // TODO(eroman): send a dictionary rather than a flat string, so client can do + // its own presentation. + std::string settings_string; + + if (proxy_service->config_has_been_initialized()) { + // net::ProxyConfig defines an operator<<. + std::ostringstream stream; + stream << proxy_service->config(); + settings_string = stream.str(); + } + + CallJavascriptFunction(L"g_browser.receivedProxySettings", + Value::CreateStringValue(settings_string)); +} + +void NetInternalsMessageHandler::IOThreadImpl::OnReloadProxySettings( + const Value* value) { + URLRequestContext* context = context_getter_->GetURLRequestContext(); + context->proxy_service()->ForceReloadProxyConfig(); + + // Cause the renderer to be notified of the new values. + OnGetProxySettings(NULL); +} + +void NetInternalsMessageHandler::IOThreadImpl::OnGetBadProxies( + const Value* value) { + URLRequestContext* context = context_getter_->GetURLRequestContext(); + + const net::ProxyRetryInfoMap& bad_proxies_map = + context->proxy_service()->proxy_retry_info(); + + ListValue* list = new ListValue(); + + for (net::ProxyRetryInfoMap::const_iterator it = bad_proxies_map.begin(); + it != bad_proxies_map.end(); ++it) { + const std::string& proxy_uri = it->first; + const net::ProxyRetryInfo& retry_info = it->second; + + DictionaryValue* dict = new DictionaryValue(); + dict->SetString(L"proxy_uri", proxy_uri); + dict->SetString(L"bad_until", TickCountToString(retry_info.bad_until)); + + list->Append(dict); } + + CallJavascriptFunction(L"g_browser.receivedBadProxies", list); +} + +void NetInternalsMessageHandler::IOThreadImpl::OnClearBadProxies( + const Value* value) { + URLRequestContext* context = context_getter_->GetURLRequestContext(); + context->proxy_service()->ClearBadProxiesCache(); + + // Cause the renderer to be notified of the new values. + OnGetBadProxies(NULL); } void NetInternalsMessageHandler::IOThreadImpl::OnAddEntry( @@ -368,10 +497,9 @@ void NetInternalsMessageHandler::IOThreadImpl::OnAddEntry( entry_dict->SetInteger(L"type", static_cast<int>(entry_type)); } - // Set the entry time. - entry_dict->SetInteger( - L"time", - static_cast<int>((entry.time - base::TimeTicks()).InMilliseconds())); + // Set the entry time. (Note that we send it as a string since integers + // might overflow). + entry_dict->SetString(L"time", TickCountToString(entry.time)); // Set the entry source. DictionaryValue* source_dict = new DictionaryValue(); @@ -402,7 +530,7 @@ void NetInternalsMessageHandler::IOThreadImpl::OnAddEntry( entry_dict->SetInteger(L"error_code", entry.error_code); } - CallJavascriptFunction(L"onLogEntryAdded", entry_dict); + CallJavascriptFunction(L"g_browser.receivedLogEntry", entry_dict); } void NetInternalsMessageHandler::IOThreadImpl::DispatchToMessageHandler( @@ -439,7 +567,6 @@ void NetInternalsMessageHandler::IOThreadImpl::CallJavascriptFunction( // Failed posting the task, avoid leaking. delete arg; } - } } // namespace diff --git a/chrome/browser/resources/net_internals/index.html b/chrome/browser/resources/net_internals/index.html index fb7ff9a..f6df28d 100644 --- a/chrome/browser/resources/net_internals/index.html +++ b/chrome/browser/resources/net_internals/index.html @@ -18,6 +18,7 @@ found in the LICENSE file. <script src="timelineviewpainter.js"></script> <script src="logviewpainter.js"></script> <script src="loggrouper.js"></script> + <script src="proxyview.js"></script> </head> <body onload="onLoaded()"> <!-- Tab switcher for main categories. --> @@ -31,8 +32,27 @@ found in the LICENSE file. </ul> <div style="clear: both;"></div> </div> + <!-- Proxy info --> + <div id=proxyTabContent> + <h4> + Current proxy settings + <input type=button value="Reload settings" id=proxyReloadSettings /> + </h4> + <pre id=proxyCurrentConfig></pre> + + <h4> + Proxies which have failed recently, and are marked as bad + <input type=button value="Clear bad proxies" id=clearBadProxies /> + </h4> + <table border=1> + <thead> + <th>Bad proxy server</th> + <th>Time for next retry</th> + </thead> + <tbody id=badProxiesTableBody></tbody> + </table> + </div> <!-- Sections TODO --> - <div id=proxyTabContent>TODO: display proxy information (PAC error log, initialization log, current settings.)</div> <div id=dnsTabContent>TODO: display dns information (outstanding jobs, host cache).</div> <div id=socketsTabContent>TODO: display socket information (outstanding connect jobs)</div> <div id=httpCacheTabContent>TODO: display http cache information (disk cache navigator)</div> diff --git a/chrome/browser/resources/net_internals/main.css b/chrome/browser/resources/net_internals/main.css index cc87520..76c608d 100644 --- a/chrome/browser/resources/net_internals/main.css +++ b/chrome/browser/resources/net_internals/main.css @@ -180,6 +180,16 @@ body { } #detailsLogBox, -#detailsTimelineBox { +#detailsTimelineBox, +#proxyTabContent { overflow: auto; } + +#proxyTabContent { + padding-left: 20px; +} + +#proxyTabContent td, +#proxyTabContent th { + font-size: 12px; +} diff --git a/chrome/browser/resources/net_internals/main.js b/chrome/browser/resources/net_internals/main.js index 7b9d3c9..c9bf433 100644 --- a/chrome/browser/resources/net_internals/main.js +++ b/chrome/browser/resources/net_internals/main.js @@ -11,9 +11,17 @@ var LogEventPhase = null; var LogSourceType = null; /** + * Object to communicate between the renderer and the browser. + * @type {!BrowserBridge} + */ +var g_browser = null; + +/** * Main entry point. called once the page has loaded. */ function onLoaded() { + g_browser = new BrowserBridge(); + // Create the view which displays requests lists, and lets you select, filter // and delete them. var requestsView = new RequestsView('requestsListTableBody', @@ -35,13 +43,20 @@ function onLoaded() { "actionBox", "splitterBox"); + // Create a view which will display info on the proxy setup. + var proxyView = new ProxyView("proxyTabContent", + "proxyCurrentConfig", + "proxyReloadSettings", + "badProxiesTableBody", + "clearBadProxies"); + // Create a view which lets you tab between the different sub-views. var categoryTabSwitcher = new TabSwitcherView(new DivView('categoryTabHandles')); // Populate the main tabs. categoryTabSwitcher.addTab('requestsTab', requestsView); - categoryTabSwitcher.addTab('proxyTab', new DivView('proxyTabContent')); + categoryTabSwitcher.addTab('proxyTab', proxyView); categoryTabSwitcher.addTab('dnsTab', new DivView('dnsTabContent')); categoryTabSwitcher.addTab('socketsTab', new DivView('socketsTabContent')); categoryTabSwitcher.addTab('httpCacheTab', @@ -57,55 +72,180 @@ function onLoaded() { windowView.resetGeometry(); // Tell the browser that we are ready to start receiving log events. - notifyApplicationReady(); + g_browser.sendReady(); } +/** + * This class provides a "bridge" for communicating between the javascript and + * the browser. + * + * @constructor + */ +function BrowserBridge() { + // List of observers for various bits of browser state. + this.logObservers_ = []; + this.proxySettingsObservers_ = []; + this.badProxiesObservers_ = []; + + // Map from observer method name (i.e. 'onProxySettingsChanged', 'onBadProxiesChanged') + // to the previously received data for that type. Used to tell if the data has + // actually changed since we last polled it. + this.prevPollData_ = {}; +} + +/** + * Delay in milliseconds between polling of certain browser information. + */ +BrowserBridge.POLL_INTERVAL_MS = 5000; + //------------------------------------------------------------------------------ // Messages sent to the browser //------------------------------------------------------------------------------ -function notifyApplicationReady() { +BrowserBridge.prototype.sendReady = function() { chrome.send('notifyReady'); -} + + // Some of the data we are interested is not currently exposed as a stream, + // so we will poll the browser to find out when it changes and then notify + // the observers. + window.setInterval( + this.doPolling_.bind(this), BrowserBridge.POLL_INTERVAL_MS); +}; + +BrowserBridge.prototype.sendGetProxySettings = function() { + // The browser will call receivedProxySettings on completion. + chrome.send('getProxySettings'); +}; + +BrowserBridge.prototype.sendReloadProxySettings = function() { + chrome.send('reloadProxySettings'); +}; + +BrowserBridge.prototype.sendGetBadProxies = function() { + // The browser will call receivedBadProxies on completion. + chrome.send('getBadProxies'); +}; + +BrowserBridge.prototype.sendClearBadProxies = function() { + chrome.send('clearBadProxies'); +}; //------------------------------------------------------------------------------ // Messages received from the browser //------------------------------------------------------------------------------ -function onLogEntryAdded(logEntry) { - LogDataProvider.broadcast(logEntry); -} +BrowserBridge.prototype.receivedLogEntry = function(logEntry) { + for (var i = 0; i < this.logObservers_.length; ++i) + this.logObservers_[i].onLogEntryAdded(logEntry); +}; -function setLogEventTypeConstants(constantsMap) { +BrowserBridge.prototype.receivedLogEventTypeConstants = function(constantsMap) { LogEventType = constantsMap; -} +}; -function setLogEventPhaseConstants(constantsMap) { +BrowserBridge.prototype.receivedLogEventPhaseConstants = function(constantsMap) { LogEventPhase = constantsMap; -} +}; -function setLogSourceTypeConstants(constantsMap) { +BrowserBridge.prototype.receivedLogSourceTypeConstants = function(constantsMap) { LogSourceType = constantsMap; -} +}; -function setLogEntryTypeConstants(constantsMap) { +BrowserBridge.prototype.receivedLogEntryTypeConstants = function(constantsMap) { LogEntryType = constantsMap; -} +}; + +BrowserBridge.prototype.receivedTimeTickOffset = function(timeTickOffset) { + this.timeTickOffset_ = timeTickOffset; +}; + +BrowserBridge.prototype.receivedProxySettings = function(proxySettings) { + this.dispatchToObserversFromPoll_( + this.proxySettingsObservers_, 'onProxySettingsChanged', proxySettings); +}; + +BrowserBridge.prototype.receivedBadProxies = function(badProxies) { + this.dispatchToObserversFromPoll_( + this.badProxiesObservers_, 'onBadProxiesChanged', badProxies); +}; -//------------------------------------------------------------------------------ -// LogDataProvider //------------------------------------------------------------------------------ -var LogDataProvider = {} +/** + * Adds a listener of log entries. |observer| will be called back when new log + * data arrives, through: + * + * observer.onLogEntryAdded(logEntry) + */ +BrowserBridge.prototype.addLogObserver = function(observer) { + this.logObservers_.push(observer); +}; -LogDataProvider.observers_ = []; +/** + * Adds a listener of the proxy settings. |observer| will be called back when + * data is received, through: + * + * observer.onProxySettingsChanged(proxySettings) + * + * |proxySettings| is a formatted string describing the settings. + * TODO(eroman): send a dictionary instead. + */ +BrowserBridge.prototype.addProxySettingsObserver = function(observer) { + this.proxySettingsObservers_.push(observer); +}; + +/** + * Adds a listener of the proxy settings. |observer| will be called back when + * data is received, through: + * + * observer.onBadProxiesChanged(badProxies) + * + * |badProxies| is an array, where each entry has the property: + * badProxies[i].proxy_uri: String identify the proxy. + * badProxies[i].bad_until: The time when the proxy stops being considered + * bad. Note the time is in time ticks. + */ +BrowserBridge.prototype.addBadProxiesObsever = function(observer) { + this.badProxiesObservers_.push(observer); +}; + +/** + * The browser gives us times in terms of "time ticks" in milliseconds. + * This function converts the tick count to a Date() object. + * + * @param {String} timeTicks. + * @returns {Date} The time that |timeTicks| represents. + */ +BrowserBridge.prototype.convertTimeTicksToDate = function(timeTicks) { + // Note that the subtraction by 0 is to cast to a number (probably a float + // since the numbers are big). + var timeStampMs = (this.timeTickOffset_ - 0) + (timeTicks - 0); + var d = new Date(); + d.setTime(timeStampMs); + return d; +}; -LogDataProvider.broadcast = function(logEntry) { - for (var i = 0; i < this.observers_.length; ++i) { - this.observers_[i].onLogEntryAdded(logEntry); - } +BrowserBridge.prototype.doPolling_ = function() { + this.sendGetProxySettings(); + this.sendGetBadProxies(); }; -LogDataProvider.addObserver = function(observer) { - this.observers_.push(observer); +/** + * Helper function to handle calling all the observers, but ONLY if the data has + * actually changed since last time. This is used for data we received from + * browser on a poll loop. + */ +BrowserBridge.prototype.dispatchToObserversFromPoll_ = function( + observerList, method, data) { + var prevData = this.prevPollData_[method]; + + // If the data hasn't changed since last time, no need to notify observers. + if (prevData && JSON.stringify(prevData) == JSON.stringify(data)) + return; + + this.prevPollData_[method] = data; + + // Ok, notify the observers of the change. + for (var i = 0; i < observerList.length; ++i) + observerList[i][method](data); }; diff --git a/chrome/browser/resources/net_internals/proxyview.js b/chrome/browser/resources/net_internals/proxyview.js new file mode 100644 index 0000000..4d7d885 --- /dev/null +++ b/chrome/browser/resources/net_internals/proxyview.js @@ -0,0 +1,62 @@ +// 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. + +/** + * This view displays information on the proxy setup: + * + * - Shows the current proxy settings. + * - Has a button to reload these settings. + * - Shows the list of proxy hostnames that are cached as "bad". + * - Has a button to clear the cached bad proxies. + * + * @constructor + */ +function ProxyView(mainBoxId, + currentConfigDivId, + reloadSettingsButtonId, + badProxiesTbodyId, + clearBadProxiesButtonId) { + DivView.call(this, mainBoxId); + + // Hook up the UI components. + this.currentConfigDiv_ = document.getElementById(currentConfigDivId); + this.badProxiesTbody_ = document.getElementById(badProxiesTbodyId); + + var reloadSettingsButton = document.getElementById(reloadSettingsButtonId); + var clearBadProxiesButton = document.getElementById(clearBadProxiesButtonId); + + clearBadProxiesButton.onclick = g_browser.sendClearBadProxies.bind(g_browser); + reloadSettingsButton.onclick = + g_browser.sendReloadProxySettings.bind(g_browser); + + // Register to receive proxy information as it changes. + g_browser.addProxySettingsObserver(this); + g_browser.addBadProxiesObsever(this); +} + +inherits(ProxyView, DivView); + +ProxyView.prototype.onProxySettingsChanged = function(proxySettings) { + // |proxySettings| is a formatted string describing the settings. + this.currentConfigDiv_.innerHTML = '' + addTextNode(this.currentConfigDiv_, proxySettings); +}; + +ProxyView.prototype.onBadProxiesChanged = function(badProxies) { + this.badProxiesTbody_.innerHTML = ''; + + // Add a table row for each bad proxy entry. + for (var i = 0; i < badProxies.length; ++i) { + var entry = badProxies[i]; + var badUntilDate = g_browser.convertTimeTicksToDate(entry.bad_until); + + var tr = addNode(this.badProxiesTbody_, 'tr'); + + var nameCell = addNode(tr, 'td'); + var badUntilCell = addNode(tr, 'td'); + + addTextNode(nameCell, entry.proxy_uri); + addTextNode(badUntilCell, badUntilDate.toLocaleString()); + } +}; diff --git a/chrome/browser/resources/net_internals/requestsview.js b/chrome/browser/resources/net_internals/requestsview.js index 16b39b9..2d16704 100644 --- a/chrome/browser/resources/net_internals/requestsview.js +++ b/chrome/browser/resources/net_internals/requestsview.js @@ -49,7 +49,7 @@ function RequestsView(tableBodyId, filterInputId, filterCountId, this.sourceIdToEntryMap_ = {}; this.currentSelectedSources_ = []; - LogDataProvider.addObserver(this); + g_browser.addLogObserver(this); this.tableBody_ = document.getElementById(tableBodyId); diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index cedfbbe..d9df1a3 100755 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -3185,6 +3185,7 @@ 'browser/resources/net_internals/logviewpainter.js', 'browser/resources/net_internals/main.css', 'browser/resources/net_internals/main.js', + 'browser/resources/net_internals/proxyview.js', 'browser/resources/net_internals/requestsview.js', 'browser/resources/net_internals/resizableverticalsplitview.js', 'browser/resources/net_internals/sourceentry.js', |