browser_about_handler.cc revision c407dc5cd9bdc5668497f21b26b09d988ab439de
1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 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 "app/l10n_util.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "app/resource_bundle.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/callback.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_version_info.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/histogram.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/i18n/number_formatting.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/path_service.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/platform_thread.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/stats_table.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_piece.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/thread.h"
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/tracked_objects.h"
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser.h"
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser_process.h"
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chrome_thread.h"
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/defaults.h"
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/dom_ui/chrome_url_data_manager.h"
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/google_service_auth_error.h"
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/memory_details.h"
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/metrics/histogram_synchronizer.h"
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/net/predictor_api.h"
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/platform_util.h"
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/pref_service.h"
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/profile.h"
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/profile_manager.h"
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/renderer_host/render_process_host.h"
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/renderer_host/render_view_host.h"
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/profile_sync_service.h"
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/about_handler.h"
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_paths.h"
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_version_info.h"
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/jstemplate_builder.h"
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/pref_names.h"
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/render_messages.h"
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/url_constants.h"
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "googleurl/src/gurl.h"
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/browser_resources.h"
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/chromium_strings.h"
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h"
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/locale_settings.h"
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/webkit_glue.h"
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifdef CHROME_V8
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "v8/include/v8.h"
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/views/about_ipc_dialog.h"
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_CHROMEOS)
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/cros/cros_library.h"
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/cros/network_library.h"
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/cros/syslogs_library.h"
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/version_loader.h"
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/zygote_host_linux.h"
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_MACOSX)
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/cocoa/about_ipc_dialog.h"
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_LINUX)
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/zygote_host_linux.h"
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(USE_TCMALLOC)
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "third_party/tcmalloc/chromium/src/google/malloc_extension.h"
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing sync_api::SyncManager;
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::Time;
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::TimeDelta;
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(USE_TCMALLOC)
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Glue between the callback task and the method in the singleton.
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AboutTcmallocRendererCallback(base::ProcessId pid, std::string output) {
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Singleton<AboutTcmallocOutputs>::get()->RendererCallback(pid, output);
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The (alphabetized) paths used for the about pages.
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Note: Keep these in sync with url_constants.h
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kAppCacheInternalsPath[] = "appcache-internals";
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kCreditsPath[] = "credits";
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kCachePath[] = "view-http-cache";
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kDnsPath[] = "dns";
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kHistogramsPath[] = "histograms";
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kMemoryRedirectPath[] = "memory-redirect";
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kMemoryPath[] = "memory";
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kStatsPath[] = "stats";
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kSyncPath[] = "sync";
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kTasksPath[] = "tasks";
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kTcmallocPath[] = "tcmalloc";
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kTermsPath[] = "terms";
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kVersionPath[] = "version";
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kAboutPath[] = "about";
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Not about:* pages, but included to make about:about look nicer
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kNetInternalsPath[] = "net-internals";
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kPluginsPath[] = "plugins";
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_LINUX)
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kLinuxProxyConfigPath[] = "linux-proxy-config";
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kSandboxPath[] = "sandbox";
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kNetworkPath[] = "network";
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kOSCreditsPath[] = "os-credits";
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kSysPath[] = "system";
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Add path here to be included in about:about
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char *kAllAboutPaths[] = {
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kAppCacheInternalsPath,
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kCachePath,
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kCreditsPath,
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kDnsPath,
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kHistogramsPath,
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kMemoryPath,
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kNetInternalsPath,
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kPluginsPath,
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kStatsPath,
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kSyncPath,
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kTasksPath,
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kTcmallocPath,
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kTermsPath,
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kVersionPath,
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_LINUX)
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kLinuxProxyConfigPath,
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kSandboxPath,
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kNetworkPath,
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kOSCreditsPath,
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  kSysPath,
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Points to the singleton AboutSource object, if any.
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochChromeURLDataManager::DataSource* about_source = NULL;
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// When you type about:memory, it actually loads an intermediate URL that
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// redirects you to the final page. This avoids the problem where typing
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// "about:memory" on the new tab page or any other page where a process
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// transition would occur to the about URL will cause some confusion.
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The problem is that during the processing of the memory page, there are two
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// processes active, the original and the destination one. This can create the
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// impression that we're using more resources than we actually are. This
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// redirect solves the problem by eliminating the process transition during the
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// time that about memory is being computed.
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string GetAboutMemoryRedirectResponse() {
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return "<meta http-equiv=\"refresh\" "
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "content=\"0;chrome://about/memory\">";
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass AboutSource : public ChromeURLDataManager::DataSource {
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Creates our datasource.
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AboutSource();
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Called when the network layer has requested a resource underneath
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the path we registered.
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void StartDataRequest(const std::string& path,
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                bool is_off_the_record,
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                int request_id);
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual std::string GetMimeType(const std::string&) const {
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return "text/html";
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Send the response data.
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void FinishDataRequest(const std::string& html, int request_id);
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~AboutSource();
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(AboutSource);
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Handling about:memory is complicated enough to encapsulate its related
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// methods into a single class. The user should create it (on the heap) and call
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// its |StartFetch()| method.
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass AboutMemoryHandler : public MemoryDetails {
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AboutMemoryHandler(AboutSource* source, int request_id)
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : source_(source), request_id_(request_id) {}
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnDetailsAvailable();
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ~AboutMemoryHandler() {}
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void BindProcessMetrics(DictionaryValue* data,
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          ProcessMemoryInformation* info);
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void AppendProcess(ListValue* child_data, ProcessMemoryInformation* info);
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<AboutSource> source_;
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int request_id_;
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(AboutMemoryHandler);
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ChromeOSAboutVersionHandler is responsible for loading the Chrome OS
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// version.
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ChromeOSAboutVersionHandler handles deleting itself once the version has
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// been obtained and AboutSource notified.
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ChromeOSAboutVersionHandler {
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ChromeOSAboutVersionHandler(AboutSource* source, int request_id);
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Callback from chromeos::VersionLoader giving the version.
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void OnVersion(chromeos::VersionLoader::Handle handle,
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 std::string version);
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Where the results are fed to.
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<AboutSource> source_;
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ID identifying the request.
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int request_id_;
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Handles asynchronously loading the version.
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  chromeos::VersionLoader loader_;
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Used to request the version.
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CancelableRequestConsumer consumer_;
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(ChromeOSAboutVersionHandler);
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Individual about handlers ---------------------------------------------------
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string AboutAbout() {
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string html;
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  html.append("<html><head><title>About Pages</title></head><body>\n");
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  html.append("<h2>List of About pages</h2><ul>\n");
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < arraysize(kAllAboutPaths); i++) {
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (kAllAboutPaths[i] == kNetInternalsPath ||
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        kAllAboutPaths[i] == kPluginsPath ||
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        kAllAboutPaths[i] == kCachePath ||
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        kAllAboutPaths[i] == kAppCacheInternalsPath)
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      html.append("<li><a href='chrome://");
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    else
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      html.append("<li><a href='chrome://about/");
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    html.append(kAllAboutPaths[i]);
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    html.append("/'>about:");
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    html.append(kAllAboutPaths[i]);
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    html.append("</a>\n");
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const char *debug[] = { "crash", "hang", "shorthang" };
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  html.append("</ul><h2>For Debug</h2>");
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  html.append("</ul><p>The following pages are for debugging purposes only. "
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              "Because they crash or hang the renderer, they're not linked "
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              "directly; you can type them into the address bar if you need "
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              "them.</p><ul>");
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < arraysize(debug); i++) {
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    html.append("<li>");
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    html.append("about:");
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    html.append(debug[i]);
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    html.append("\n");
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  html.append("</ul></body></html>");
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return html;
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string AboutNetwork(const std::string& query) {
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int refresh;
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  StringToInt(query, &refresh);
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return chromeos::CrosLibrary::Get()->GetNetworkLibrary()->
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GetHtmlInfo(refresh);
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// AboutDnsHandler bounces the request back to the IO thread to collect
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the DNS information.
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass AboutDnsHandler : public base::RefCountedThreadSafe<AboutDnsHandler> {
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static void Start(AboutSource* source, int request_id) {
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    scoped_refptr<AboutDnsHandler> handler =
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        new AboutDnsHandler(source, request_id);
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    handler->StartOnUIThread();
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AboutDnsHandler(AboutSource* source, int request_id)
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : source_(source),
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        request_id_(request_id) {
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Calls FinishOnUIThread() on completion.
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void StartOnUIThread() {
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ChromeThread::PostTask(
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ChromeThread::IO, FROM_HERE,
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NewRunnableMethod(this, &AboutDnsHandler::StartOnIOThread));
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void StartOnIOThread() {
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string data;
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    chrome_browser_net::PredictorGetHtmlInfo(&data);
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ChromeThread::PostTask(
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ChromeThread::UI, FROM_HERE,
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NewRunnableMethod(this, &AboutDnsHandler::FinishOnUIThread, data));
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void FinishOnUIThread(const std::string& data) {
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    source_->FinishDataRequest(data, request_id_);
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Where the results are fed to.
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<AboutSource> source_;
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ID identifying the request.
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int request_id_;
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(AboutDnsHandler);
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(USE_TCMALLOC)
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string AboutTcmalloc(const std::string& query) {
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string data;
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AboutTcmallocOutputsType* outputs =
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Singleton<AboutTcmallocOutputs>::get()->outputs();
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Display any stats for which we sent off requests the last time.
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("<html><head><title>About tcmalloc</title></head><body>\n");
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("<p>Stats as of last page load;");
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("reload to get stats as of this page load.</p>\n");
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("<table width=\"100%\">\n");
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (AboutTcmallocOutputsType::const_iterator oit = outputs->begin();
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       oit != outputs->end();
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       oit++) {
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data.append("<tr><td bgcolor=\"yellow\">");
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data.append(oit->first);
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data.append("</td></tr>\n");
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data.append("<tr><td><pre>\n");
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data.append(oit->second);
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data.append("</pre></td></tr>\n");
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("</table>\n");
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("</body></html>\n");
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Reset our collector singleton.
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  outputs->clear();
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Populate the collector with stats from the local browser process
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // and send off requests to all the renderer processes.
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  char buffer[1024 * 32];
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MallocExtension::instance()->GetStats(buffer, sizeof(buffer));
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string browser("Browser");
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Singleton<AboutTcmallocOutputs>::get()->SetOutput(browser, buffer);
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  while (!it.IsAtEnd()) {
372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    it.GetCurrentValue()->Send(new ViewMsg_GetRendererTcmalloc);
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    it.Advance();
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return data;
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string AboutHistograms(const std::string& query) {
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TimeDelta wait_time = TimeDelta::FromMilliseconds(10000);
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HistogramSynchronizer* current_synchronizer =
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      HistogramSynchronizer::CurrentSynchronizer();
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(current_synchronizer != NULL);
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  current_synchronizer->FetchRendererHistogramsSynchronously(wait_time);
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string data;
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  StatisticsRecorder::WriteHTMLGraph(query, &data);
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return data;
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AboutMemory(AboutSource* source, int request_id) {
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The AboutMemoryHandler cleans itself up, but |StartFetch()| will want the
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // refcount to be greater than 0.
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<AboutMemoryHandler>
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      handler(new AboutMemoryHandler(source, request_id));
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  handler->StartFetch();
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifdef TRACK_ALL_TASK_OBJECTS
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic std::string AboutObjects(const std::string& query) {
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string data;
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tracked_objects::ThreadData::WriteHTML(query, &data);
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return data;
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // TRACK_ALL_TASK_OBJECTS
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string AboutStats() {
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We keep the DictionaryValue tree live so that we can do delta
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // stats computations across runs.
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static DictionaryValue root;
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  StatsTable* table = StatsTable::current();
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!table)
416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return std::string();
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We maintain two lists - one for counters and one for timers.
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Timers actually get stored on both lists.
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue* counters;
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!root.GetList(L"counters", &counters)) {
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    counters = new ListValue();
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    root.Set(L"counters", counters);
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue* timers;
427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!root.GetList(L"timers", &timers)) {
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    timers = new ListValue();
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    root.Set(L"timers", timers);
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // NOTE: Counters start at index 1.
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int index = 1; index <= table->GetMaxCounters(); index++) {
434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Get the counter's full name
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string full_name = table->GetRowName(index);
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (full_name.length() == 0)
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK_EQ(':', full_name[1]);
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    char counter_type = full_name[0];
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string name = full_name.substr(2);
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // JSON doesn't allow '.' in names.
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    size_t pos;
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    while ((pos = name.find(".")) != std::string::npos)
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      name.replace(pos, 1, ":");
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Try to see if this name already exists.
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* counter = NULL;
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t scan_index = 0;
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         scan_index < counters->GetSize(); scan_index++) {
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DictionaryValue* dictionary;
452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (counters->GetDictionary(scan_index, &dictionary)) {
453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        std::wstring scan_name;
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        if (dictionary->GetString(L"name", &scan_name) &&
455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            WideToASCII(scan_name) == name) {
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          counter = dictionary;
457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      } else {
459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NOTREACHED();  // Should always be there
460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (counter == NULL) {
464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      counter = new DictionaryValue();
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      counter->SetString(L"name", ASCIIToWide(name));
466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      counters->Append(counter);
467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    switch (counter_type) {
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case 'c':
471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        {
472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          int new_value = table->GetRowValue(index);
473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          int prior_value = 0;
474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          int delta = 0;
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          if (counter->GetInteger(L"value", &prior_value)) {
476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            delta = new_value - prior_value;
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          }
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          counter->SetInteger(L"value", new_value);
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          counter->SetInteger(L"delta", delta);
480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case 'm':
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        {
484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          // TODO(mbelshe): implement me.
485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case 't':
488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        {
489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          int time = table->GetRowValue(index);
490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          counter->SetInteger(L"time", time);
491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          // Store this on the timers list as well.
493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          timers->Append(counter);
494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      default:
497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NOTREACHED();
498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Get about_stats.html
502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const base::StringPiece stats_html(
503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ResourceBundle::GetSharedInstance().GetRawDataResource(
504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          IDR_ABOUT_STATS_HTML));
505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Create jstemplate and return.
507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string data = jstemplate_builder::GetTemplateHtml(
508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      stats_html, &root, "t" /* template root node id */);
509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Clear the timer list since we stored the data in the timers list as well.
511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int index = static_cast<int>(timers->GetSize())-1; index >= 0;
512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       index--) {
513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Value* value;
514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    timers->Remove(index, &value);
515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We don't care about the value pointer; it's still tracked
516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // on the counters list.
517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return data;
520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_LINUX)
523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string AboutLinuxProxyConfig() {
524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string data;
525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("<!DOCTYPE HTML>\n");
526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("<html><head><meta charset=\"utf-8\"><title>");
527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append(l10n_util::GetStringUTF8(IDS_ABOUT_LINUX_PROXY_CONFIG_TITLE));
528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("</title>");
529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("<style>body { max-width: 70ex; padding: 2ex 5ex; }</style>");
530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("</head><body>\n");
531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath binary = CommandLine::ForCurrentProcess()->GetProgram();
532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append(l10n_util::GetStringFUTF8(
533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  IDS_ABOUT_LINUX_PROXY_CONFIG_BODY,
534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  ASCIIToUTF16(binary.BaseName().value())));
536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("</body></html>\n");
537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return data;
538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AboutSandboxRow(std::string* data, const std::string& prefix, int name_id,
541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                     bool good) {
542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data->append("<tr><td>");
543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data->append(prefix);
544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data->append(l10n_util::GetStringUTF8(name_id));
545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (good) {
546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data->append("</td><td style=\"color: green;\">");
547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data->append(
548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        l10n_util::GetStringUTF8(IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL));
549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data->append("</td><td style=\"color: red;\">");
551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data->append(
552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        l10n_util::GetStringUTF8(IDS_CONFIRM_MESSAGEBOX_NO_BUTTON_LABEL));
553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data->append("</td></tr>");
555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string AboutSandbox() {
558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string data;
559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("<!DOCTYPE HTML>\n");
560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("<html><head><meta charset=\"utf-8\"><title>");
561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append(l10n_util::GetStringUTF8(IDS_ABOUT_SANDBOX_TITLE));
562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("</title>");
563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("</head><body>\n");
564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("<h1>");
565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append(l10n_util::GetStringUTF8(IDS_ABOUT_SANDBOX_TITLE));
566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("</h1>");
567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const int status = Singleton<ZygoteHost>()->sandbox_status();
569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("<table>");
571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AboutSandboxRow(&data, "", IDS_ABOUT_SANDBOX_SUID_SANDBOX,
573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  status & ZygoteHost::kSandboxSUID);
574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (status & ZygoteHost::kSandboxPIDNS) {
575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AboutSandboxRow(&data, "&nbsp;&nbsp;", IDS_ABOUT_SANDBOX_PID_NAMESPACES,
576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    status & ZygoteHost::kSandboxPIDNS);
577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AboutSandboxRow(&data, "&nbsp;&nbsp;", IDS_ABOUT_SANDBOX_NET_NAMESPACES,
578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    status & ZygoteHost::kSandboxNetNS);
579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AboutSandboxRow(&data, "", IDS_ABOUT_SANDBOX_SECCOMP_SANDBOX,
581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  status & ZygoteHost::kSandboxSeccomp);
582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("</table>");
584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool good = ((status & ZygoteHost::kSandboxSUID) &&
586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch               (status & ZygoteHost::kSandboxPIDNS)) ||
587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              (status & ZygoteHost::kSandboxSeccomp);
588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (good) {
589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data.append("<p style=\"color: green\">");
590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data.append(l10n_util::GetStringUTF8(IDS_ABOUT_SANDBOX_OK));
591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data.append("<p style=\"color: red\">");
593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data.append(l10n_util::GetStringUTF8(IDS_ABOUT_SANDBOX_BAD));
594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("</p>");
596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.append("</body></html>\n");
598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return data;
599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string AboutVersion(DictionaryValue* localized_strings) {
603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings->SetString(L"title",
604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_ABOUT_VERSION_TITLE));
605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<FileVersionInfo> version_info(chrome::GetChromeVersionInfo());
606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (version_info == NULL) {
607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DLOG(ERROR) << "Unable to create FileVersionInfo object";
608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return std::string();
609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string webkit_version = webkit_glue::GetWebKitVersion();
612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifdef CHROME_V8
613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string js_version(v8::V8::GetVersion());
614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string js_engine = "V8";
615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else
616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string js_version = webkit_version;
617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string js_engine = "JavaScriptCore";
618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings->SetString(L"name",
621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_PRODUCT_NAME));
622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings->SetString(L"version", version_info->file_version());
623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::wstring mod = UTF16ToWide(platform_util::GetVersionStringModifier());
624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings->SetString(L"version_modifier", mod);
625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings->SetString(L"js_engine", js_engine);
626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings->SetString(L"js_version", js_version);
627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings->SetString(L"webkit_version", webkit_version);
628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings->SetString(L"company",
629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_ABOUT_VERSION_COMPANY_NAME));
630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings->SetString(L"copyright",
631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_ABOUT_VERSION_COPYRIGHT));
632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings->SetString(L"cl", version_info->last_change());
633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (version_info->is_official_build()) {
634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    localized_strings->SetString(L"official",
635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_ABOUT_VERSION_OFFICIAL));
636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    localized_strings->SetString(L"official",
638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_ABOUT_VERSION_UNOFFICIAL));
639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings->SetString(L"user_agent_name",
641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_ABOUT_VERSION_USER_AGENT));
642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings->SetString(L"useragent", webkit_glue::GetUserAgent(GURL()));
643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings->SetString(L"command_line_name",
644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_ABOUT_VERSION_COMMAND_LINE));
645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings->SetString(L"command_line",
648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      CommandLine::ForCurrentProcess()->command_line_string());
649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_POSIX)
650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string command_line = "";
651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef std::vector<std::string> ArgvList;
652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const ArgvList& argv = CommandLine::ForCurrentProcess()->argv();
653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (ArgvList::const_iterator iter = argv.begin(); iter != argv.end(); iter++)
654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    command_line += " " + *iter;
655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings->SetString(L"command_line", command_line);
656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::StringPiece version_html(
659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ResourceBundle::GetSharedInstance().GetRawDataResource(
660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          IDR_ABOUT_VERSION_HTML));
661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return jstemplate_builder::GetTemplatesHtml(
663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      version_html, localized_strings, "t" /* template root node id */);
664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void AddBoolSyncDetail(ListValue* details, const std::wstring& stat_name,
667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              bool stat_value) {
668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue* val = new DictionaryValue;
669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  val->SetString(L"stat_name", stat_name);
670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  val->SetBoolean(L"stat_value", stat_value);
671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  details->Append(val);
672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void AddIntSyncDetail(ListValue* details, const std::wstring& stat_name,
675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             int64 stat_value) {
676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue* val = new DictionaryValue;
677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  val->SetString(L"stat_name", stat_name);
678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  val->SetString(L"stat_value", UTF16ToWide(base::FormatNumber(stat_value)));
679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  details->Append(val);
680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic std::wstring MakeSyncAuthErrorText(
683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const GoogleServiceAuthError::State& state) {
684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (state) {
685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS:
686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return L"INVALID_GAIA_CREDENTIALS";
687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case GoogleServiceAuthError::USER_NOT_SIGNED_UP:
688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return L"USER_NOT_SIGNED_UP";
689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case GoogleServiceAuthError::CONNECTION_FAILED:
690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return L"CONNECTION_FAILED";
691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    default:
692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return std::wstring();
693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string AboutSync() {
697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath user_data_dir;
698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!PathService::Get(chrome::DIR_USER_DATA, &user_data_dir))
699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return std::string();
700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ProfileManager* profile_manager = g_browser_process->profile_manager();
701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Profile* profile = profile_manager->GetDefaultProfile(user_data_dir);
702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ProfileSyncService* service = profile->GetProfileSyncService();
703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue strings;
705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!service || !service->HasSyncSetupCompleted()) {
706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    strings.SetString(L"summary", L"SYNC DISABLED");
707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SyncManager::Status full_status(service->QueryDetailedSyncStatus());
709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    strings.SetString(L"summary",
711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ProfileSyncService::BuildSyncStatusSummaryText(
712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            full_status.summary));
713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    strings.Set(L"authenticated",
715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        new FundamentalValue(full_status.authenticated));
716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    strings.SetString(L"auth_problem",
717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        MakeSyncAuthErrorText(service->GetAuthError().state()));
718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    strings.SetString(L"time_since_sync", service->GetLastSyncedTimeString());
720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ListValue* details = new ListValue();
722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    strings.Set(L"details", details);
723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddBoolSyncDetail(details, L"Server Up", full_status.server_up);
724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddBoolSyncDetail(details, L"Server Reachable",
725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      full_status.server_reachable);
726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddBoolSyncDetail(details, L"Server Broken", full_status.server_broken);
727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddBoolSyncDetail(details, L"Notifications Enabled",
728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      full_status.notifications_enabled);
729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddIntSyncDetail(details, L"Notifications Received",
730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                     full_status.notifications_received);
731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddIntSyncDetail(details, L"Notifications Sent",
732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                     full_status.notifications_sent);
733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddIntSyncDetail(details, L"Unsynced Count", full_status.unsynced_count);
734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddIntSyncDetail(details, L"Conflicting Count",
735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                     full_status.conflicting_count);
736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddBoolSyncDetail(details, L"Syncing", full_status.syncing);
737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddBoolSyncDetail(details, L"Initial Sync Ended",
738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      full_status.initial_sync_ended);
739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddBoolSyncDetail(details, L"Syncer Stuck", full_status.syncer_stuck);
740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddIntSyncDetail(details, L"Updates Available",
741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                     full_status.updates_available);
742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddIntSyncDetail(details, L"Updates Received",
743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                     full_status.updates_received);
744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddBoolSyncDetail(details, L"Disk Full", full_status.disk_full);
745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddBoolSyncDetail(details, L"Invalid Store", full_status.invalid_store);
746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddIntSyncDetail(details, L"Max Consecutive Errors",
747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                     full_status.max_consecutive_errors);
748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (service->unrecoverable_error_detected()) {
750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      strings.Set(L"unrecoverable_error_detected", new FundamentalValue(true));
751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      strings.SetString(L"unrecoverable_error_message",
752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        service->unrecoverable_error_message());
753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tracked_objects::Location loc(service->unrecoverable_error_location());
754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      std::string location_str;
755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      loc.Write(true, true, &location_str);
756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      strings.SetString(L"unrecoverable_error_location", location_str);
757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    browser_sync::ModelSafeRoutingInfo routes;
760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    service->backend()->GetModelSafeRoutingInfo(&routes);
761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ListValue* routing_info = new ListValue();
762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    strings.Set(L"routing_info", routing_info);
763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    browser_sync::ModelSafeRoutingInfo::const_iterator it = routes.begin();
764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (; it != routes.end(); ++it) {
765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DictionaryValue* val = new DictionaryValue;
766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      val->SetString(L"model_type", ModelTypeToString(it->first));
767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      val->SetString(L"group", ModelSafeGroupToString(it->second));
768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      routing_info->Append(val);
769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const base::StringPiece sync_html(
773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ResourceBundle::GetSharedInstance().GetRawDataResource(
774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      IDR_ABOUT_SYNC_HTML));
775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return jstemplate_builder::GetTemplateHtml(
777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      sync_html, &strings , "t" /* template root node id */);
778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string AboutSys() {
782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue strings;
783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  chromeos::SyslogsLibrary* syslogs_lib =
784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      chromeos::CrosLibrary::Get()->GetSyslogsLibrary();
785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<chromeos::LogDictionaryType> sys_info_;
786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (syslogs_lib)
787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    sys_info_.reset(syslogs_lib->GetSyslogs(new FilePath()));
788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (sys_info_.get()) {
789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch     ListValue* details = new ListValue();
790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch     strings.Set(L"details", details);
791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch     chromeos::LogDictionaryType::iterator it;
792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch     for (it = sys_info_.get()->begin(); it != sys_info_.get()->end(); ++it) {
794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       DictionaryValue* val = new DictionaryValue;
795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       val->SetString(L"stat_name", (*it).first);
796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       val->SetString(L"stat_value", (*it).second);
797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       details->Append(val);
798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch     }
799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const base::StringPiece sys_html(
801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ResourceBundle::GetSharedInstance().GetRawDataResource(
802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        IDR_ABOUT_SYS_HTML));
803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return jstemplate_builder::GetTemplateHtml(
805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        sys_html, &strings , "t" /* template root node id */);
806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// AboutSource -----------------------------------------------------------------
810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
811c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochAboutSource::AboutSource()
812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : DataSource(chrome::kAboutScheme, MessageLoop::current()) {
813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This should be a singleton.
814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(!about_source);
815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  about_source = this;
816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add us to the global URL handler on the IO thread.
818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ChromeThread::PostTask(
819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ChromeThread::IO, FROM_HERE,
820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewRunnableMethod(
821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          Singleton<ChromeURLDataManager>::get(),
822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          &ChromeURLDataManager::AddDataSource,
823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          make_scoped_refptr(this)));
824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
826c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochAboutSource::~AboutSource() {
827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  about_source = NULL;
828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AboutSource::StartDataRequest(const std::string& path_raw,
831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool is_off_the_record, int request_id) {
832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string path = path_raw;
833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string info;
834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (path.find("/") != std::string::npos) {
835c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    size_t pos = path.find("/");
836c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    info = path.substr(pos + 1, path.length() - (pos + 1));
837c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    path = path.substr(0, pos);
838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  path = StringToLowerASCII(path);
840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string response;
842c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (path == kDnsPath) {
843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AboutDnsHandler::Start(this, request_id);
844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kHistogramsPath) {
846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response = AboutHistograms(info);
847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kMemoryPath) {
848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AboutMemory(this, request_id);
849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kMemoryRedirectPath) {
851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response = GetAboutMemoryRedirectResponse();
852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifdef TRACK_ALL_TASK_OBJECTS
853c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kTasksPath) {
854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response = AboutObjects(info);
855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kStatsPath) {
857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response = AboutStats();
858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(USE_TCMALLOC)
859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kTcmallocPath) {
860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response = AboutTcmalloc(info);
861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kVersionPath || path.empty()) {
863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    new ChromeOSAboutVersionHandler(this, request_id);
865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else
867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue value;
868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response = AboutVersion(&value);
869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kCreditsPath) {
871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response = ResourceBundle::GetSharedInstance().GetRawDataResource(
872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        IDR_CREDITS_HTML).as_string();
873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kAboutPath) {
874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response = AboutAbout();
875c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kOSCreditsPath) {
877c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response = ResourceBundle::GetSharedInstance().GetRawDataResource(
878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        IDR_OS_CREDITS_HTML).as_string();
879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kNetworkPath) {
880c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response = AboutNetwork(info);
881c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kTermsPath) {
883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response = ResourceBundle::GetSharedInstance().GetRawDataResource(
884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        IDR_TERMS_HTML).as_string();
885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_LINUX)
886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kLinuxProxyConfigPath) {
887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response = AboutLinuxProxyConfig();
888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kSandboxPath) {
889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response = AboutSandbox();
890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kSyncPath) {
892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response = AboutSync();
893c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (path == kSysPath) {
895c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response = AboutSys();
896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FinishDataRequest(response, request_id);
900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AboutSource::FinishDataRequest(const std::string& response,
903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    int request_id) {
904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  html_bytes->data.resize(response.size());
906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::copy(response.begin(), response.end(), html_bytes->data.begin());
907c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SendResponse(request_id, html_bytes);
908c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
910c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// AboutMemoryHandler ----------------------------------------------------------
911c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
912c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Helper for AboutMemory to bind results from a ProcessMetrics object
913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// to a DictionaryValue. Fills ws_usage and comm_usage so that the objects
914c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// can be used in caller's scope (e.g for appending to a net total).
915c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AboutMemoryHandler::BindProcessMetrics(DictionaryValue* data,
916c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                            ProcessMemoryInformation* info) {
917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(data && info);
918c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Bind metrics to dictionary.
920c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data->SetInteger(L"ws_priv", static_cast<int>(info->working_set.priv));
921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data->SetInteger(L"ws_shareable",
922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    static_cast<int>(info->working_set.shareable));
923c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data->SetInteger(L"ws_shared", static_cast<int>(info->working_set.shared));
924c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data->SetInteger(L"comm_priv", static_cast<int>(info->committed.priv));
925c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data->SetInteger(L"comm_map", static_cast<int>(info->committed.mapped));
926c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data->SetInteger(L"comm_image", static_cast<int>(info->committed.image));
927c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data->SetInteger(L"pid", info->pid);
928c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data->SetString(L"version", info->version);
929c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data->SetInteger(L"processes", info->num_processes);
930c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
931c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
932c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Helper for AboutMemory to append memory usage information for all
933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// sub-processes (i.e. renderers, plugins) used by Chrome.
934c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AboutMemoryHandler::AppendProcess(ListValue* child_data,
935c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       ProcessMemoryInformation* info) {
936c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(child_data && info);
937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Append a new DictionaryValue for this renderer to our list.
939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue* child = new DictionaryValue();
940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  child_data->Append(child);
941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BindProcessMetrics(child, info);
942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::wstring child_label(ChildProcessInfo::GetTypeNameInEnglish(info->type));
944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (info->is_diagnostics)
945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    child_label.append(L" (diagnostics)");
946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  child->SetString(L"child_name", child_label);
947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue* titles = new ListValue();
948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  child->Set(L"titles", titles);
949c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < info->titles.size(); ++i)
950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    titles->Append(new StringValue(info->titles[i]));
951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
952c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AboutMemoryHandler::OnDetailsAvailable() {
955c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the root of the JSON hierarchy for about:memory jstemplate
956c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue root;
957c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue* browsers = new ListValue();
958c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  root.Set(L"browsers", browsers);
959c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
960c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const std::vector<ProcessData>& browser_processes = processes();
961c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
962c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Aggregate per-process data into browser summary data.
963c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::wstring log_string;
964c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t index = 0; index < browser_processes.size(); index++) {
965c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (browser_processes[index].processes.size() == 0)
966c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      continue;
967c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Sum the information for the processes within this browser.
969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ProcessMemoryInformation aggregate;
970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ProcessMemoryInformationList::const_iterator iterator;
971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    iterator = browser_processes[index].processes.begin();
972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    aggregate.pid = iterator->pid;
973c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    aggregate.version = iterator->version;
974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    while (iterator != browser_processes[index].processes.end()) {
975c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (!iterator->is_diagnostics ||
976c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          browser_processes[index].processes.size() == 1) {
977c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        aggregate.working_set.priv += iterator->working_set.priv;
978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        aggregate.working_set.shared += iterator->working_set.shared;
979c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        aggregate.working_set.shareable += iterator->working_set.shareable;
980c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        aggregate.committed.priv += iterator->committed.priv;
981c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        aggregate.committed.mapped += iterator->committed.mapped;
982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        aggregate.committed.image += iterator->committed.image;
983c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        aggregate.num_processes++;
984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
985c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ++iterator;
986c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
987c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* browser_data = new DictionaryValue();
988c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    browsers->Append(browser_data);
989c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    browser_data->SetString(L"name", browser_processes[index].name);
990c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
991c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    BindProcessMetrics(browser_data, &aggregate);
992c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
993c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We log memory info as we record it.
994c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (log_string.length() > 0)
995c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      log_string.append(L", ");
996c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    log_string.append(browser_processes[index].name);
997c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    log_string.append(L", ");
998c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    log_string.append(Int64ToWString(aggregate.working_set.priv));
999c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    log_string.append(L", ");
1000c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    log_string.append(Int64ToWString(aggregate.working_set.shared));
1001c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    log_string.append(L", ");
1002c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    log_string.append(Int64ToWString(aggregate.working_set.shareable));
1003c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1004c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (log_string.length() > 0)
1005c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    LOG(INFO) << "memory: " << log_string;
1006c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1007c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Set the browser & renderer detailed process data.
1008c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue* browser_data = new DictionaryValue();
1009c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  root.Set(L"browzr_data", browser_data);
1010c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue* child_data = new ListValue();
1011c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  root.Set(L"child_data", child_data);
1012c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1013c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ProcessData process = browser_processes[0];  // Chrome is the first browser.
1014c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  root.SetString(L"current_browser_name", process.name);
1015c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1016c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t index = 0; index < process.processes.size(); index++) {
1017c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (process.processes[index].type == ChildProcessInfo::BROWSER_PROCESS)
1018c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      BindProcessMetrics(browser_data, &process.processes[index]);
1019c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    else
1020c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      AppendProcess(child_data, &process.processes[index]);
1021c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1022c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1023c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  root.SetBoolean(L"show_other_browsers",
1024c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      browser_defaults::kShowOtherBrowsersInAboutMemory);
1025c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1026c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Get about_memory.html
1027c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const base::StringPiece memory_html(
1028c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ResourceBundle::GetSharedInstance().GetRawDataResource(
1029c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          IDR_ABOUT_MEMORY_HTML));
1030c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1031c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Create jstemplate and return.
1032c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string template_html = jstemplate_builder::GetTemplateHtml(
1033c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      memory_html, &root, "t" /* template root node id */);
1034c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1035c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  source_->FinishDataRequest(template_html, request_id_);
1036c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1037c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1038c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
1039c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ChromeOSAboutVersionHandler  -----------------------------------------------
1040c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1041c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochChromeOSAboutVersionHandler::ChromeOSAboutVersionHandler(AboutSource* source,
1042c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                         int request_id)
1043c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : source_(source),
1044c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      request_id_(request_id) {
1045c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loader_.GetVersion(&consumer_,
1046c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &ChromeOSAboutVersionHandler::OnVersion));
1047c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1048c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1049c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ChromeOSAboutVersionHandler::OnVersion(
1050c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    chromeos::VersionLoader::Handle handle,
1051c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string version) {
1052c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue localized_strings;
1053c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"os_name",
1054c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              l10n_util::GetString(IDS_PRODUCT_OS_NAME));
1055c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"os_version", UTF8ToWide(version));
1056c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetBoolean(L"is_chrome_os", true);
1057c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  source_->FinishDataRequest(AboutVersion(&localized_strings), request_id_);
1058c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1059c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // CancelableRequestProvider isn't happy when it's deleted and servicing a
1060c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // task, so we delay the deletion.
1061c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->DeleteSoon(FROM_HERE, this);
1062c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1063c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1064c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
1065c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1066c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns true if |url|'s spec starts with |about_specifier|, and is
1067c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// terminated by the start of a path.
1068c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool StartsWithAboutSpecifier(const GURL& url, const char* about_specifier) {
1069c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return StartsWithASCII(url.spec(), about_specifier, true) &&
1070c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         (url.spec().size() == strlen(about_specifier) ||
1071c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          url.spec()[strlen(about_specifier)] == '/');
1072c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1073c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1074c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Transforms a URL of the form "about:foo/XXX" to <url_prefix> + "XXX".
1075c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGURL RemapAboutURL(const std::string& url_prefix, const GURL& url) {
1076c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string path;
1077c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  size_t split = url.spec().find('/');
1078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (split != std::string::npos)
1079c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    path = url.spec().substr(split + 1);
1080c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return GURL(url_prefix + path);
1081c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1082c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1083c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
1084c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1085c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// -----------------------------------------------------------------------------
1086c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1087c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool WillHandleBrowserAboutURL(GURL* url, Profile* profile) {
1088c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We only handle about: schemes.
1089c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!url->SchemeIs(chrome::kAboutScheme))
1090c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
1091c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1092c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // about:blank is special. Frames are allowed to access about:blank,
1093c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // but they are not allowed to access other types of about pages.
1094c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Just ignore the about:blank and let the TAB_CONTENTS_WEB handle it.
1095c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (LowerCaseEqualsASCII(url->spec(), chrome::kAboutBlankURL))
1096c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
1097c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1098c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Rewrite about:cache/* URLs to chrome://view-http-cache/*
1099c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (StartsWithAboutSpecifier(*url, chrome::kAboutCacheURL)) {
1100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *url = RemapAboutURL(chrome::kNetworkViewCacheURL, *url);
1101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
1102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Rewrite about:net-internals/* URLs to chrome://net-internals/*
1105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (StartsWithAboutSpecifier(*url, chrome::kAboutNetInternalsURL)) {
1106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *url = RemapAboutURL(chrome::kNetworkViewInternalsURL, *url);
1107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
1108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Rewrite about:appcache-internals/* URLs to chrome://appcache/*
1111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (StartsWithAboutSpecifier(*url, chrome::kAboutAppCacheInternalsURL)) {
1112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *url = RemapAboutURL(chrome::kAppCacheViewInternalsURL, *url);
1113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
1114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Rewrite about:plugins to chrome://plugins/.
1117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (LowerCaseEqualsASCII(url->spec(), chrome::kAboutPluginsURL)) {
1118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *url = GURL(chrome::kChromeUIPluginsURL);
1119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
1120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Handle URL to crash the browser process.
1123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (LowerCaseEqualsASCII(url->spec(), chrome::kAboutBrowserCrash)) {
1124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Induce an intentional crash in the browser process.
1125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int* bad_pointer = NULL;
1126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *bad_pointer = 42;
1127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
1128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // There are a few about: URLs that we hand over to the renderer. If the
1131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // renderer wants them, don't do any rewriting.
1132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (chrome_about_handler::WillHandle(*url))
1133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
1134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Anything else requires our special handler, make sure its initialized.
1136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We only need to register the AboutSource once and it is kept globally.
1137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // There is currently no way to remove a data source.
1138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static bool initialized = false;
1139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!initialized) {
1140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    about_source = new AboutSource();
1141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    initialized = true;
1142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Special case about:memory to go through a redirect before ending up on
1145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the final page. See GetAboutMemoryRedirectResponse above for why.
1146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (LowerCaseEqualsASCII(url->path(), kMemoryPath)) {
1147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *url = GURL("chrome://about/memory-redirect");
1148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
1149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Rewrite the about URL to use chrome:. WebKit treats all about URLS the
1152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // same (blank page), so if we want to display content, we need another
1153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // scheme.
1154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string about_url = "chrome://about/";
1155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  about_url.append(url->path());
1156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  *url = GURL(about_url);
1157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
1158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This function gets called with the fixed-up chrome: URLs, so we have to
1161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// compare against those instead of "about:blah".
1162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool HandleNonNavigationAboutURL(const GURL& url) {
1163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // about:ipc is currently buggy, so we disable it for official builds.
1164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if !defined(OFFICIAL_BUILD)
1165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if (defined(OS_MACOSX) || defined(OS_WIN)) && defined(IPC_MESSAGE_LOG_ENABLED)
1167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (LowerCaseEqualsASCII(url.spec(), chrome::kChromeUIIPCURL)) {
1168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Run the dialog. This will re-use the existing one if it's already up.
1169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AboutIPCDialog::RunDialog();
1170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
1171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
1173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // OFFICIAL_BUILD
1175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return false;
1177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1178