172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/webui/net_internals_ui.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <algorithm>
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string>
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <utility>
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector>
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/base64.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/command_line.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_util.h"
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/singleton.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/path_service.h"
183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_piece.h"
20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/string_split.h"
21dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/string_util.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h"
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/values.h"
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser_process.h"
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/io_thread.h"
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/net/chrome_net_log.h"
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/net/connection_tester.h"
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/net/passive_log_collector.h"
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/net/url_fixer_upper.h"
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/platform_util.h"
31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/prefs/pref_member.h"
3221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/shell_dialogs.h"
34dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/webui/chrome_url_data_manager.h"
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_paths.h"
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_version_info.h"
3721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/common/jstemplate_builder.h"
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/common/pref_names.h"
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/url_constants.h"
40dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
41dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h"
42dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents_view.h"
43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_details.h"
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h"
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/net_internals_resources.h"
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/escape.h"
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/host_resolver_impl.h"
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_errors.h"
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_util.h"
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/sys_addrinfo.h"
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/base/x509_cert_types.h"
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/disk_cache/disk_cache.h"
5372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "net/http/http_alternate_protocols.h"
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/http/http_cache.h"
553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/http/http_network_layer.h"
563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/http/http_network_session.h"
57dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "net/http/http_stream_factory.h"
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/proxy/proxy_service.h"
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/url_request/url_request_context.h"
60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/url_request/url_request_context_getter.h"
6172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h"
6272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/resource/resource_bundle.h"
6372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#ifdef OS_WIN
653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/net/service_providers_win.h"
663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#endif
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
703f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// Delay between when an event occurs and when it is passed to the Javascript
713f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// page.  All events that occur during this period are grouped together and
723f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// sent to the page at once, which reduces context switching and CPU usage.
733f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenconst int kNetLogEventDelayMilliseconds = 100;
743f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns the HostCache for |context|'s primary HostResolver, or NULL if
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// there is none.
7772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsennet::HostCache* GetHostResolverCache(net::URLRequestContext* context) {
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  net::HostResolverImpl* host_resolver_impl =
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      context->host_resolver()->GetAsHostResolverImpl();
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!host_resolver_impl)
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return NULL;
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return host_resolver_impl->cache();
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns the disk cache backend for |context| if there is one, or NULL.
8872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsendisk_cache::Backend* GetDiskCacheBackend(net::URLRequestContext* context) {
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!context->http_transaction_factory())
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return NULL;
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  net::HttpCache* http_cache = context->http_transaction_factory()->GetCache();
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!http_cache)
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return NULL;
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return http_cache->GetCurrentBackend();
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Returns the http network session for |context| if there is one.
1003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Otherwise, returns NULL.
10172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsennet::HttpNetworkSession* GetHttpNetworkSession(
10272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    net::URLRequestContext* context) {
1033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!context->http_transaction_factory())
1043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return NULL;
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return context->http_transaction_factory()->GetSession();
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochValue* ExperimentToValue(const ConnectionTester::Experiment& experiment) {
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue* dict = new DictionaryValue();
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (experiment.url.is_valid())
1133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    dict->SetString("url", experiment.url.spec());
1143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  dict->SetString("proxy_settings_experiment",
1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                  ConnectionTester::ProxySettingsExperimentDescription(
1173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                      experiment.proxy_settings_experiment));
1183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  dict->SetString("host_resolver_experiment",
1193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                  ConnectionTester::HostResolverExperimentDescription(
1203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                      experiment.host_resolver_experiment));
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return dict;
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass NetInternalsHTMLSource : public ChromeURLDataManager::DataSource {
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NetInternalsHTMLSource();
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Called when the network layer has requested a resource underneath
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the path we registered.
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void StartDataRequest(const std::string& path,
131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                bool is_incognito,
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                int request_id);
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual std::string GetMimeType(const std::string&) const;
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ~NetInternalsHTMLSource() {}
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(NetInternalsHTMLSource);
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This class receives javascript messages from the renderer.
14172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Note that the WebUI infrastructure runs on the UI thread, therefore all of
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// this class's methods are expected to run on the UI thread.
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Since the network code we want to run lives on the IO thread, we proxy
145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// almost everything over to NetInternalsMessageHandler::IOThreadImpl, which
146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// runs on the IO thread.
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(eroman): Can we start on the IO thread to begin with?
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass NetInternalsMessageHandler
15072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : public WebUIMessageHandler,
15172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      public SelectFileDialog::Listener,
152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      public base::SupportsWeakPtr<NetInternalsMessageHandler>,
153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      public NotificationObserver {
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NetInternalsMessageHandler();
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~NetInternalsMessageHandler();
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
15872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // WebUIMessageHandler implementation.
15972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual WebUIMessageHandler* Attach(WebUI* web_ui);
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void RegisterMessages();
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Executes the javascript function |function_name| in the renderer, passing
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // it the argument |value|.
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void CallJavascriptFunction(const std::wstring& function_name,
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              const Value* value);
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // NotificationObserver implementation.
168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void Observe(NotificationType type,
169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                       const NotificationSource& source,
170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                       const NotificationDetails& details);
171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Javascript message handlers.
173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void OnRendererReady(const ListValue* list);
174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void OnEnableHttpThrottling(const ListValue* list);
175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
17672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // SelectFileDialog::Listener implementation
17772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual void FileSelected(const FilePath& path, int index, void* params);
17872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual void FileSelectionCanceled(void* params);
17972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
18072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // The only callback handled on the UI thread.  As it needs to access fields
18172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // from |web_ui_|, it can't be called on the IO thread.
18272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void OnLoadLogFile(const ListValue* list);
18372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  class IOThreadImpl;
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
18772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Task run on the FILE thread to read the contents of a log file.  The result
18872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // is then passed to IOThreadImpl's CallJavascriptFunction, which sends it
18972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // back to the web page.  IOThreadImpl is used instead of the
19072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // NetInternalsMessageHandler directly because it checks if the message
19172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // handler has been destroyed in the meantime.
19272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  class ReadLogFileTask : public Task {
19372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen   public:
19472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    ReadLogFileTask(IOThreadImpl* proxy, const FilePath& path);
19572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
19672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    virtual void Run();
19772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
19872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen   private:
19972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // IOThreadImpl implements existence checks already.  Simpler to reused them
20072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // then to reimplement them.
20172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    scoped_refptr<IOThreadImpl> proxy_;
20272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
20372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // Path of the file to open.
20472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const FilePath path_;
20572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  };
20672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // The pref member about whether HTTP throttling is enabled, which needs to
208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // be accessed on the UI thread.
209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  BooleanPrefMember http_throttling_enabled_;
210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // OnRendererReady invokes this callback to do the part of message handling
212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // that needs to happen on the IO thread.
213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_ptr<WebUI::MessageCallback> renderer_ready_io_callback_;
214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This is the "real" message handler, which lives on the IO thread.
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<IOThreadImpl> proxy_;
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
21872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Used for loading log files.
21972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  scoped_refptr<SelectFileDialog> select_log_file_dialog_;
22072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(NetInternalsMessageHandler);
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
22421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// This class is the "real" message handler. It is allocated and destroyed on
22572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// the UI thread.  With the exception of OnAddEntry, OnWebUIDeleted, and
22621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// CallJavascriptFunction, its methods are all expected to be called from the IO
22721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// thread.  OnAddEntry and CallJavascriptFunction can be called from any thread,
22872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// and OnWebUIDeleted can only be called from the UI thread.
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass NetInternalsMessageHandler::IOThreadImpl
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : public base::RefCountedThreadSafe<
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          NetInternalsMessageHandler::IOThreadImpl,
232731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          BrowserThread::DeleteOnUIThread>,
23321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      public ChromeNetLog::ThreadSafeObserver,
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      public ConnectionTester::Delegate {
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Type for methods that can be used as MessageHandler callbacks.
2373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  typedef void (IOThreadImpl::*MessageHandler)(const ListValue*);
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Creates a proxy for |handler| that will live on the IO thread.
24072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // |handler| is a weak pointer, since it is possible for the
24172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // WebUIMessageHandler to be deleted on the UI thread while we were executing
24272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // on the IO thread. |io_thread| is the global IOThread (it is passed in as
24372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // an argument since we need to grab it from the UI thread).
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  IOThreadImpl(
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const base::WeakPtr<NetInternalsMessageHandler>& handler,
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      IOThread* io_thread,
247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      net::URLRequestContextGetter* context_getter);
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Creates a callback that will run |method| on the IO thread.
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //
25172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // This can be used with WebUI::RegisterMessageCallback() to bind to a method
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // on the IO thread.
25372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  WebUI::MessageCallback* CreateCallback(MessageHandler method);
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
25572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Called once the WebUI has been deleted (i.e. renderer went away), on the
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // IO thread.
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Detach();
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
25921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Sends all passive log entries in |passive_entries| to the Javascript
26021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // handler, called on the IO thread.
26121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  void SendPassiveLogEntries(const ChromeNetLog::EntryList& passive_entries);
26221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
26372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Called when the WebUI is deleted.  Prevents calling Javascript functions
26421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // afterwards.  Called on UI thread.
26572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void OnWebUIDeleted();
26621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //--------------------------------
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Javascript message handlers:
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //--------------------------------
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void OnRendererReady(const ListValue* list);
2723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void OnGetProxySettings(const ListValue* list);
2743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void OnReloadProxySettings(const ListValue* list);
2753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void OnGetBadProxies(const ListValue* list);
2763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void OnClearBadProxies(const ListValue* list);
277731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void OnGetHostResolverInfo(const ListValue* list);
2783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void OnClearHostResolverCache(const ListValue* list);
279731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void OnEnableIPv6(const ListValue* list);
2803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void OnStartConnectionTests(const ListValue* list);
281dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  void OnHSTSQuery(const ListValue* list);
282dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  void OnHSTSAdd(const ListValue* list);
283dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  void OnHSTSDelete(const ListValue* list);
2843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void OnGetHttpCacheInfo(const ListValue* list);
2853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void OnGetSocketPoolInfo(const ListValue* list);
286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void OnCloseIdleSockets(const ListValue* list);
287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void OnFlushSocketPools(const ListValue* list);
288731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void OnGetSpdySessionInfo(const ListValue* list);
28972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void OnGetSpdyStatus(const ListValue* list);
29072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void OnGetSpdyAlternateProtocolMappings(const ListValue* list);
2913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#ifdef OS_WIN
2923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void OnGetServiceProviders(const ListValue* list);
2933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#endif
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
295731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void OnSetLogLevel(const ListValue* list);
296731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
29721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // ChromeNetLog::ThreadSafeObserver implementation:
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnAddEntry(net::NetLog::EventType type,
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          const base::TimeTicks& time,
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          const net::NetLog::Source& source,
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          net::NetLog::EventPhase phase,
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          net::NetLog::EventParameters* params);
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ConnectionTester::Delegate implementation:
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnStartConnectionTestSuite();
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnStartConnectionTestExperiment(
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const ConnectionTester::Experiment& experiment);
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnCompletedConnectionTestExperiment(
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const ConnectionTester::Experiment& experiment,
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      int result);
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnCompletedConnectionTestSuite();
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
31372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Helper that executes |function_name| in the attached renderer.
31472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // The function takes ownership of |arg|.  Note that this can be called from
31572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // any thread.
31672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void CallJavascriptFunction(const std::wstring& function_name, Value* arg);
31772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
319dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>;
320dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  friend class DeleteTask<IOThreadImpl>;
321dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
322dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ~IOThreadImpl();
323dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  class CallbackHelper;
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Helper that runs |method| with |arg|, and deletes |arg| on completion.
3273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void DispatchToMessageHandler(ListValue* arg, MessageHandler method);
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3293f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Adds |entry| to the queue of pending log entries to be sent to the page via
3303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Javascript.  Must be called on the IO Thread.  Also creates a delayed task
3313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // that will call PostPendingEntries, if there isn't one already.
3323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  void AddEntryToQueue(Value* entry);
3333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Sends all pending entries to the page via Javascript, and clears the list
3353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // of pending entries.  Sending multiple entries at once results in a
3363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // significant reduction of CPU usage when a lot of events are happening.
3373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Must be called on the IO Thread.
3383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  void PostPendingEntries();
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Pointer to the UI-thread message handler. Only access this from
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the UI thread.
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::WeakPtr<NetInternalsMessageHandler> handler_;
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The global IOThread, which contains the global NetLog to observer.
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  IOThread* io_thread_;
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
347ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<net::URLRequestContextGetter> context_getter_;
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Helper that runs the suite of connection tests.
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<ConnectionTester> connection_tester_;
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
35272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // True if the Web UI has been deleted.  This is used to prevent calling
35372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Javascript functions after the Web UI is destroyed.  On refresh, the
35421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // messages can end up being sent to the refreshed page, causing duplicate
35521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // or partial entries.
35621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  //
35721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // This is only read and written to on the UI thread.
35872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  bool was_webui_deleted_;
35921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // True if we have attached an observer to the NetLog already.
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool is_observing_log_;
3623f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3633f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Log entries that have yet to be passed along to Javascript page.  Non-NULL
3643f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // when and only when there is a pending delayed task to call
3653f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // PostPendingEntries.  Read and written to exclusively on the IO Thread.
3663f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  scoped_ptr<ListValue> pending_entries_;
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
369ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Helper class for a WebUI::MessageCallback which when executed calls
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// instance->*method(value) on the IO thread.
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass NetInternalsMessageHandler::IOThreadImpl::CallbackHelper
37272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : public WebUI::MessageCallback {
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CallbackHelper(IOThreadImpl* instance, IOThreadImpl::MessageHandler method)
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : instance_(instance),
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        method_(method) {
377731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual void RunWithParams(const Tuple1<const ListValue*>& params) {
381731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We need to make a copy of the value in order to pass it over to the IO
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // thread. We will delete this in IOThreadImpl::DispatchMessageHandler().
3853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ListValue* list_copy = static_cast<ListValue*>(
3863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        params.a ? params.a->DeepCopy() : NULL);
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
388731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (!BrowserThread::PostTask(
389731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick            BrowserThread::IO, FROM_HERE,
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            NewRunnableMethod(instance_.get(),
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              &IOThreadImpl::DispatchToMessageHandler,
3923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                              list_copy, method_))) {
3933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      // Failed posting the task, avoid leaking |list_copy|.
3943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      delete list_copy;
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<IOThreadImpl> instance_;
400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  IOThreadImpl::MessageHandler method_;
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// NetInternalsHTMLSource
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNetInternalsHTMLSource::NetInternalsHTMLSource()
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : DataSource(chrome::kChromeUINetInternalsHost, MessageLoop::current()) {
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NetInternalsHTMLSource::StartDataRequest(const std::string& path,
414ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                              bool is_incognito,
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                              int request_id) {
41621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DictionaryValue localized_strings;
41721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  SetFontAndTextDirection(&localized_strings);
41821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The provided "path" may contain a fragment, or query section. We only
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // care about the path itself, and will disregard anything else.
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string filename =
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL(std::string("chrome://net/") + path).path().substr(1);
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The source for the net internals page is flattened during compilation, so
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the only resource that should legitimately be requested is the main file.
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Note that users can type anything into the address bar, though, so we must
427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // handle arbitrary input.
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (filename.empty() || filename == "index.html") {
42921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    base::StringPiece html(
43021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        ResourceBundle::GetSharedInstance().GetRawDataResource(
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            IDR_NET_INTERNALS_INDEX_HTML));
43221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    std::string full_html(html.data(), html.size());
43321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    jstemplate_builder::AppendJsonHtml(&localized_strings, &full_html);
43421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    jstemplate_builder::AppendI18nTemplateSourceHtml(&full_html);
43521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    jstemplate_builder::AppendI18nTemplateProcessHtml(&full_html);
43621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    jstemplate_builder::AppendJsTemplateSourceHtml(&full_html);
43721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
43821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
43921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    html_bytes->data.resize(full_html.size());
44021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin());
44121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    SendResponse(request_id, html_bytes);
44221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return;
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const std::string data_string("<p style='color:red'>Failed to read resource" +
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EscapeForHTML(filename) + "</p>");
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<RefCountedBytes> bytes(new RefCountedBytes);
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bytes->data.resize(data_string.size());
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::copy(data_string.begin(), data_string.end(), bytes->data.begin());
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SendResponse(request_id, bytes);
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string NetInternalsHTMLSource::GetMimeType(const std::string&) const {
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return "text/html";
455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// NetInternalsMessageHandler
460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNetInternalsMessageHandler::NetInternalsMessageHandler() {}
464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNetInternalsMessageHandler::~NetInternalsMessageHandler() {
466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (proxy_) {
46772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    proxy_.get()->OnWebUIDeleted();
468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Notify the handler on the IO thread that the renderer is gone.
469731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NewRunnableMethod(proxy_.get(), &IOThreadImpl::Detach));
471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
47272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (select_log_file_dialog_)
47372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    select_log_file_dialog_->ListenerDestroyed();
474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
47672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenWebUIMessageHandler* NetInternalsMessageHandler::Attach(WebUI* web_ui) {
477731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
478ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
479ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PrefService* pref_service = web_ui->GetProfile()->GetPrefs();
480ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  http_throttling_enabled_.Init(prefs::kHttpThrottlingEnabled, pref_service,
481ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                this);
482ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  proxy_ = new IOThreadImpl(this->AsWeakPtr(), g_browser_process->io_thread(),
48472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                            web_ui->GetProfile()->GetRequestContext());
485ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  renderer_ready_io_callback_.reset(
486ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      proxy_->CreateCallback(&IOThreadImpl::OnRendererReady));
487ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
48872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  WebUIMessageHandler* result = WebUIMessageHandler::Attach(web_ui);
489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return result;
490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
49272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid NetInternalsMessageHandler::FileSelected(
49372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const FilePath& path, int index, void* params) {
49472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  select_log_file_dialog_.release();
49572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  BrowserThread::PostTask(
49672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      BrowserThread::FILE, FROM_HERE,
49772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      new ReadLogFileTask(proxy_.get(), path));
49872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
49972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
50072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid NetInternalsMessageHandler::FileSelectionCanceled(void* params) {
50172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  select_log_file_dialog_.release();
50272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
50372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
50472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid NetInternalsMessageHandler::OnLoadLogFile(const ListValue* list) {
50572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Only allow a single dialog at a time.
50672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (select_log_file_dialog_.get())
50772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
50872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  select_log_file_dialog_ = SelectFileDialog::Create(this);
50972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  select_log_file_dialog_->SelectFile(
51072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      SelectFileDialog::SELECT_OPEN_FILE, string16(), FilePath(), NULL, 0,
511ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      FILE_PATH_LITERAL(""), web_ui_->tab_contents(),
51272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      web_ui_->tab_contents()->view()->GetTopLevelNativeWindow(), NULL);
51372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
51472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NetInternalsMessageHandler::RegisterMessages() {
516731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
51772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Only callback handled on UI thread.
51872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  web_ui_->RegisterMessageCallback(
51972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      "loadLogFile",
52072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      NewCallback(this, &NetInternalsMessageHandler::OnLoadLogFile));
521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
52272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  web_ui_->RegisterMessageCallback(
523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "notifyReady",
524ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      NewCallback(this, &NetInternalsMessageHandler::OnRendererReady));
52572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  web_ui_->RegisterMessageCallback(
526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "getProxySettings",
527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      proxy_->CreateCallback(&IOThreadImpl::OnGetProxySettings));
52872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  web_ui_->RegisterMessageCallback(
529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "reloadProxySettings",
530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      proxy_->CreateCallback(&IOThreadImpl::OnReloadProxySettings));
53172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  web_ui_->RegisterMessageCallback(
532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "getBadProxies",
533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      proxy_->CreateCallback(&IOThreadImpl::OnGetBadProxies));
53472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  web_ui_->RegisterMessageCallback(
535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "clearBadProxies",
536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      proxy_->CreateCallback(&IOThreadImpl::OnClearBadProxies));
53772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  web_ui_->RegisterMessageCallback(
538731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      "getHostResolverInfo",
539731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      proxy_->CreateCallback(&IOThreadImpl::OnGetHostResolverInfo));
54072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  web_ui_->RegisterMessageCallback(
541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "clearHostResolverCache",
542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      proxy_->CreateCallback(&IOThreadImpl::OnClearHostResolverCache));
54372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  web_ui_->RegisterMessageCallback(
544731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      "enableIPv6",
545731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      proxy_->CreateCallback(&IOThreadImpl::OnEnableIPv6));
54672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  web_ui_->RegisterMessageCallback(
547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "startConnectionTests",
548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      proxy_->CreateCallback(&IOThreadImpl::OnStartConnectionTests));
54972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  web_ui_->RegisterMessageCallback(
550dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      "hstsQuery",
551dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      proxy_->CreateCallback(&IOThreadImpl::OnHSTSQuery));
552dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  web_ui_->RegisterMessageCallback(
553dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      "hstsAdd",
554dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      proxy_->CreateCallback(&IOThreadImpl::OnHSTSAdd));
555dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  web_ui_->RegisterMessageCallback(
556dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      "hstsDelete",
557dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      proxy_->CreateCallback(&IOThreadImpl::OnHSTSDelete));
558dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  web_ui_->RegisterMessageCallback(
559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "getHttpCacheInfo",
560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      proxy_->CreateCallback(&IOThreadImpl::OnGetHttpCacheInfo));
56172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  web_ui_->RegisterMessageCallback(
5623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "getSocketPoolInfo",
5633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      proxy_->CreateCallback(&IOThreadImpl::OnGetSocketPoolInfo));
56472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  web_ui_->RegisterMessageCallback(
565ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      "closeIdleSockets",
566ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      proxy_->CreateCallback(&IOThreadImpl::OnCloseIdleSockets));
567ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  web_ui_->RegisterMessageCallback(
568ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      "flushSocketPools",
569ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      proxy_->CreateCallback(&IOThreadImpl::OnFlushSocketPools));
570ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  web_ui_->RegisterMessageCallback(
571731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      "getSpdySessionInfo",
572731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      proxy_->CreateCallback(&IOThreadImpl::OnGetSpdySessionInfo));
57372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  web_ui_->RegisterMessageCallback(
57472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      "getSpdyStatus",
57572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      proxy_->CreateCallback(&IOThreadImpl::OnGetSpdyStatus));
57672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  web_ui_->RegisterMessageCallback(
57772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      "getSpdyAlternateProtocolMappings",
57872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      proxy_->CreateCallback(
57972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          &IOThreadImpl::OnGetSpdyAlternateProtocolMappings));
5803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#ifdef OS_WIN
58172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  web_ui_->RegisterMessageCallback(
5823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "getServiceProviders",
5833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      proxy_->CreateCallback(&IOThreadImpl::OnGetServiceProviders));
5843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#endif
585731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
58672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  web_ui_->RegisterMessageCallback(
587731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      "setLogLevel",
588731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      proxy_->CreateCallback(&IOThreadImpl::OnSetLogLevel));
589ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
590ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  web_ui_->RegisterMessageCallback(
591ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      "enableHttpThrottling",
592ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      NewCallback(this, &NetInternalsMessageHandler::OnEnableHttpThrottling));
593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NetInternalsMessageHandler::CallJavascriptFunction(
596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::wstring& function_name,
597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const Value* value) {
598731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (value) {
600ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    web_ui_->CallJavascriptFunction(WideToASCII(function_name), *value);
601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
602ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    web_ui_->CallJavascriptFunction(WideToASCII(function_name));
603ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
604ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
605ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
606ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid NetInternalsMessageHandler::Observe(NotificationType type,
607ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                         const NotificationSource& source,
608ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                         const NotificationDetails& details) {
609ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
610ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK_EQ(type.value, NotificationType::PREF_CHANGED);
611ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
612ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::string* pref_name = Details<std::string>(details).ptr();
613ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (*pref_name == prefs::kHttpThrottlingEnabled) {
614ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    scoped_ptr<Value> enabled(
615ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        Value::CreateBooleanValue(*http_throttling_enabled_));
616ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
617ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    CallJavascriptFunction(
618ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        L"g_browser.receivedHttpThrottlingEnabledPrefChanged", enabled.get());
619ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
620ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
621ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
622ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid NetInternalsMessageHandler::OnRendererReady(const ListValue* list) {
623ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  CHECK(renderer_ready_io_callback_.get());
624ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  renderer_ready_io_callback_->Run(list);
625ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
626ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_ptr<Value> enabled(
627ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      Value::CreateBooleanValue(*http_throttling_enabled_));
628ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  CallJavascriptFunction(
629ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      L"g_browser.receivedHttpThrottlingEnabledPrefChanged", enabled.get());
630ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
631ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
632ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid NetInternalsMessageHandler::OnEnableHttpThrottling(const ListValue* list) {
633ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
634ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
635ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool enable = false;
636ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!list->GetBoolean(0, &enable)) {
637ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    NOTREACHED();
638ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
640ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
641ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  http_throttling_enabled_.SetValue(enable);
642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
64672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// NetInternalsMessageHandler::ReadLogFileTask
64772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//
64872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen////////////////////////////////////////////////////////////////////////////////
64972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
65072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenNetInternalsMessageHandler::ReadLogFileTask::ReadLogFileTask(
65172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    IOThreadImpl* proxy, const FilePath& path)
65272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : proxy_(proxy), path_(path) {
65372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
65472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
65572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid NetInternalsMessageHandler::ReadLogFileTask::Run() {
65672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  std::string file_contents;
65772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!file_util::ReadFileToString(path_, &file_contents))
65872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
65972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  proxy_->CallJavascriptFunction(L"g_browser.loadedLogFile",
66072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                 new StringValue(file_contents));
66172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
66272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
66372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen////////////////////////////////////////////////////////////////////////////////
66472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//
665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// NetInternalsMessageHandler::IOThreadImpl
666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
669c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNetInternalsMessageHandler::IOThreadImpl::IOThreadImpl(
670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const base::WeakPtr<NetInternalsMessageHandler>& handler,
671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IOThread* io_thread,
672ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    net::URLRequestContextGetter* context_getter)
67321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    : ThreadSafeObserver(net::NetLog::LOG_ALL_BUT_BYTES),
6743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      handler_(handler),
675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      io_thread_(io_thread),
676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      context_getter_(context_getter),
67772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      was_webui_deleted_(false),
678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      is_observing_log_(false) {
679731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
682c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNetInternalsMessageHandler::IOThreadImpl::~IOThreadImpl() {
683731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
68672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenWebUI::MessageCallback*
687c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNetInternalsMessageHandler::IOThreadImpl::CreateCallback(
688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageHandler method) {
689731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return new CallbackHelper(this, method);
691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NetInternalsMessageHandler::IOThreadImpl::Detach() {
694731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Unregister with network stack to observe events.
696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (is_observing_log_)
69721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    io_thread_->net_log()->RemoveObserver(this);
698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Cancel any in-progress connection tests.
700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connection_tester_.reset();
701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
70321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid NetInternalsMessageHandler::IOThreadImpl::SendPassiveLogEntries(
70421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    const ChromeNetLog::EntryList& passive_entries) {
70521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
70621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ListValue* dict_list = new ListValue();
70721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  for (size_t i = 0; i < passive_entries.size(); ++i) {
70821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    const ChromeNetLog::Entry& e = passive_entries[i];
70921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    dict_list->Append(net::NetLog::EntryToDictionaryValue(e.type,
71021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                                          e.time,
71121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                                          e.source,
71221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                                          e.phase,
71321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                                          e.params,
71421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                                          false));
71521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
71621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
71721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  CallJavascriptFunction(L"g_browser.receivedPassiveLogEntries", dict_list);
71821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
71921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
72072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid NetInternalsMessageHandler::IOThreadImpl::OnWebUIDeleted() {
72121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
72272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  was_webui_deleted_ = true;
72321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
72421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NetInternalsMessageHandler::IOThreadImpl::OnRendererReady(
7263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const ListValue* list) {
727731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(!is_observing_log_) << "notifyReady called twice";
729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Tell the javascript about the relationship between event type enums and
731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // their symbolic name.
732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::vector<net::NetLog::EventType> event_types =
734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        net::NetLog::GetAllEventTypes();
735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* dict = new DictionaryValue();
737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t i = 0; i < event_types.size(); ++i) {
739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const char* name = net::NetLog::EventTypeToString(event_types[i]);
7403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      dict->SetInteger(name, static_cast<int>(event_types[i]));
741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CallJavascriptFunction(L"g_browser.receivedLogEventTypeConstants", dict);
744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Tell the javascript about the version of the client and its
747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // command line arguments.
748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* dict = new DictionaryValue();
750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    chrome::VersionInfo version_info;
752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (!version_info.is_valid()) {
7543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      DLOG(ERROR) << "Unable to create chrome::VersionInfo";
755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // We have everything we need to send the right values.
7573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      dict->SetString("version", version_info.Version());
7583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      dict->SetString("cl", version_info.LastChange());
7593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      dict->SetString("version_mod",
7603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                      platform_util::GetVersionStringModifier());
7613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      dict->SetString("official",
7623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          l10n_util::GetStringUTF16(
7633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick              version_info.IsOfficialBuild() ?
7643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                IDS_ABOUT_VERSION_OFFICIAL
7653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick              : IDS_ABOUT_VERSION_UNOFFICIAL));
7663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
7673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      dict->SetString("command_line",
768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          CommandLine::ForCurrentProcess()->command_line_string());
769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CallJavascriptFunction(L"g_browser.receivedClientInfo",
772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           dict);
773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Tell the javascript about the relationship between load flag enums and
776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // their symbolic name.
777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* dict = new DictionaryValue();
779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define LOAD_FLAG(label, value) \
7813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    dict->SetInteger(# label, static_cast<int>(value));
782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/load_flags_list.h"
783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#undef LOAD_FLAG
784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CallJavascriptFunction(L"g_browser.receivedLoadFlagConstants", dict);
786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Tell the javascript about the relationship between net error codes and
789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // their symbolic name.
790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* dict = new DictionaryValue();
792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define NET_ERROR(label, value) \
7943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    dict->SetInteger(# label, static_cast<int>(value));
795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_error_list.h"
796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#undef NET_ERROR
797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CallJavascriptFunction(L"g_browser.receivedNetErrorConstants", dict);
799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Tell the javascript about the relationship between event phase enums and
802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // their symbolic name.
803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* dict = new DictionaryValue();
805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
8063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    dict->SetInteger("PHASE_BEGIN", net::NetLog::PHASE_BEGIN);
8073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    dict->SetInteger("PHASE_END", net::NetLog::PHASE_END);
8083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    dict->SetInteger("PHASE_NONE", net::NetLog::PHASE_NONE);
809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CallJavascriptFunction(L"g_browser.receivedLogEventPhaseConstants", dict);
811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Tell the javascript about the relationship between source type enums and
814731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // their symbolic names.
815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* dict = new DictionaryValue();
817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
8183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#define SOURCE_TYPE(label, value) dict->SetInteger(# label, value);
819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_log_source_type_list.h"
820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#undef SOURCE_TYPE
821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CallJavascriptFunction(L"g_browser.receivedLogSourceTypeConstants", dict);
823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
825731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Tell the javascript about the relationship between LogLevel enums and their
826731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // symbolic names.
827731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  {
828731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    DictionaryValue* dict = new DictionaryValue();
829731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
830731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    dict->SetInteger("LOG_ALL", net::NetLog::LOG_ALL);
831731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    dict->SetInteger("LOG_ALL_BUT_BYTES", net::NetLog::LOG_ALL_BUT_BYTES);
832731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    dict->SetInteger("LOG_BASIC", net::NetLog::LOG_BASIC);
833731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
834731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CallJavascriptFunction(L"g_browser.receivedLogLevelConstants", dict);
835731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
836731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
837731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Tell the javascript about the relationship between address family enums and
838731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // their symbolic names.
839731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  {
840731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    DictionaryValue* dict = new DictionaryValue();
841731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
842731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    dict->SetInteger("ADDRESS_FAMILY_UNSPECIFIED",
843731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                     net::ADDRESS_FAMILY_UNSPECIFIED);
844731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    dict->SetInteger("ADDRESS_FAMILY_IPV4",
845731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                     net::ADDRESS_FAMILY_IPV4);
846731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    dict->SetInteger("ADDRESS_FAMILY_IPV6",
847731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                     net::ADDRESS_FAMILY_IPV6);
848731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
849731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CallJavascriptFunction(L"g_browser.receivedAddressFamilyConstants", dict);
850731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
851731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Tell the javascript how the "time ticks" values we have given it relate to
853c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // actual system times. (We used time ticks throughout since they are stable
854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // across system clock changes).
855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int64 cur_time_ms = (base::Time::Now() - base::Time()).InMilliseconds();
857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int64 cur_time_ticks_ms =
859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        (base::TimeTicks::Now() - base::TimeTicks()).InMilliseconds();
860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // If we add this number to a time tick value, it gives the timestamp.
862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int64 tick_to_time_ms = cur_time_ms - cur_time_ticks_ms;
863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Chrome on all platforms stores times using the Windows epoch
865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // (Jan 1 1601), but the javascript wants a unix epoch.
866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // TODO(eroman): Getting the timestamp relative the to unix epoch should
867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    //               be part of the time library.
868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const int64 kUnixEpochMs = 11644473600000LL;
869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int64 tick_to_unix_time_ms = tick_to_time_ms - kUnixEpochMs;
870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Pass it as a string, since it may be too large to fit in an integer.
872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CallJavascriptFunction(L"g_browser.receivedTimeTickOffset",
873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           Value::CreateStringValue(
8743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               base::Int64ToString(tick_to_unix_time_ms)));
875c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
87721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Register with network stack to observe events.
87821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  is_observing_log_ = true;
87921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ChromeNetLog::EntryList entries;
88021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  io_thread_->net_log()->AddObserverAndGetAllPassivelyCapturedEvents(this,
88121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                                                     &entries);
88221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  SendPassiveLogEntries(entries);
883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NetInternalsMessageHandler::IOThreadImpl::OnGetProxySettings(
8863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const ListValue* list) {
88772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  net::URLRequestContext* context = context_getter_->GetURLRequestContext();
888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  net::ProxyService* proxy_service = context->proxy_service();
889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
8903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DictionaryValue* dict = new DictionaryValue();
8913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (proxy_service->fetched_config().is_valid())
8923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    dict->Set("original", proxy_service->fetched_config().ToValue());
8933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (proxy_service->config().is_valid())
8943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    dict->Set("effective", proxy_service->config().ToValue());
895c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
8963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CallJavascriptFunction(L"g_browser.receivedProxySettings", dict);
897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NetInternalsMessageHandler::IOThreadImpl::OnReloadProxySettings(
9003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const ListValue* list) {
90172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  net::URLRequestContext* context = context_getter_->GetURLRequestContext();
902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  context->proxy_service()->ForceReloadProxyConfig();
903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Cause the renderer to be notified of the new values.
905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  OnGetProxySettings(NULL);
906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
907c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
908c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NetInternalsMessageHandler::IOThreadImpl::OnGetBadProxies(
9093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const ListValue* list) {
91072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  net::URLRequestContext* context = context_getter_->GetURLRequestContext();
911c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
912c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const net::ProxyRetryInfoMap& bad_proxies_map =
913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      context->proxy_service()->proxy_retry_info();
914c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ListValue* dict_list = new ListValue();
916c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (net::ProxyRetryInfoMap::const_iterator it = bad_proxies_map.begin();
918c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       it != bad_proxies_map.end(); ++it) {
919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& proxy_uri = it->first;
920c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const net::ProxyRetryInfo& retry_info = it->second;
921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* dict = new DictionaryValue();
9233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    dict->SetString("proxy_uri", proxy_uri);
924731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    dict->SetString("bad_until",
925731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                    net::NetLog::TickCountToString(retry_info.bad_until));
926c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    dict_list->Append(dict);
928c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
929c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CallJavascriptFunction(L"g_browser.receivedBadProxies", dict_list);
931c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
932c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NetInternalsMessageHandler::IOThreadImpl::OnClearBadProxies(
9343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const ListValue* list) {
93572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  net::URLRequestContext* context = context_getter_->GetURLRequestContext();
936c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  context->proxy_service()->ClearBadProxiesCache();
937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Cause the renderer to be notified of the new values.
939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  OnGetBadProxies(NULL);
940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
942731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid NetInternalsMessageHandler::IOThreadImpl::OnGetHostResolverInfo(
9433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const ListValue* list) {
94472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  net::URLRequestContext* context = context_getter_->GetURLRequestContext();
945731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  net::HostResolverImpl* host_resolver_impl =
946731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      context->host_resolver()->GetAsHostResolverImpl();
947731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  net::HostCache* cache = GetHostResolverCache(context);
948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
949731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (!host_resolver_impl || !cache) {
950731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CallJavascriptFunction(L"g_browser.receivedHostResolverInfo", NULL);
951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
952c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue* dict = new DictionaryValue();
955c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
956c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dict->SetInteger(
957731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      "default_address_family",
958731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      static_cast<int>(host_resolver_impl->GetDefaultAddressFamily()));
959731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
960731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DictionaryValue* cache_info_dict = new DictionaryValue();
961731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
962731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  cache_info_dict->SetInteger(
963731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      "capacity",
964731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      static_cast<int>(cache->max_entries()));
965731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  cache_info_dict->SetInteger(
9663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "ttl_success_ms",
967c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      static_cast<int>(cache->success_entry_ttl().InMilliseconds()));
968731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  cache_info_dict->SetInteger(
9693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "ttl_failure_ms",
970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      static_cast<int>(cache->failure_entry_ttl().InMilliseconds()));
971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue* entry_list = new ListValue();
973c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (net::HostCache::EntryMap::const_iterator it =
975c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       cache->entries().begin();
976c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       it != cache->entries().end();
977c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       ++it) {
978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const net::HostCache::Key& key = it->first;
979c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const net::HostCache::Entry* entry = it->second.get();
980c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
981c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* entry_dict = new DictionaryValue();
982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    entry_dict->SetString("hostname", key.hostname);
9843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    entry_dict->SetInteger("address_family",
985c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        static_cast<int>(key.address_family));
986731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    entry_dict->SetString("expiration",
987731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                          net::NetLog::TickCountToString(entry->expiration));
988c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
989c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (entry->error != net::OK) {
9903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      entry_dict->SetInteger("error", entry->error);
991c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
992c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Append all of the resolved addresses.
993c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ListValue* address_list = new ListValue();
994c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const struct addrinfo* current_address = entry->addrlist.head();
995c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      while (current_address) {
996c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        address_list->Append(Value::CreateStringValue(
997c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            net::NetAddressToStringWithPort(current_address)));
998c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        current_address = current_address->ai_next;
999c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
10003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      entry_dict->Set("addresses", address_list);
1001c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1002c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1003c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    entry_list->Append(entry_dict);
1004c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1005c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1006731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  cache_info_dict->Set("entries", entry_list);
1007731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  dict->Set("cache", cache_info_dict);
1008c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1009731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  CallJavascriptFunction(L"g_browser.receivedHostResolverInfo", dict);
1010c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1011c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1012c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NetInternalsMessageHandler::IOThreadImpl::OnClearHostResolverCache(
10133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const ListValue* list) {
1014c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  net::HostCache* cache =
1015c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GetHostResolverCache(context_getter_->GetURLRequestContext());
1016c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1017c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (cache)
1018c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cache->clear();
1019c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1020c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Cause the renderer to be notified of the new values.
1021731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  OnGetHostResolverInfo(NULL);
1022731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
1023731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1024731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid NetInternalsMessageHandler::IOThreadImpl::OnEnableIPv6(
1025731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const ListValue* list) {
102672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  net::URLRequestContext* context = context_getter_->GetURLRequestContext();
1027731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  net::HostResolverImpl* host_resolver_impl =
1028731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      context->host_resolver()->GetAsHostResolverImpl();
1029731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1030731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (host_resolver_impl) {
1031731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    host_resolver_impl->SetDefaultAddressFamily(
1032731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        net::ADDRESS_FAMILY_UNSPECIFIED);
1033731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
1034731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1035731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Cause the renderer to be notified of the new value.
1036731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  OnGetHostResolverInfo(NULL);
1037c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1038c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1039c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NetInternalsMessageHandler::IOThreadImpl::OnStartConnectionTests(
10403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const ListValue* list) {
1041c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // |value| should be: [<URL to test>].
1042c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string16 url_str;
10433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(list->GetString(0, &url_str));
1044c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1045c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Try to fix-up the user provided URL into something valid.
1046c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // For example, turn "www.google.com" into "http://www.google.com".
1047c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url(URLFixerUpper::FixupURL(UTF16ToUTF8(url_str), std::string()));
1048c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
104921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  connection_tester_.reset(new ConnectionTester(
105021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      this, io_thread_->globals()->proxy_script_fetcher_context.get()));
1051c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connection_tester_->RunAllTests(url);
1052c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1053c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1054dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid NetInternalsMessageHandler::IOThreadImpl::OnHSTSQuery(
1055dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const ListValue* list) {
1056dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // |list| should be: [<domain to query>].
1057dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  std::string domain;
1058dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  CHECK(list->GetString(0, &domain));
1059dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DictionaryValue* result = new(DictionaryValue);
1060dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1061dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (!IsStringASCII(domain)) {
1062dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    result->SetString("error", "non-ASCII domain name");
1063dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  } else {
1064dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    net::TransportSecurityState* transport_security_state =
1065dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        context_getter_->GetURLRequestContext()->transport_security_state();
1066dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    if (!transport_security_state) {
1067dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      result->SetString("error", "no TransportSecurityState active");
1068dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    } else {
1069dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      net::TransportSecurityState::DomainState state;
1070dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      const bool found = transport_security_state->IsEnabledForHost(
1071ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          &state, domain, true);
1072dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1073dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      result->SetBoolean("result", found);
1074dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      if (found) {
1075dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        result->SetInteger("mode", static_cast<int>(state.mode));
1076dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        result->SetBoolean("subdomains", state.include_subdomains);
1077dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        result->SetBoolean("preloaded", state.preloaded);
1078dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        result->SetString("domain", state.domain);
1079ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1080ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        std::vector<std::string> parts;
1081ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        for (std::vector<net::SHA1Fingerprint>::const_iterator
1082ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen             i = state.public_key_hashes.begin();
1083ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen             i != state.public_key_hashes.end(); i++) {
1084ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          std::string part = "sha1/";
1085ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          std::string hash_str(reinterpret_cast<const char*>(i->data),
1086ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                               sizeof(i->data));
1087ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          std::string b64;
1088ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          base::Base64Encode(hash_str, &b64);
1089ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          part += b64;
1090ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          parts.push_back(part);
1091ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        }
1092ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        result->SetString("public_key_hashes", JoinString(parts, ','));
1093dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      }
1094dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    }
1095dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
1096dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1097dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  CallJavascriptFunction(L"g_browser.receivedHSTSResult", result);
1098dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
1099dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1100dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid NetInternalsMessageHandler::IOThreadImpl::OnHSTSAdd(
1101dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const ListValue* list) {
1102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // |list| should be: [<domain to query>, <include subdomains>, <cert pins>].
1103dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  std::string domain;
1104dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  CHECK(list->GetString(0, &domain));
1105dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (!IsStringASCII(domain)) {
1106dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // Silently fail. The user will get a helpful error if they query for the
1107dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // name.
1108dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return;
1109dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
1110dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  bool include_subdomains;
1111dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  CHECK(list->GetBoolean(1, &include_subdomains));
1112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::string hashes_str;
1113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  CHECK(list->GetString(2, &hashes_str));
1114dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1115dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  net::TransportSecurityState* transport_security_state =
1116dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      context_getter_->GetURLRequestContext()->transport_security_state();
1117dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (!transport_security_state)
1118dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return;
1119dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1120dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  net::TransportSecurityState::DomainState state;
1121dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  state.expiry = state.created + base::TimeDelta::FromDays(1000);
1122dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  state.include_subdomains = include_subdomains;
1123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  state.public_key_hashes.clear();
1124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!hashes_str.empty()) {
1125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    std::vector<std::string> type_and_b64s;
1126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::SplitString(hashes_str, ',', &type_and_b64s);
1127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (std::vector<std::string>::const_iterator
1128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         i = type_and_b64s.begin(); i != type_and_b64s.end(); i++) {
1129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      std::string type_and_b64;
1130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      RemoveChars(*i, " \t\r\n", &type_and_b64);
1131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (type_and_b64.find("sha1/") != 0)
1132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        continue;
1133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      std::string b64 = type_and_b64.substr(5, type_and_b64.size() - 5);
1134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      std::string hash_str;
1135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (!base::Base64Decode(b64, &hash_str))
1136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        continue;
1137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      net::SHA1Fingerprint hash;
1138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (hash_str.size() != sizeof(hash.data))
1139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        continue;
1140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      memcpy(hash.data, hash_str.data(), sizeof(hash.data));
1141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      state.public_key_hashes.push_back(hash);
1142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
1144dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1145dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  transport_security_state->EnableHost(domain, state);
1146dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
1147dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1148dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid NetInternalsMessageHandler::IOThreadImpl::OnHSTSDelete(
1149dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const ListValue* list) {
1150dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // |list| should be: [<domain to query>].
1151dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  std::string domain;
1152dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  CHECK(list->GetString(0, &domain));
1153dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (!IsStringASCII(domain)) {
1154dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // There cannot be a unicode entry in the HSTS set.
1155dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return;
1156dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
1157dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  net::TransportSecurityState* transport_security_state =
1158dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      context_getter_->GetURLRequestContext()->transport_security_state();
1159dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (!transport_security_state)
1160dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return;
1161dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1162dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  transport_security_state->DeleteHost(domain);
1163dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
1164dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NetInternalsMessageHandler::IOThreadImpl::OnGetHttpCacheInfo(
11663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const ListValue* list) {
1167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue* info_dict = new DictionaryValue();
1168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue* stats_dict = new DictionaryValue();
1169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  disk_cache::Backend* disk_cache = GetDiskCacheBackend(
1171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      context_getter_->GetURLRequestContext());
1172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (disk_cache) {
1174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Extract the statistics key/value pairs from the backend.
1175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::vector<std::pair<std::string, std::string> > stats;
1176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    disk_cache->GetStats(&stats);
1177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t i = 0; i < stats.size(); ++i) {
11783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      stats_dict->Set(stats[i].first,
1179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      Value::CreateStringValue(stats[i].second));
1180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
11833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  info_dict->Set("stats", stats_dict);
1184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CallJavascriptFunction(L"g_browser.receivedHttpCacheInfo", info_dict);
1186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
11883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid NetInternalsMessageHandler::IOThreadImpl::OnGetSocketPoolInfo(
11893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const ListValue* list) {
11903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  net::HttpNetworkSession* http_network_session =
11913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      GetHttpNetworkSession(context_getter_->GetURLRequestContext());
11923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
11933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Value* socket_pool_info = NULL;
11943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (http_network_session)
11953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    socket_pool_info = http_network_session->SocketPoolInfoToValue();
11963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
11973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CallJavascriptFunction(L"g_browser.receivedSocketPoolInfo", socket_pool_info);
11983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
11993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid NetInternalsMessageHandler::IOThreadImpl::OnFlushSocketPools(
1202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const ListValue* list) {
1203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  net::HttpNetworkSession* http_network_session =
1204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      GetHttpNetworkSession(context_getter_->GetURLRequestContext());
1205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (http_network_session)
1207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    http_network_session->CloseAllConnections();
1208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid NetInternalsMessageHandler::IOThreadImpl::OnCloseIdleSockets(
1211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const ListValue* list) {
1212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  net::HttpNetworkSession* http_network_session =
1213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      GetHttpNetworkSession(context_getter_->GetURLRequestContext());
1214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (http_network_session)
1216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    http_network_session->CloseIdleConnections();
1217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1219731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid NetInternalsMessageHandler::IOThreadImpl::OnGetSpdySessionInfo(
1220731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const ListValue* list) {
1221731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  net::HttpNetworkSession* http_network_session =
1222731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      GetHttpNetworkSession(context_getter_->GetURLRequestContext());
1223731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1224731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Value* spdy_info = NULL;
1225731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (http_network_session) {
1226731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    spdy_info = http_network_session->SpdySessionPoolInfoToValue();
1227731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
1228731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1229731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  CallJavascriptFunction(L"g_browser.receivedSpdySessionInfo", spdy_info);
1230731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
1231731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
123272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid NetInternalsMessageHandler::IOThreadImpl::OnGetSpdyStatus(
123372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const ListValue* list) {
123472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DictionaryValue* status_dict = new DictionaryValue();
123572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
123672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  status_dict->Set("spdy_enabled",
123772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                   Value::CreateBooleanValue(
123872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                       net::HttpStreamFactory::spdy_enabled()));
123972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  status_dict->Set("use_alternate_protocols",
124072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                   Value::CreateBooleanValue(
124172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                       net::HttpStreamFactory::use_alternate_protocols()));
124272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  status_dict->Set("force_spdy_over_ssl",
124372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                   Value::CreateBooleanValue(
124472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                       net::HttpStreamFactory::force_spdy_over_ssl()));
124572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  status_dict->Set("force_spdy_always",
124672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                   Value::CreateBooleanValue(
124772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                       net::HttpStreamFactory::force_spdy_always()));
124872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  status_dict->Set("next_protos",
124972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                   Value::CreateStringValue(
125072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                       *net::HttpStreamFactory::next_protos()));
125172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
125272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CallJavascriptFunction(L"g_browser.receivedSpdyStatus", status_dict);
125372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
125472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
125572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid
125672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenNetInternalsMessageHandler::IOThreadImpl::OnGetSpdyAlternateProtocolMappings(
125772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const ListValue* list) {
125872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  net::HttpNetworkSession* http_network_session =
125972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      GetHttpNetworkSession(context_getter_->GetURLRequestContext());
126072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
126172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ListValue* dict_list = new ListValue();
126272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
126372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (http_network_session) {
126472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const net::HttpAlternateProtocols& http_alternate_protocols =
126572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        http_network_session->alternate_protocols();
126672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const net::HttpAlternateProtocols::ProtocolMap& map =
126772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        http_alternate_protocols.protocol_map();
126872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
126972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    for (net::HttpAlternateProtocols::ProtocolMap::const_iterator it =
127072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen             map.begin();
127172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen         it != map.end(); ++it) {
127272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      DictionaryValue* dict = new DictionaryValue();
127372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      dict->SetString("host_port_pair", it->first.ToString());
127472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      dict->SetString("alternate_protocol", it->second.ToString());
127572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      dict_list->Append(dict);
127672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
127772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
127872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
127972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CallJavascriptFunction(L"g_browser.receivedSpdyAlternateProtocolMappings",
128072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                         dict_list);
128172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
128272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
12833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#ifdef OS_WIN
12843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid NetInternalsMessageHandler::IOThreadImpl::OnGetServiceProviders(
12853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const ListValue* list) {
12863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
12873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DictionaryValue* service_providers = new DictionaryValue();
12883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
12893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  WinsockLayeredServiceProviderList layered_providers;
12903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GetWinsockLayeredServiceProviders(&layered_providers);
12913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ListValue* layered_provider_list = new ListValue();
12923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  for (size_t i = 0; i < layered_providers.size(); ++i) {
12933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    DictionaryValue* service_dict = new DictionaryValue();
12943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    service_dict->SetString("name", layered_providers[i].name);
12953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    service_dict->SetInteger("version", layered_providers[i].version);
12963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    service_dict->SetInteger("chain_length", layered_providers[i].chain_length);
12973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    service_dict->SetInteger("socket_type", layered_providers[i].socket_type);
12983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    service_dict->SetInteger("socket_protocol",
12993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        layered_providers[i].socket_protocol);
13003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    service_dict->SetString("path", layered_providers[i].path);
13013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
13023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    layered_provider_list->Append(service_dict);
13033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
13043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  service_providers->Set("service_providers", layered_provider_list);
13053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
13063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  WinsockNamespaceProviderList namespace_providers;
13073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GetWinsockNamespaceProviders(&namespace_providers);
13083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ListValue* namespace_list = new ListValue;
13093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  for (size_t i = 0; i < namespace_providers.size(); ++i) {
13103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    DictionaryValue* namespace_dict = new DictionaryValue();
13113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    namespace_dict->SetString("name", namespace_providers[i].name);
13123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    namespace_dict->SetBoolean("active", namespace_providers[i].active);
13133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    namespace_dict->SetInteger("version", namespace_providers[i].version);
13143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    namespace_dict->SetInteger("type", namespace_providers[i].type);
13153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
13163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    namespace_list->Append(namespace_dict);
13173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
13183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  service_providers->Set("namespace_providers", namespace_list);
13193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
13203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CallJavascriptFunction(L"g_browser.receivedServiceProviders",
13213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         service_providers);
13223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
13233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#endif
13243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1325731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid NetInternalsMessageHandler::IOThreadImpl::OnSetLogLevel(
1326731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const ListValue* list) {
1327731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  int log_level;
1328731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  std::string log_level_string;
1329731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (!list->GetString(0, &log_level_string) ||
1330731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      !base::StringToInt(log_level_string, &log_level)) {
1331731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    NOTREACHED();
1332731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return;
1333731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
1334731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1335731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK_GE(log_level, net::NetLog::LOG_ALL);
1336731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK_LE(log_level, net::NetLog::LOG_BASIC);
133721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  SetLogLevel(static_cast<net::NetLog::LogLevel>(log_level));
1338731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
1339731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
134021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Note that unlike other methods of IOThreadImpl, this function
134121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// can be called from ANY THREAD.
1342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NetInternalsMessageHandler::IOThreadImpl::OnAddEntry(
1343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    net::NetLog::EventType type,
1344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const base::TimeTicks& time,
1345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const net::NetLog::Source& source,
1346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    net::NetLog::EventPhase phase,
1347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    net::NetLog::EventParameters* params) {
13483f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  BrowserThread::PostTask(
13493f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      BrowserThread::IO, FROM_HERE,
13503f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      NewRunnableMethod(
13513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen          this, &IOThreadImpl::AddEntryToQueue,
13523f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen          net::NetLog::EntryToDictionaryValue(type, time, source, phase,
13533f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                              params, false)));
13543f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
13553f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
13563f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid NetInternalsMessageHandler::IOThreadImpl::AddEntryToQueue(Value* entry) {
13573f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
13583f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (!pending_entries_.get()) {
13593f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    pending_entries_.reset(new ListValue());
13603f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    BrowserThread::PostDelayedTask(
13613f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        BrowserThread::IO, FROM_HERE,
13623f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        NewRunnableMethod(this, &IOThreadImpl::PostPendingEntries),
13633f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        kNetLogEventDelayMilliseconds);
13643f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
13653f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  pending_entries_->Append(entry);
13663f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
13673f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
13683f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid NetInternalsMessageHandler::IOThreadImpl::PostPendingEntries() {
13693f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CallJavascriptFunction(
13713f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      L"g_browser.receivedLogEntries",
13723f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      pending_entries_.release());
1373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NetInternalsMessageHandler::IOThreadImpl::OnStartConnectionTestSuite() {
1376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CallJavascriptFunction(L"g_browser.receivedStartConnectionTestSuite", NULL);
1377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NetInternalsMessageHandler::IOThreadImpl::OnStartConnectionTestExperiment(
1380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const ConnectionTester::Experiment& experiment) {
1381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CallJavascriptFunction(
1382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      L"g_browser.receivedStartConnectionTestExperiment",
1383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ExperimentToValue(experiment));
1384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid
1387c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNetInternalsMessageHandler::IOThreadImpl::OnCompletedConnectionTestExperiment(
1388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const ConnectionTester::Experiment& experiment,
1389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int result) {
1390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue* dict = new DictionaryValue();
1391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
13923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  dict->Set("experiment", ExperimentToValue(experiment));
13933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  dict->SetInteger("result", result);
1394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CallJavascriptFunction(
1396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      L"g_browser.receivedCompletedConnectionTestExperiment",
1397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      dict);
1398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid
1401c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNetInternalsMessageHandler::IOThreadImpl::OnCompletedConnectionTestSuite() {
1402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CallJavascriptFunction(
1403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      L"g_browser.receivedCompletedConnectionTestSuite",
1404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NULL);
1405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NetInternalsMessageHandler::IOThreadImpl::DispatchToMessageHandler(
14083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ListValue* arg, MessageHandler method) {
1409731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  (this->*method)(arg);
1411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delete arg;
1412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
141421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Note that this can be called from ANY THREAD.
1415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NetInternalsMessageHandler::IOThreadImpl::CallJavascriptFunction(
1416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::wstring& function_name,
1417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Value* arg) {
1418731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
141972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (handler_ && !was_webui_deleted_) {
1420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // We check |handler_| in case it was deleted on the UI thread earlier
1421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // while we were running on the IO thread.
1422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      handler_->CallJavascriptFunction(function_name, arg);
1423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delete arg;
1425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
1426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1428731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (!BrowserThread::PostTask(
1429731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick           BrowserThread::UI, FROM_HERE,
1430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch           NewRunnableMethod(
1431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch               this,
1432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch               &IOThreadImpl::CallJavascriptFunction,
1433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch               function_name, arg))) {
1434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Failed posting the task, avoid leaking.
1435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delete arg;
1436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
1440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
1443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
1444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// NetInternalsUI
1445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
1446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
1447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
144872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenNetInternalsUI::NetInternalsUI(TabContents* contents) : WebUI(contents) {
1449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddMessageHandler((new NetInternalsMessageHandler())->Attach(this));
1450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NetInternalsHTMLSource* html_source = new NetInternalsHTMLSource();
1452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Set up the chrome://net-internals/ source.
145472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source);
1455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1456