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
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser_about_handler.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <algorithm>
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string>
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector>
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/callback.h"
123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/command_line.h"
13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/file_util.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/i18n/number_formatting.h"
1572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/json/json_writer.h"
16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/singleton.h"
17731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/metrics/histogram.h"
18731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/metrics/stats_table.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/path_service.h"
203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_piece.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
23dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/stringprintf.h"
243f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread.h"
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/tracked_objects.h"
263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h"
2772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/values.h"
28731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/about_flags.h"
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser_process.h"
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/defaults.h"
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/memory_details.h"
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/metrics/histogram_synchronizer.h"
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/net/predictor_api.h"
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/platform_util.h"
3521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
3621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile_manager.h"
3772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/browser_dialogs.h"
38dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/webui/chrome_url_data_manager.h"
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/about_handler.h"
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_paths.h"
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_version_info.h"
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/jstemplate_builder.h"
433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/net/gaia/google_service_auth_error.h"
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/render_messages.h"
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/url_constants.h"
46dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
47dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/gpu_process_host.h"
48dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_process_host.h"
49dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_view_host.h"
50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/gpu_messages.h"
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "googleurl/src/gurl.h"
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/browser_resources.h"
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/chromium_strings.h"
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h"
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/locale_settings.h"
56731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/base/escape.h"
5772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h"
5872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/resource/resource_bundle.h"
59dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "webkit/glue/webkit_glue.h"
60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "webkit/glue/plugins/plugin_list.h"
61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "webkit/plugins/npapi/webplugininfo.h"
62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifdef CHROME_V8
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "v8/include/v8.h"
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
68513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/browser/enumerate_modules_model_win.h"
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_CHROMEOS)
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/cros/cros_library.h"
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/cros/network_library.h"
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/cros/syslogs_library.h"
73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/chromeos/login/wizard_controller.h"
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/version_loader.h"
75dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/zygote_host_linux.h"
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_LINUX)
77dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/zygote_host_linux.h"
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(USE_TCMALLOC)
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "third_party/tcmalloc/chromium/src/google/malloc_extension.h"
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::Time;
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::TimeDelta;
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(USE_TCMALLOC)
8821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// static
8921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenAboutTcmallocOutputs* AboutTcmallocOutputs::GetInstance() {
9021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return Singleton<AboutTcmallocOutputs>::get();
9121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
9221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
93dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenAboutTcmallocOutputs::AboutTcmallocOutputs() {}
94dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
95dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenAboutTcmallocOutputs::~AboutTcmallocOutputs() {}
96dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Glue between the callback task and the method in the singleton.
98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid AboutTcmallocRendererCallback(base::ProcessId pid,
99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                   const std::string& output) {
10021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  AboutTcmallocOutputs::GetInstance()->RendererCallback(pid, output);
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The (alphabetized) paths used for the about pages.
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Note: Keep these in sync with url_constants.h
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kAppCacheInternalsPath[] = "appcache-internals";
109731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst char kBlobInternalsPath[] = "blob-internals";
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kCreditsPath[] = "credits";
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kCachePath[] = "view-http-cache";
112513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#if defined(OS_WIN)
113513209b27ff55e2841eac0e4120199c23acce758Ben Murdochconst char kConflictsPath[] = "conflicts";
114513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#endif
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kDnsPath[] = "dns";
116731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst char kFlagsPath[] = "flags";
117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char kGpuPath[] = "gpu-internals";
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kHistogramsPath[] = "histograms";
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kMemoryRedirectPath[] = "memory-redirect";
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kMemoryPath[] = "memory";
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kStatsPath[] = "stats";
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kTasksPath[] = "tasks";
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kTcmallocPath[] = "tcmalloc";
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kTermsPath[] = "terms";
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kVersionPath[] = "version";
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kAboutPath[] = "about";
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Not about:* pages, but included to make about:about look nicer
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kNetInternalsPath[] = "net-internals";
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kPluginsPath[] = "plugins";
13072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst char kSyncInternalsPath[] = "sync-internals";
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_LINUX)
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kLinuxProxyConfigPath[] = "linux-proxy-config";
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kSandboxPath[] = "sandbox";
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kNetworkPath[] = "network";
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kOSCreditsPath[] = "os-credits";
140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char kEULAPathFormat[] = "/usr/share/chromeos-assets/eula/%s/eula.html";
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Add path here to be included in about:about
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char *kAllAboutPaths[] = {
145dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  kAboutPath,
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kAppCacheInternalsPath,
147731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  kBlobInternalsPath,
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kCachePath,
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kCreditsPath,
150513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#if defined(OS_WIN)
151513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  kConflictsPath,
152513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#endif
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kDnsPath,
154731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  kFlagsPath,
1553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  kGpuPath,
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kHistogramsPath,
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kMemoryPath,
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kNetInternalsPath,
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kPluginsPath,
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kStatsPath,
16172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  kSyncInternalsPath,
162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#ifdef TRACK_ALL_TASK_OBJECTS
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kTasksPath,
164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif  // TRACK_ALL_TASK_OBJECTS
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kTcmallocPath,
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kTermsPath,
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kVersionPath,
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_LINUX)
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kSandboxPath,
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kNetworkPath,
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kOSCreditsPath,
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// When you type about:memory, it actually loads an intermediate URL that
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// redirects you to the final page. This avoids the problem where typing
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// "about:memory" on the new tab page or any other page where a process
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// transition would occur to the about URL will cause some confusion.
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The problem is that during the processing of the memory page, there are two
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// processes active, the original and the destination one. This can create the
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// impression that we're using more resources than we actually are. This
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// redirect solves the problem by eliminating the process transition during the
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// time that about memory is being computed.
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string GetAboutMemoryRedirectResponse() {
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return "<meta http-equiv=\"refresh\" "
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "content=\"0;chrome://about/memory\">";
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass AboutSource : public ChromeURLDataManager::DataSource {
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Creates our datasource.
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AboutSource();
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Called when the network layer has requested a resource underneath
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the path we registered.
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void StartDataRequest(const std::string& path,
200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                bool is_incognito,
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                int request_id);
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual std::string GetMimeType(const std::string&) const {
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return "text/html";
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Send the response data.
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void FinishDataRequest(const std::string& html, int request_id);
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~AboutSource();
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(AboutSource);
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Handling about:memory is complicated enough to encapsulate its related
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// methods into a single class. The user should create it (on the heap) and call
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// its |StartFetch()| method.
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass AboutMemoryHandler : public MemoryDetails {
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AboutMemoryHandler(AboutSource* source, int request_id)
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : source_(source), request_id_(request_id) {}
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnDetailsAvailable();
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ~AboutMemoryHandler() {}
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void BindProcessMetrics(DictionaryValue* data,
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          ProcessMemoryInformation* info);
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void AppendProcess(ListValue* child_data, ProcessMemoryInformation* info);
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<AboutSource> source_;
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int request_id_;
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(AboutMemoryHandler);
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ChromeOSAboutVersionHandler is responsible for loading the Chrome OS
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// version.
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ChromeOSAboutVersionHandler handles deleting itself once the version has
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// been obtained and AboutSource notified.
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ChromeOSAboutVersionHandler {
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ChromeOSAboutVersionHandler(AboutSource* source, int request_id);
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Callback from chromeos::VersionLoader giving the version.
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void OnVersion(chromeos::VersionLoader::Handle handle,
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 std::string version);
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Where the results are fed to.
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<AboutSource> source_;
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ID identifying the request.
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int request_id_;
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Handles asynchronously loading the version.
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  chromeos::VersionLoader loader_;
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Used to request the version.
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CancelableRequestConsumer consumer_;
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(ChromeOSAboutVersionHandler);
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass ChromeOSTermsHandler
270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    : public base::RefCountedThreadSafe<ChromeOSTermsHandler> {
271ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen public:
272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  static void Start(AboutSource* source, int request_id) {
273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    scoped_refptr<ChromeOSTermsHandler> handler(
274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        new ChromeOSTermsHandler(source, request_id));
275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    handler->StartOnUIThread();
276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen private:
279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ChromeOSTermsHandler(AboutSource* source, int request_id)
280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    : source_(source),
281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      request_id_(request_id),
282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      locale_(WizardController::GetInitialLocale()) {
283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
284ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
285ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void StartOnUIThread() {
286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BrowserThread::PostTask(
288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        BrowserThread::FILE, FROM_HERE,
289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        NewRunnableMethod(this, &ChromeOSTermsHandler::LoadFileOnFileThread));
290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void LoadFileOnFileThread() {
293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    std::string path = StringPrintf(kEULAPathFormat, locale_.c_str());
295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!file_util::ReadFileToString(FilePath(path), &contents_)) {
296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // No EULA for given language - try en-US as default.
297ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      path = StringPrintf(kEULAPathFormat, "en-US");
298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (!file_util::ReadFileToString(FilePath(path), &contents_)) {
299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // File with EULA not found, ResponseOnUIThread will load EULA from
300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // resources if contents_ is empty.
301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        contents_.clear();
302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
303ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BrowserThread::PostTask(
305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        BrowserThread::UI, FROM_HERE,
306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        NewRunnableMethod(this, &ChromeOSTermsHandler::ResponseOnUIThread));
307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void ResponseOnUIThread() {
310ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
311ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (contents_.empty()) {
312ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      contents_ = ResourceBundle::GetSharedInstance().GetRawDataResource(
313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          IDR_TERMS_HTML).as_string();
314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    source_->FinishDataRequest(contents_, request_id_);
316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Where the results are fed to.
319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<AboutSource> source_;
320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // ID identifying the request.
322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  int request_id_;
323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
324ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::string locale_;
325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
326ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::string contents_;
327ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
328ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DISALLOW_COPY_AND_ASSIGN(ChromeOSTermsHandler);
329ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen};
330ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Individual about handlers ---------------------------------------------------
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string AboutAbout() {
336dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  std::string html("<html><head><title>About Pages</title></head>\n"
337dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      "<body><h2>List of About pages</h2>\n<ul>");
338dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  std::vector<std::string> paths(AboutPaths());
339dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  for (std::vector<std::string>::const_iterator i = paths.begin();
340dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen       i != paths.end(); ++i) {
341dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    html += "<li><a href='chrome://";
342dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    if ((*i != kAppCacheInternalsPath) &&
343dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        (*i != kBlobInternalsPath) &&
344dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        (*i != kCachePath) &&
345dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  #if defined(OS_WIN)
346dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        (*i != kConflictsPath) &&
347dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  #endif
348dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        (*i != kFlagsPath) &&
349dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        (*i != kGpuPath) &&
350dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        (*i != kNetInternalsPath) &&
351dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        (*i != kPluginsPath)) {
352dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      html += "about/";
3533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
354dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    html += *i + "/'>about:" + *i + "</a></li>\n";
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
35672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  const char *debug[] = { "crash", "kill", "hang", "shorthang",
35772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                          "gpucrash", "gpuhang" };
358dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  html += "</ul>\n<h2>For Debug</h2>\n"
359dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      "<p>The following pages are for debugging purposes only. Because they "
360dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      "crash or hang the renderer, they're not linked directly; you can type "
361dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      "them into the address bar if you need them.</p>\n<ul>";
362dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  for (size_t i = 0; i < arraysize(debug); i++)
363dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    html += "<li>about:" + std::string(debug[i]) + "</li>\n";
364dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  html += "</ul>\n</body></html>";
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return html;
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
369ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
370ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Html output helper functions
371ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// TODO(stevenjb): L10N this.
372ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
373ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Helper function to wrap Html with <th> tag.
374ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic std::string WrapWithTH(std::string text) {
375ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return "<th>" + text + "</th>";
376ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
377ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
378ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Helper function to wrap Html with <td> tag.
379ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic std::string WrapWithTD(std::string text) {
380ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return "<td>" + text + "</td>";
381ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
382ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
383ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Helper function to create an Html table header for a Network.
384ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic std::string ToHtmlTableHeader(const chromeos::Network* network) {
385ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::string str =
386ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      WrapWithTH("Name") +
387ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      WrapWithTH("Active") +
388ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      WrapWithTH("State");
389ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (network->type() == chromeos::TYPE_WIFI ||
390ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      network->type() == chromeos::TYPE_CELLULAR) {
391ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTH("Auto-Connect");
392ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTH("Strength");
393ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
394ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (network->type() == chromeos::TYPE_WIFI) {
395ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTH("Encryption");
396ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTH("Passphrase");
397ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTH("Identity");
398ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTH("Certificate");
399ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
400ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (network->type() == chromeos::TYPE_CELLULAR) {
401ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTH("Technology");
402ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTH("Connectivity");
403ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTH("Activation");
404ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTH("Roaming");
405ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
406ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (network->type() == chromeos::TYPE_VPN) {
407ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTH("Host");
408ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTH("Provider Type");
409ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTH("PSK Passphrase");
410ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTH("Username");
411ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTH("User Passphrase");
412ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
413ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  str += WrapWithTH("Error");
414ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  str += WrapWithTH("IP Address");
415ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return str;
416ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
417ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
418ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Helper function to create an Html table row for a Network.
419ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic std::string ToHtmlTableRow(const chromeos::Network* network) {
420ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::string str =
421ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      WrapWithTD(network->name()) +
422ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      WrapWithTD(base::IntToString(network->is_active())) +
423ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      WrapWithTD(network->GetStateString());
424ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (network->type() == chromeos::TYPE_WIFI ||
425ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      network->type() == chromeos::TYPE_CELLULAR) {
426ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const chromeos::WirelessNetwork* wireless =
427ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        static_cast<const chromeos::WirelessNetwork*>(network);
428ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTD(base::IntToString(wireless->auto_connect()));
429ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTD(base::IntToString(wireless->strength()));
430ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
431ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (network->type() == chromeos::TYPE_WIFI) {
432ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const chromeos::WifiNetwork* wifi =
433ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        static_cast<const chromeos::WifiNetwork*>(network);
434ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTD(wifi->GetEncryptionString());
435ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTD(std::string(wifi->passphrase().length(), '*'));
436ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTD(wifi->identity());
437ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTD(wifi->cert_path());
438ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
439ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (network->type() == chromeos::TYPE_CELLULAR) {
440ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const chromeos::CellularNetwork* cell =
441ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        static_cast<const chromeos::CellularNetwork*>(network);
442ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTH(cell->GetNetworkTechnologyString());
443ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTH(cell->GetConnectivityStateString());
444ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTH(cell->GetActivationStateString());
445ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTH(cell->GetRoamingStateString());
446ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
447ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (network->type() == chromeos::TYPE_VPN) {
448ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const chromeos::VirtualNetwork* vpn =
449ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        static_cast<const chromeos::VirtualNetwork*>(network);
450ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTH(vpn->server_hostname());
451ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTH(vpn->GetProviderTypeString());
452ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTD(std::string(vpn->psk_passphrase().length(), '*'));
453ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTH(vpn->username());
454ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    str += WrapWithTD(std::string(vpn->user_passphrase().length(), '*'));
455ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
456ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  str += WrapWithTD(network->failed() ? network->GetErrorString() : "");
457ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  str += WrapWithTD(network->ip_address());
458ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return str;
459ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
460ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
461ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstd::string GetNetworkHtmlInfo(int refresh) {
462ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  chromeos::NetworkLibrary* cros =
463ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      chromeos::CrosLibrary::Get()->GetNetworkLibrary();
464ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::string output;
465ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  output.append("<html><head><title>About Network</title>");
466ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (refresh > 0)
467ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    output.append("<meta http-equiv=\"refresh\" content=\"" +
468ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  base::IntToString(refresh) + "\"/>");
469ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  output.append("</head><body>");
470ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (refresh > 0) {
471ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    output.append("(Auto-refreshing page every " +
472ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  base::IntToString(refresh) + "s)");
473ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else {
474ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    output.append("(To auto-refresh this page: about:network/&lt;secs&gt;)");
475ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
476ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
477ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (cros->ethernet_enabled()) {
478ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    output.append("<h3>Ethernet:</h3><table border=1>");
479ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const chromeos::EthernetNetwork* ethernet = cros->ethernet_network();
480ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (ethernet) {
481ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      output.append("<tr>" + ToHtmlTableHeader(ethernet) + "</tr>");
482ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      output.append("<tr>" + ToHtmlTableRow(ethernet) + "</tr>");
483ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
484ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
485ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
486ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (cros->wifi_enabled()) {
487ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    output.append("</table><h3>Wifi Networks:</h3><table border=1>");
488ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const chromeos::WifiNetworkVector& wifi_networks = cros->wifi_networks();
489ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (size_t i = 0; i < wifi_networks.size(); ++i) {
490ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (i == 0)
491ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        output.append("<tr>" + ToHtmlTableHeader(wifi_networks[i]) +
492ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                      "</tr>");
493ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      output.append("<tr>" + ToHtmlTableRow(wifi_networks[i]) + "</tr>");
494ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
495ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
496ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
497ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (cros->cellular_enabled()) {
498ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    output.append("</table><h3>Cellular Networks:</h3><table border=1>");
499ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const chromeos::CellularNetworkVector& cellular_networks =
500ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        cros->cellular_networks();
501ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (size_t i = 0; i < cellular_networks.size(); ++i) {
502ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (i == 0)
503ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        output.append("<tr>" + ToHtmlTableHeader(cellular_networks[i]) +
504ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                      "</tr>");
505ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      output.append("<tr>" + ToHtmlTableRow(cellular_networks[i]) + "</tr>");
506ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
507ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
508ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
509ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  {
510ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    output.append("</table><h3>Virtual Networks:</h3><table border=1>");
511ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const chromeos::VirtualNetworkVector& virtual_networks =
512ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        cros->virtual_networks();
513ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (size_t i = 0; i < virtual_networks.size(); ++i) {
514ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (i == 0)
515ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        output.append("<tr>" + ToHtmlTableHeader(virtual_networks[i]) +
516ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                      "</tr>");
517ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      output.append("<tr>" + ToHtmlTableRow(virtual_networks[i]) + "</tr>");
518ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
519ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
520ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
521ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  {
522ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    output.append(
523ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        "</table><h3>Remembered Wi-Fi Networks:</h3><table border=1>");
524ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const chromeos::WifiNetworkVector& remembered_wifi_networks =
525ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        cros->remembered_wifi_networks();
526ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (size_t i = 0; i < remembered_wifi_networks.size(); ++i) {
527ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (i == 0)
528ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        output.append("<tr>" +
529ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                      ToHtmlTableHeader(remembered_wifi_networks[i]) + "</tr>");
530ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      output.append("<tr>" + ToHtmlTableRow(remembered_wifi_networks[i]) +
531ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                    "</tr>");
532ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
533ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
534ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
535ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  output.append("</table></body></html>");
536ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return output;
537ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
538ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string AboutNetwork(const std::string& query) {
540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int refresh;
5413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  base::StringToInt(query, &refresh);
542ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return GetNetworkHtmlInfo(refresh);
543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// AboutDnsHandler bounces the request back to the IO thread to collect
547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the DNS information.
548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass AboutDnsHandler : public base::RefCountedThreadSafe<AboutDnsHandler> {
549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static void Start(AboutSource* source, int request_id) {
551513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    scoped_refptr<AboutDnsHandler> handler(
552513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        new AboutDnsHandler(source, request_id));
553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    handler->StartOnUIThread();
554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AboutDnsHandler(AboutSource* source, int request_id)
558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : source_(source),
559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        request_id_(request_id) {
560731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Calls FinishOnUIThread() on completion.
564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void StartOnUIThread() {
565731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
566731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BrowserThread::PostTask(
567731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        BrowserThread::IO, FROM_HERE,
568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NewRunnableMethod(this, &AboutDnsHandler::StartOnIOThread));
569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void StartOnIOThread() {
572731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string data;
575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    chrome_browser_net::PredictorGetHtmlInfo(&data);
576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
577731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BrowserThread::PostTask(
578731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        BrowserThread::UI, FROM_HERE,
579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NewRunnableMethod(this, &AboutDnsHandler::FinishOnUIThread, data));
580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void FinishOnUIThread(const std::string& data) {
583731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    source_->FinishDataRequest(data, request_id_);
585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Where the results are fed to.
588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<AboutSource> source_;
589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ID identifying the request.
591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int request_id_;
592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(AboutDnsHandler);
594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(USE_TCMALLOC)
597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string AboutTcmalloc(const std::string& query) {
598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string data;
599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AboutTcmallocOutputsType* outputs =
60021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      AboutTcmallocOutputs::GetInstance()->outputs();
601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Display any stats for which we sent off requests the last time.
603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("<html><head><title>About tcmalloc</title></head><body>\n");
604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("<p>Stats as of last page load;");
605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("reload to get stats as of this page load.</p>\n");
606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("<table width=\"100%\">\n");
607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (AboutTcmallocOutputsType::const_iterator oit = outputs->begin();
608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       oit != outputs->end();
609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       oit++) {
610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data.append("<tr><td bgcolor=\"yellow\">");
611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data.append(oit->first);
612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data.append("</td></tr>\n");
613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data.append("<tr><td><pre>\n");
614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data.append(oit->second);
615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data.append("</pre></td></tr>\n");
616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("</table>\n");
618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("</body></html>\n");
619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Reset our collector singleton.
621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  outputs->clear();
622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Populate the collector with stats from the local browser process
624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // and send off requests to all the renderer processes.
625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  char buffer[1024 * 32];
626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MallocExtension::instance()->GetStats(buffer, sizeof(buffer));
627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string browser("Browser");
62821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  AboutTcmallocOutputs::GetInstance()->SetOutput(browser, buffer);
629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  while (!it.IsAtEnd()) {
631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    it.GetCurrentValue()->Send(new ViewMsg_GetRendererTcmalloc);
632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    it.Advance();
633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return data;
636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string AboutHistograms(const std::string& query) {
640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TimeDelta wait_time = TimeDelta::FromMilliseconds(10000);
641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HistogramSynchronizer* current_synchronizer =
643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      HistogramSynchronizer::CurrentSynchronizer();
644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(current_synchronizer != NULL);
645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  current_synchronizer->FetchRendererHistogramsSynchronously(wait_time);
646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string data;
648731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  base::StatisticsRecorder::WriteHTMLGraph(query, &data);
649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return data;
650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AboutMemory(AboutSource* source, int request_id) {
653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The AboutMemoryHandler cleans itself up, but |StartFetch()| will want the
654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // refcount to be greater than 0.
655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<AboutMemoryHandler>
656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      handler(new AboutMemoryHandler(source, request_id));
657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  handler->StartFetch();
658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifdef TRACK_ALL_TASK_OBJECTS
661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic std::string AboutObjects(const std::string& query) {
662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string data;
663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tracked_objects::ThreadData::WriteHTML(query, &data);
664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return data;
665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // TRACK_ALL_TASK_OBJECTS
667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
66872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Handler for filling in the "about:stats" page, as called by the browser's
66972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// About handler processing.
67072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// |query| is roughly the query string of the about:stats URL.
67172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Returns a string containing the HTML to render for the about:stats page.
67272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Conditional Output:
67372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//      if |query| is "json", returns a JSON format of all counters.
67472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//      if |query| is "raw", returns plain text of counter deltas.
67572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//      otherwise, returns HTML with pretty JS/HTML to display the data.
67672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstd::string AboutStats(const std::string& query) {
677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We keep the DictionaryValue tree live so that we can do delta
678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // stats computations across runs.
679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static DictionaryValue root;
68072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  static base::TimeTicks last_sample_time = base::TimeTicks::Now();
68172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
68272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::TimeTicks now = base::TimeTicks::Now();
68372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::TimeDelta time_since_last_sample = now - last_sample_time;
68472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  last_sample_time = now;
685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
686731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  base::StatsTable* table = base::StatsTable::current();
687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!table)
688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return std::string();
689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We maintain two lists - one for counters and one for timers.
691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Timers actually get stored on both lists.
692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue* counters;
6933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!root.GetList("counters", &counters)) {
694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    counters = new ListValue();
6953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    root.Set("counters", counters);
696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue* timers;
6993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!root.GetList("timers", &timers)) {
700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    timers = new ListValue();
7013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    root.Set("timers", timers);
702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // NOTE: Counters start at index 1.
705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int index = 1; index <= table->GetMaxCounters(); index++) {
706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Get the counter's full name
707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string full_name = table->GetRowName(index);
708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (full_name.length() == 0)
709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK_EQ(':', full_name[1]);
711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    char counter_type = full_name[0];
712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string name = full_name.substr(2);
713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // JSON doesn't allow '.' in names.
715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    size_t pos;
716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    while ((pos = name.find(".")) != std::string::npos)
717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      name.replace(pos, 1, ":");
718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Try to see if this name already exists.
720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* counter = NULL;
721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t scan_index = 0;
722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         scan_index < counters->GetSize(); scan_index++) {
723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DictionaryValue* dictionary;
724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (counters->GetDictionary(scan_index, &dictionary)) {
7253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        std::string scan_name;
7263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        if (dictionary->GetString("name", &scan_name) && scan_name == name) {
727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          counter = dictionary;
728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      } else {
730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NOTREACHED();  // Should always be there
731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (counter == NULL) {
735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      counter = new DictionaryValue();
7363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      counter->SetString("name", name);
737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      counters->Append(counter);
738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    switch (counter_type) {
741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case 'c':
742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        {
743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          int new_value = table->GetRowValue(index);
744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          int prior_value = 0;
745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          int delta = 0;
7463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          if (counter->GetInteger("value", &prior_value)) {
747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            delta = new_value - prior_value;
748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          }
7493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          counter->SetInteger("value", new_value);
7503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          counter->SetInteger("delta", delta);
751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case 'm':
754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        {
755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          // TODO(mbelshe): implement me.
756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case 't':
759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        {
760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          int time = table->GetRowValue(index);
7613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          counter->SetInteger("time", time);
762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          // Store this on the timers list as well.
764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          timers->Append(counter);
765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      default:
768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NOTREACHED();
769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
77272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  std::string data;
77372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (query == "json") {
77472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    base::JSONWriter::WriteWithOptionalEscape(&root, true, false, &data);
77572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  } else if (query == "raw") {
77672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // Dump the raw counters which have changed in text format.
77772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    data = "<pre>";
77872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    data.append(StringPrintf("Counter changes in the last %ldms\n",
77972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        static_cast<long int>(time_since_last_sample.InMilliseconds())));
78072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    for (size_t i = 0; i < counters->GetSize(); ++i) {
78172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      Value* entry = NULL;
78272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      bool rv = counters->Get(i, &entry);
78372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      if (!rv)
78472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        continue;  // None of these should fail.
78572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      DictionaryValue* counter = static_cast<DictionaryValue*>(entry);
78672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      int delta;
78772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      rv = counter->GetInteger("delta", &delta);
78872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      if (!rv)
78972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        continue;
79072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      if (delta > 0) {
79172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        std::string name;
79272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        rv = counter->GetString("name", &name);
79372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        if (!rv)
79472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          continue;
79572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        int value;
79672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        rv = counter->GetInteger("value", &value);
79772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        if (!rv)
79872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          continue;
79972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        data.append(name);
80072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        data.append(":");
80172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        data.append(base::IntToString(delta));
80272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        data.append("\n");
80372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      }
80472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
80572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    data.append("</pre>");
80672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  } else {
80772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // Get about_stats.html and process a pretty page.
80872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    static const base::StringPiece stats_html(
80972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        ResourceBundle::GetSharedInstance().GetRawDataResource(
81072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            IDR_ABOUT_STATS_HTML));
81172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
81272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // Create jstemplate and return.
81372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    data = jstemplate_builder::GetTemplateHtml(
81472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        stats_html, &root, "t" /* template root node id */);
81572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
81672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // Clear the timer list since we stored the data in the timers list as well.
81772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    for (int index = static_cast<int>(timers->GetSize())-1; index >= 0;
81872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen         index--) {
81972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      Value* value;
82072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      timers->Remove(index, &value);
82172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      // We don't care about the value pointer; it's still tracked
82272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      // on the counters list.
82372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return data;
827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_LINUX)
830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string AboutLinuxProxyConfig() {
831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string data;
832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("<!DOCTYPE HTML>\n");
833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("<html><head><meta charset=\"utf-8\"><title>");
834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append(l10n_util::GetStringUTF8(IDS_ABOUT_LINUX_PROXY_CONFIG_TITLE));
835c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("</title>");
836c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("<style>body { max-width: 70ex; padding: 2ex 5ex; }</style>");
837c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("</head><body>\n");
838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath binary = CommandLine::ForCurrentProcess()->GetProgram();
839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append(l10n_util::GetStringFUTF8(
840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  IDS_ABOUT_LINUX_PROXY_CONFIG_BODY,
841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
842c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  ASCIIToUTF16(binary.BaseName().value())));
843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("</body></html>\n");
844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return data;
845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AboutSandboxRow(std::string* data, const std::string& prefix, int name_id,
848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                     bool good) {
849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data->append("<tr><td>");
850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data->append(prefix);
851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data->append(l10n_util::GetStringUTF8(name_id));
852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (good) {
853c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data->append("</td><td style=\"color: green;\">");
854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data->append(
855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        l10n_util::GetStringUTF8(IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL));
856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data->append("</td><td style=\"color: red;\">");
858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data->append(
859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        l10n_util::GetStringUTF8(IDS_CONFIRM_MESSAGEBOX_NO_BUTTON_LABEL));
860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data->append("</td></tr>");
862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string AboutSandbox() {
865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string data;
866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("<!DOCTYPE HTML>\n");
867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("<html><head><meta charset=\"utf-8\"><title>");
868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append(l10n_util::GetStringUTF8(IDS_ABOUT_SANDBOX_TITLE));
869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("</title>");
870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("</head><body>\n");
871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("<h1>");
872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append(l10n_util::GetStringUTF8(IDS_ABOUT_SANDBOX_TITLE));
873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("</h1>");
874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
87521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  const int status = ZygoteHost::GetInstance()->sandbox_status();
876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
877c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("<table>");
878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AboutSandboxRow(&data, "", IDS_ABOUT_SANDBOX_SUID_SANDBOX,
880c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  status & ZygoteHost::kSandboxSUID);
881c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (status & ZygoteHost::kSandboxPIDNS) {
882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AboutSandboxRow(&data, "&nbsp;&nbsp;", IDS_ABOUT_SANDBOX_PID_NAMESPACES,
883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    status & ZygoteHost::kSandboxPIDNS);
884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AboutSandboxRow(&data, "&nbsp;&nbsp;", IDS_ABOUT_SANDBOX_NET_NAMESPACES,
885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    status & ZygoteHost::kSandboxNetNS);
886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AboutSandboxRow(&data, "", IDS_ABOUT_SANDBOX_SECCOMP_SANDBOX,
888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  status & ZygoteHost::kSandboxSeccomp);
889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("</table>");
891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool good = ((status & ZygoteHost::kSandboxSUID) &&
893c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch               (status & ZygoteHost::kSandboxPIDNS)) ||
894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              (status & ZygoteHost::kSandboxSeccomp);
895c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (good) {
896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data.append("<p style=\"color: green\">");
897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data.append(l10n_util::GetStringUTF8(IDS_ABOUT_SANDBOX_OK));
898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data.append("<p style=\"color: red\">");
900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data.append(l10n_util::GetStringUTF8(IDS_ABOUT_SANDBOX_BAD));
901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("</p>");
903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("</body></html>\n");
905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return data;
906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
907c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
908c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string AboutVersion(DictionaryValue* localized_strings) {
9103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings->SetString("title",
9113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_ABOUT_VERSION_TITLE));
9123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  chrome::VersionInfo version_info;
913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
914c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string webkit_version = webkit_glue::GetWebKitVersion();
915c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifdef CHROME_V8
916c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string js_version(v8::V8::GetVersion());
917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string js_engine = "V8";
918c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else
919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string js_version = webkit_version;
920c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string js_engine = "JavaScriptCore";
921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings->SetString("name",
9243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
9253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings->SetString("version", version_info.Version());
926ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Bug 79458: Need to evaluate the use of getting the version string on
927ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // this thread.
928ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::ThreadRestrictions::ScopedAllowIO allow_io;
9293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings->SetString("version_modifier",
9303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               platform_util::GetVersionStringModifier());
9313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings->SetString("js_engine", js_engine);
9323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings->SetString("js_version", js_version);
933ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
934ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Obtain the version of the first enabled Flash plugin.
935ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<webkit::npapi::WebPluginInfo> info_array;
936ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  webkit::npapi::PluginList::Singleton()->GetPluginInfoArray(
937ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      GURL(), "application/x-shockwave-flash", false, &info_array, NULL);
938ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  string16 flash_version =
939ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      l10n_util::GetStringUTF16(IDS_PLUGINS_DISABLED_PLUGIN);
940ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (size_t i = 0; i < info_array.size(); ++i) {
941ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (webkit::npapi::IsPluginEnabled(info_array[i])) {
942ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      flash_version = info_array[i].version;
943ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      break;
944ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
945ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
946ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  localized_strings->SetString("flash_plugin", "Flash");
947ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  localized_strings->SetString("flash_version", flash_version);
9483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings->SetString("webkit_version", webkit_version);
9493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings->SetString("company",
9503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_ABOUT_VERSION_COMPANY_NAME));
9513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings->SetString("copyright",
9523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_ABOUT_VERSION_COPYRIGHT));
9533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings->SetString("cl", version_info.LastChange());
9543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings->SetString("official",
9553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(
9563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          version_info.IsOfficialBuild() ?
9573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick              IDS_ABOUT_VERSION_OFFICIAL
9583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            : IDS_ABOUT_VERSION_UNOFFICIAL));
9593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings->SetString("user_agent_name",
9603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_ABOUT_VERSION_USER_AGENT));
9613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings->SetString("useragent", webkit_glue::GetUserAgent(GURL()));
9623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings->SetString("command_line_name",
9633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_ABOUT_VERSION_COMMAND_LINE));
964c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
965c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
9663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings->SetString("command_line",
9673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      WideToUTF16(CommandLine::ForCurrentProcess()->command_line_string()));
968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_POSIX)
969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string command_line = "";
970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef std::vector<std::string> ArgvList;
971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const ArgvList& argv = CommandLine::ForCurrentProcess()->argv();
972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (ArgvList::const_iterator iter = argv.begin(); iter != argv.end(); iter++)
973c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    command_line += " " + *iter;
9743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // TODO(viettrungluu): |command_line| could really have any encoding, whereas
9753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // below we assumes it's UTF-8.
9763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings->SetString("command_line", command_line);
977c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
979c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::StringPiece version_html(
980c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ResourceBundle::GetSharedInstance().GetRawDataResource(
981c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          IDR_ABOUT_VERSION_HTML));
982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
983c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return jstemplate_builder::GetTemplatesHtml(
984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      version_html, localized_strings, "t" /* template root node id */);
985c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
986c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstd::string VersionNumberToString(uint32 value) {
9883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int hi = (value >> 8) & 0xff;
9893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int low = value & 0xff;
9903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return base::IntToString(hi) + "." + base::IntToString(low);
9913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
9923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
993c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// AboutSource -----------------------------------------------------------------
994c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
995c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochAboutSource::AboutSource()
996c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : DataSource(chrome::kAboutScheme, MessageLoop::current()) {
997c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
998c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
999c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochAboutSource::~AboutSource() {
1000c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1001c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1002c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AboutSource::StartDataRequest(const std::string& path_raw,
1003ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    bool is_incognito, int request_id) {
1004c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string path = path_raw;
1005c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string info;
1006c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (path.find("/") != std::string::npos) {
1007c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    size_t pos = path.find("/");
1008c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    info = path.substr(pos + 1, path.length() - (pos + 1));
1009c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    path = path.substr(0, pos);
1010c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1011c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  path = StringToLowerASCII(path);
1012c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1013c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string response;
1014c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (path == kDnsPath) {
1015c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AboutDnsHandler::Start(this, request_id);
1016c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
1017c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kHistogramsPath) {
1018c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response = AboutHistograms(info);
1019c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kMemoryPath) {
1020c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AboutMemory(this, request_id);
1021c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
1022c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kMemoryRedirectPath) {
1023c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response = GetAboutMemoryRedirectResponse();
1024c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifdef TRACK_ALL_TASK_OBJECTS
1025c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kTasksPath) {
1026c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response = AboutObjects(info);
1027c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
1028c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kStatsPath) {
102972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    response = AboutStats(info);
1030c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(USE_TCMALLOC)
1031c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kTcmallocPath) {
1032c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response = AboutTcmalloc(info);
1033c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
1034c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kVersionPath || path.empty()) {
1035c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
1036c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    new ChromeOSAboutVersionHandler(this, request_id);
1037c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
1038c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else
1039c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue value;
1040c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response = AboutVersion(&value);
1041c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
1042c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kCreditsPath) {
1043c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response = ResourceBundle::GetSharedInstance().GetRawDataResource(
1044c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        IDR_CREDITS_HTML).as_string();
1045c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kAboutPath) {
1046c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response = AboutAbout();
1047c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
1048c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kOSCreditsPath) {
1049c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response = ResourceBundle::GetSharedInstance().GetRawDataResource(
1050c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        IDR_OS_CREDITS_HTML).as_string();
1051c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kNetworkPath) {
1052c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response = AboutNetwork(info);
1053c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
1054c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kTermsPath) {
1055ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(OS_CHROMEOS)
1056ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ChromeOSTermsHandler::Start(this, request_id);
1057ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
1058ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else
1059c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response = ResourceBundle::GetSharedInstance().GetRawDataResource(
1060c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        IDR_TERMS_HTML).as_string();
1061ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
1062c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_LINUX)
1063c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kLinuxProxyConfigPath) {
1064c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response = AboutLinuxProxyConfig();
1065c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kSandboxPath) {
1066c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response = AboutSandbox();
1067c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
1068c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1069c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1070c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FinishDataRequest(response, request_id);
1071c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1072c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1073c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AboutSource::FinishDataRequest(const std::string& response,
1074c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    int request_id) {
1075c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
1076c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  html_bytes->data.resize(response.size());
1077c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::copy(response.begin(), response.end(), html_bytes->data.begin());
1078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SendResponse(request_id, html_bytes);
1079c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1080c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1081c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// AboutMemoryHandler ----------------------------------------------------------
1082c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1083c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Helper for AboutMemory to bind results from a ProcessMetrics object
1084c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// to a DictionaryValue. Fills ws_usage and comm_usage so that the objects
1085c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// can be used in caller's scope (e.g for appending to a net total).
1086c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AboutMemoryHandler::BindProcessMetrics(DictionaryValue* data,
1087c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                            ProcessMemoryInformation* info) {
1088c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(data && info);
1089c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1090c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Bind metrics to dictionary.
10913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  data->SetInteger("ws_priv", static_cast<int>(info->working_set.priv));
10923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  data->SetInteger("ws_shareable",
1093c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    static_cast<int>(info->working_set.shareable));
10943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  data->SetInteger("ws_shared", static_cast<int>(info->working_set.shared));
10953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  data->SetInteger("comm_priv", static_cast<int>(info->committed.priv));
10963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  data->SetInteger("comm_map", static_cast<int>(info->committed.mapped));
10973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  data->SetInteger("comm_image", static_cast<int>(info->committed.image));
10983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  data->SetInteger("pid", info->pid);
109921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  data->SetString("version", info->version);
11003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  data->SetInteger("processes", info->num_processes);
1101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Helper for AboutMemory to append memory usage information for all
1104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// sub-processes (i.e. renderers, plugins) used by Chrome.
1105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AboutMemoryHandler::AppendProcess(ListValue* child_data,
1106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       ProcessMemoryInformation* info) {
1107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(child_data && info);
1108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Append a new DictionaryValue for this renderer to our list.
1110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue* child = new DictionaryValue();
1111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  child_data->Append(child);
1112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BindProcessMetrics(child, info);
1113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
11143f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  std::string child_label(
11153f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      ChildProcessInfo::GetFullTypeNameInEnglish(info->type,
11163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                                 info->renderer_type));
1117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (info->is_diagnostics)
11183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    child_label.append(" (diagnostics)");
11193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  child->SetString("child_name", child_label);
1120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue* titles = new ListValue();
11213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  child->Set("titles", titles);
1122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < info->titles.size(); ++i)
112321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    titles->Append(new StringValue(info->titles[i]));
1124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AboutMemoryHandler::OnDetailsAvailable() {
1128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the root of the JSON hierarchy for about:memory jstemplate
1129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue root;
1130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue* browsers = new ListValue();
11313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  root.Set("browsers", browsers);
1132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const std::vector<ProcessData>& browser_processes = processes();
1134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Aggregate per-process data into browser summary data.
1136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::wstring log_string;
1137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t index = 0; index < browser_processes.size(); index++) {
1138dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    if (browser_processes[index].processes.empty())
1139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      continue;
1140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Sum the information for the processes within this browser.
1142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ProcessMemoryInformation aggregate;
1143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ProcessMemoryInformationList::const_iterator iterator;
1144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    iterator = browser_processes[index].processes.begin();
1145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    aggregate.pid = iterator->pid;
1146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    aggregate.version = iterator->version;
1147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    while (iterator != browser_processes[index].processes.end()) {
1148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (!iterator->is_diagnostics ||
1149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          browser_processes[index].processes.size() == 1) {
1150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        aggregate.working_set.priv += iterator->working_set.priv;
1151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        aggregate.working_set.shared += iterator->working_set.shared;
1152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        aggregate.working_set.shareable += iterator->working_set.shareable;
1153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        aggregate.committed.priv += iterator->committed.priv;
1154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        aggregate.committed.mapped += iterator->committed.mapped;
1155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        aggregate.committed.image += iterator->committed.image;
1156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        aggregate.num_processes++;
1157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
1158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ++iterator;
1159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* browser_data = new DictionaryValue();
1161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    browsers->Append(browser_data);
116221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    browser_data->SetString("name", browser_processes[index].name);
1163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    BindProcessMetrics(browser_data, &aggregate);
1165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We log memory info as we record it.
1167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (log_string.length() > 0)
1168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      log_string.append(L", ");
116921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    log_string.append(UTF16ToWide(browser_processes[index].name));
1170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    log_string.append(L", ");
11713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    log_string.append(UTF8ToWide(
11723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        base::Int64ToString(aggregate.working_set.priv)));
1173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    log_string.append(L", ");
11743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    log_string.append(UTF8ToWide(
11753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        base::Int64ToString(aggregate.working_set.shared)));
1176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    log_string.append(L", ");
11773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    log_string.append(UTF8ToWide(
11783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        base::Int64ToString(aggregate.working_set.shareable)));
1179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (log_string.length() > 0)
1181731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    VLOG(1) << "memory: " << log_string;
1182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Set the browser & renderer detailed process data.
1184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue* browser_data = new DictionaryValue();
11853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  root.Set("browzr_data", browser_data);
1186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue* child_data = new ListValue();
11873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  root.Set("child_data", child_data);
1188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ProcessData process = browser_processes[0];  // Chrome is the first browser.
119021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  root.SetString("current_browser_name", process.name);
1191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t index = 0; index < process.processes.size(); index++) {
1193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (process.processes[index].type == ChildProcessInfo::BROWSER_PROCESS)
1194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      BindProcessMetrics(browser_data, &process.processes[index]);
1195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    else
1196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      AppendProcess(child_data, &process.processes[index]);
1197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
11993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  root.SetBoolean("show_other_browsers",
1200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      browser_defaults::kShowOtherBrowsersInAboutMemory);
1201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Get about_memory.html
1203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const base::StringPiece memory_html(
1204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ResourceBundle::GetSharedInstance().GetRawDataResource(
1205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          IDR_ABOUT_MEMORY_HTML));
1206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Create jstemplate and return.
1208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string template_html = jstemplate_builder::GetTemplateHtml(
1209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      memory_html, &root, "t" /* template root node id */);
1210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  source_->FinishDataRequest(template_html, request_id_);
1212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
1215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ChromeOSAboutVersionHandler  -----------------------------------------------
1216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1217c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochChromeOSAboutVersionHandler::ChromeOSAboutVersionHandler(AboutSource* source,
1218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                         int request_id)
1219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : source_(source),
1220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      request_id_(request_id) {
1221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  loader_.EnablePlatformVersions(true);
1222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loader_.GetVersion(&consumer_,
1223201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                     NewCallback(this, &ChromeOSAboutVersionHandler::OnVersion),
1224201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                     chromeos::VersionLoader::VERSION_FULL);
1225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ChromeOSAboutVersionHandler::OnVersion(
1228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    chromeos::VersionLoader::Handle handle,
1229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string version) {
1230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue localized_strings;
12313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("os_name",
12323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                              l10n_util::GetStringUTF16(IDS_PRODUCT_OS_NAME));
12333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("os_version", version);
12343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetBoolean("is_chrome_os", true);
1235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  source_->FinishDataRequest(AboutVersion(&localized_strings), request_id_);
1236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // CancelableRequestProvider isn't happy when it's deleted and servicing a
1238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // task, so we delay the deletion.
1239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->DeleteSoon(FROM_HERE, this);
1240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
1243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns true if |url|'s spec starts with |about_specifier|, and is
1245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// terminated by the start of a path.
1246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool StartsWithAboutSpecifier(const GURL& url, const char* about_specifier) {
1247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return StartsWithASCII(url.spec(), about_specifier, true) &&
1248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         (url.spec().size() == strlen(about_specifier) ||
1249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          url.spec()[strlen(about_specifier)] == '/');
1250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Transforms a URL of the form "about:foo/XXX" to <url_prefix> + "XXX".
1253c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGURL RemapAboutURL(const std::string& url_prefix, const GURL& url) {
1254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string path;
1255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  size_t split = url.spec().find('/');
1256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (split != std::string::npos)
1257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    path = url.spec().substr(split + 1);
1258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return GURL(url_prefix + path);
1259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
1262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// -----------------------------------------------------------------------------
1264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool WillHandleBrowserAboutURL(GURL* url, Profile* profile) {
1266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We only handle about: schemes.
1267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!url->SchemeIs(chrome::kAboutScheme))
1268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
1269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // about:blank is special. Frames are allowed to access about:blank,
1271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // but they are not allowed to access other types of about pages.
1272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Just ignore the about:blank and let the TAB_CONTENTS_WEB handle it.
1273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (LowerCaseEqualsASCII(url->spec(), chrome::kAboutBlankURL))
1274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
1275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Rewrite about:cache/* URLs to chrome://view-http-cache/*
1277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (StartsWithAboutSpecifier(*url, chrome::kAboutCacheURL)) {
1278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *url = RemapAboutURL(chrome::kNetworkViewCacheURL, *url);
1279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
1280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1282513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#if defined(OS_WIN)
1283513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Rewrite about:conflicts/* URLs to chrome://conflicts/*
1284513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (StartsWithAboutSpecifier(*url, chrome::kAboutConflicts)) {
1285513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    *url = GURL(chrome::kChromeUIConflictsURL);
1286513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    return true;
1287513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  }
1288513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#endif
1289513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
1290dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Rewrite about:flags to chrome://flags/.
1291dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (LowerCaseEqualsASCII(url->spec(), chrome::kAboutFlagsURL)) {
1292731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    *url = GURL(chrome::kChromeUIFlagsURL);
1293731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return true;
12943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
12953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Rewrite about:net-internals/* URLs to chrome://net-internals/*
1297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (StartsWithAboutSpecifier(*url, chrome::kAboutNetInternalsURL)) {
1298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *url = RemapAboutURL(chrome::kNetworkViewInternalsURL, *url);
1299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
1300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
130221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Rewrite about:gpu/* URLs to chrome://gpu-internals/*
130321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (StartsWithAboutSpecifier(*url, chrome::kAboutGpuURL)) {
130421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    *url = RemapAboutURL(chrome::kGpuInternalsURL, *url);
130521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return true;
130621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
130721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
1308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Rewrite about:appcache-internals/* URLs to chrome://appcache/*
1309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (StartsWithAboutSpecifier(*url, chrome::kAboutAppCacheInternalsURL)) {
1310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *url = RemapAboutURL(chrome::kAppCacheViewInternalsURL, *url);
1311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
1312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
131472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Rewrite about:sync-internals/* URLs (and about:sync, too, for
131572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // legacy reasons) to chrome://sync-internals/*
131672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (StartsWithAboutSpecifier(*url, chrome::kAboutSyncInternalsURL) ||
131772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      StartsWithAboutSpecifier(*url, chrome::kAboutSyncURL)) {
131872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    *url = RemapAboutURL(chrome::kSyncViewInternalsURL, *url);
131972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return true;
132072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
132172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
1322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Rewrite about:plugins to chrome://plugins/.
1323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (LowerCaseEqualsASCII(url->spec(), chrome::kAboutPluginsURL)) {
1324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *url = GURL(chrome::kChromeUIPluginsURL);
1325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
1326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Handle URL to crash the browser process.
1329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (LowerCaseEqualsASCII(url->spec(), chrome::kAboutBrowserCrash)) {
1330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Induce an intentional crash in the browser process.
1331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int* bad_pointer = NULL;
1332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *bad_pointer = 42;
1333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
1334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
13363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Handle URLs to wreck the gpu process.
1337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (LowerCaseEqualsASCII(url->spec(), chrome::kAboutGpuCrashURL)) {
1338ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    GpuProcessHost::SendOnIO(
1339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        0, content::CAUSE_FOR_GPU_LAUNCH_ABOUT_GPUCRASH, new GpuMsg_Crash());
1340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
1341ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (LowerCaseEqualsASCII(url->spec(), chrome::kAboutGpuHangURL)) {
1342ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    GpuProcessHost::SendOnIO(
1343ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        0, content::CAUSE_FOR_GPU_LAUNCH_ABOUT_GPUHANG, new GpuMsg_Hang());
13443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
13453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // There are a few about: URLs that we hand over to the renderer. If the
1347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // renderer wants them, don't do any rewriting.
1348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (chrome_about_handler::WillHandle(*url))
1349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
1350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
13513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Anything else requires our special handler; make sure it's initialized.
135272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  InitializeAboutDataSource(profile);
1353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Special case about:memory to go through a redirect before ending up on
1355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the final page. See GetAboutMemoryRedirectResponse above for why.
1356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (LowerCaseEqualsASCII(url->path(), kMemoryPath)) {
1357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *url = GURL("chrome://about/memory-redirect");
1358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
1359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Rewrite the about URL to use chrome:. WebKit treats all about URLS the
1362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // same (blank page), so if we want to display content, we need another
1363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // scheme.
1364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string about_url = "chrome://about/";
1365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  about_url.append(url->path());
1366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  *url = GURL(about_url);
1367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
1368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
137072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid InitializeAboutDataSource(Profile* profile) {
137172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  profile->GetChromeURLDataManager()->AddDataSource(new AboutSource());
13723f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
13733f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This function gets called with the fixed-up chrome: URLs, so we have to
1375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// compare against those instead of "about:blah".
1376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool HandleNonNavigationAboutURL(const GURL& url) {
1377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // about:ipc is currently buggy, so we disable it for official builds.
1378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if !defined(OFFICIAL_BUILD)
1379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if (defined(OS_MACOSX) || defined(OS_WIN)) && defined(IPC_MESSAGE_LOG_ENABLED)
1381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (LowerCaseEqualsASCII(url.spec(), chrome::kChromeUIIPCURL)) {
1382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Run the dialog. This will re-use the existing one if it's already up.
138372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    browser::ShowAboutIPCDialog();
1384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
1385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
1387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // OFFICIAL_BUILD
1389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return false;
1391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1392dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1393dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstd::vector<std::string> AboutPaths() {
1394dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  std::vector<std::string> paths;
1395dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  paths.reserve(arraysize(kAllAboutPaths));
1396dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  for (size_t i = 0; i < arraysize(kAllAboutPaths); i++)
1397dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    paths.push_back(kAllAboutPaths[i]);
1398dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return paths;
1399dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
1400